rpmsgfs: do NOT access the pointer when do remote ioctl

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2022-03-25 13:12:28 +08:00 committed by Xiang Xiao
parent 463a437733
commit 6f210655fa
3 changed files with 69 additions and 11 deletions

View File

@ -110,7 +110,9 @@ begin_packed_struct struct rpmsgfs_ioctl_s
struct rpmsgfs_header_s header; struct rpmsgfs_header_s header;
int32_t fd; int32_t fd;
int32_t request; int32_t request;
int32_t arg; uint64_t arg;
uint32_t arglen;
char buf[0];
} end_packed_struct; } end_packed_struct;
#define rpmsgfs_sync_s rpmsgfs_close_s #define rpmsgfs_sync_s rpmsgfs_close_s

View File

@ -28,6 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/fs/rpmsgfs.h> #include <nuttx/fs/rpmsgfs.h>
#include <nuttx/rptun/openamp.h> #include <nuttx/rptun/openamp.h>
#include <nuttx/semaphore.h> #include <nuttx/semaphore.h>
@ -62,6 +63,9 @@ static int rpmsgfs_default_handler(FAR struct rpmsg_endpoint *ept,
static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept, static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len, FAR void *data, size_t len,
uint32_t src, FAR void *priv); uint32_t src, FAR void *priv);
static int rpmsgfs_ioctl_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv);
static int rpmsgfs_readdir_handler(FAR struct rpmsg_endpoint *ept, static int rpmsgfs_readdir_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len, FAR void *data, size_t len,
uint32_t src, FAR void *priv); uint32_t src, FAR void *priv);
@ -94,7 +98,7 @@ static const rpmsg_ept_cb g_rpmsgfs_handler[] =
[RPMSGFS_READ] = rpmsgfs_read_handler, [RPMSGFS_READ] = rpmsgfs_read_handler,
[RPMSGFS_WRITE] = rpmsgfs_default_handler, [RPMSGFS_WRITE] = rpmsgfs_default_handler,
[RPMSGFS_LSEEK] = rpmsgfs_default_handler, [RPMSGFS_LSEEK] = rpmsgfs_default_handler,
[RPMSGFS_IOCTL] = rpmsgfs_default_handler, [RPMSGFS_IOCTL] = rpmsgfs_ioctl_handler,
[RPMSGFS_SYNC] = rpmsgfs_default_handler, [RPMSGFS_SYNC] = rpmsgfs_default_handler,
[RPMSGFS_DUP] = rpmsgfs_default_handler, [RPMSGFS_DUP] = rpmsgfs_default_handler,
[RPMSGFS_FSTAT] = rpmsgfs_stat_handler, [RPMSGFS_FSTAT] = rpmsgfs_stat_handler,
@ -156,6 +160,25 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
return 0; return 0;
} }
static int rpmsgfs_ioctl_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv)
{
FAR struct rpmsgfs_header_s *header = data;
FAR struct rpmsgfs_cookie_s *cookie =
(FAR struct rpmsgfs_cookie_s *)(uintptr_t)header->cookie;
FAR struct rpmsgfs_ioctl_s *rsp = data;
if (cookie->result >= 0 && rsp->arglen > 0)
{
memcpy(cookie->data, (FAR void *)(uintptr_t)rsp->arg, rsp->arglen);
}
rpmsg_post(ept, &cookie->sem);
return 0;
}
static int rpmsgfs_readdir_handler(FAR struct rpmsg_endpoint *ept, static int rpmsgfs_readdir_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len, FAR void *data, size_t len,
uint32_t src, FAR void *priv) uint32_t src, FAR void *priv)
@ -353,6 +376,19 @@ fail:
return ret; return ret;
} }
static size_t rpmsgfs_ioctl_arglen(int cmd)
{
switch (cmd)
{
case FIONBIO:
case FIONWRITE:
case FIONREAD:
return sizeof(int);
default:
return 0;
}
}
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -483,15 +519,34 @@ off_t rpmsgfs_client_lseek(FAR void *handle, int fd,
int rpmsgfs_client_ioctl(FAR void *handle, int fd, int rpmsgfs_client_ioctl(FAR void *handle, int fd,
int request, unsigned long arg) int request, unsigned long arg)
{ {
struct rpmsgfs_ioctl_s msg = size_t arglen = rpmsgfs_ioctl_arglen(request);
{ FAR struct rpmsgfs_s *priv = handle;
.fd = fd, FAR struct rpmsgfs_ioctl_s *msg;
.request = request, uint32_t space;
.arg = arg, size_t len;
};
return rpmsgfs_send_recv(handle, RPMSGFS_IOCTL, true, len = sizeof(*msg) + arglen;
(struct rpmsgfs_header_s *)&msg, sizeof(msg), NULL); msg = rpmsgfs_get_tx_payload_buffer(priv, &space);
if (msg == NULL)
{
return -ENOMEM;
}
DEBUGASSERT(len <= space);
msg->fd = fd;
msg->request = request;
msg->arg = arg;
msg->arglen = arglen;
if (arglen > 0)
{
memcpy(msg->buf, (FAR void *)(uintptr_t)arg, arglen);
}
return rpmsgfs_send_recv(handle, RPMSGFS_IOCTL, false,
(FAR struct rpmsgfs_header_s *)msg, len,
arglen > 0 ? (FAR void *)arg : NULL);
} }
void rpmsgfs_client_sync(FAR void *handle, int fd) void rpmsgfs_client_sync(FAR void *handle, int fd)

View File

@ -443,7 +443,8 @@ static int rpmsgfs_ioctl_handler(FAR struct rpmsg_endpoint *ept,
filep = rpmsgfs_get_file(priv, msg->fd); filep = rpmsgfs_get_file(priv, msg->fd);
if (filep != NULL) if (filep != NULL)
{ {
ret = file_ioctl(filep, msg->request, msg->arg); ret = file_ioctl(filep, msg->request, msg->arglen > 0 ?
(unsigned long)msg->buf : msg->arg);
} }
msg->header.result = ret; msg->header.result = ret;