misc/rpmsgdev: The private data should be freed only when endpoint is released

A use-after-free problem occurs when there are multiple remotes in the list `g_rpmsg` and the matching remote is not the last item in the list.

Log
  # Export the device "/dev/LOCAL_DEV" to remote "REMOTE_CPU"
  ap> testdev -d 2 -c "REMOTE_CPU" -l "/dev/LOCAL_DEV"
  [ap] kasan_report: kasan detected a read access error, address at 0x3c3d4740,size is 4, return address: 0x2c33620f
  [ap] kasan_show_memory: Shadow bytes around the buggy address:
  [ap] kasan_show_memory:   0x3c3d46f0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4700: aa aa aa aa cc cc cc cc cc cc cc cc cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4710: 40 47 3d 3c ed 61 33 2c 00 00 00 00 00 00 00 00
  [ap] kasan_show_memory:   0x3c3d4720: 00 00 00 00 00 00 00 00 00 00 00 00 cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4730: 55 55 55 55 38 00 00 00 02 2c 00 00 cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4740:[00 00 00 00]66 e0 42 3c cc cc cc cc cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4750: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4760: aa aa aa aa 38 00 00 00 01 2c 00 00 cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4770: 50 57 44 3d 2f 00 cc cc cc cc cc cc cc cc cc cc
  [ap] kasan_show_memory:   0x3c3d4780: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
  [ap] dump_assert_info: Current Version: NuttX ****** ***** *** 12.3.0 **********-***** *** ** 2024 **:**:** arm
  [ap] dump_assert_info: Assertion failed panic: at file: kasan/hook.c:187 task: testdev process: testdev 0x2ca20495

  $ addr2line -fe nuttx/nuttx 0x2c33620f
  rpmsgdev_server_created
  /workspace/nuttx/drivers/misc/rpmsgdev_server.c:529
  # Line 529 => strcmp()

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
wangjianyu3 2024-09-27 17:16:14 +08:00 committed by Xiang Xiao
parent a953f14e78
commit 223088d847
1 changed files with 9 additions and 2 deletions

View File

@ -66,6 +66,7 @@ struct rpmsgdev_server_s
* operation
*/
struct work_s work; /* Poll notify work */
FAR void *priv;
};
struct rpmsgdev_export_s
@ -454,6 +455,12 @@ static void rpmsgdev_ept_release(FAR struct rpmsg_endpoint *ept)
nxmutex_unlock(&server->lock);
if (server->priv)
{
kmm_free(server->priv);
server->priv = NULL;
}
kmm_free(server);
}
@ -476,6 +483,7 @@ static void rpmsgdev_ns_bind(FAR struct rpmsg_device *rdev,
list_initialize(&server->head);
nxmutex_init(&server->lock);
server->priv = priv;
server->ept.priv = server;
server->ept.release_cb = rpmsgdev_ept_release;
@ -518,14 +526,13 @@ static void rpmsgdev_server_created(FAR struct rpmsg_device *rdev,
{
snprintf(buf, sizeof(buf), "%s%s", RPMSGDEV_NAME_PREFIX,
priv->localpath);
rpmsgdev_ns_bind(rdev, NULL, buf, RPMSG_ADDR_ANY);
rpmsgdev_ns_bind(rdev, priv, buf, RPMSG_ADDR_ANY);
rpmsg_unregister_callback(priv,
rpmsgdev_server_created,
NULL,
NULL,
NULL);
kmm_free(priv);
}
}