rpmsgfs: do NOT access the pointer when do remote ioctl
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
463a437733
commit
6f210655fa
@ -110,7 +110,9 @@ begin_packed_struct struct rpmsgfs_ioctl_s
|
||||
struct rpmsgfs_header_s header;
|
||||
int32_t fd;
|
||||
int32_t request;
|
||||
int32_t arg;
|
||||
uint64_t arg;
|
||||
uint32_t arglen;
|
||||
char buf[0];
|
||||
} end_packed_struct;
|
||||
|
||||
#define rpmsgfs_sync_s rpmsgfs_close_s
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/fs/rpmsgfs.h>
|
||||
#include <nuttx/rptun/openamp.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,
|
||||
FAR void *data, size_t len,
|
||||
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,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
@ -94,7 +98,7 @@ static const rpmsg_ept_cb g_rpmsgfs_handler[] =
|
||||
[RPMSGFS_READ] = rpmsgfs_read_handler,
|
||||
[RPMSGFS_WRITE] = rpmsgfs_default_handler,
|
||||
[RPMSGFS_LSEEK] = rpmsgfs_default_handler,
|
||||
[RPMSGFS_IOCTL] = rpmsgfs_default_handler,
|
||||
[RPMSGFS_IOCTL] = rpmsgfs_ioctl_handler,
|
||||
[RPMSGFS_SYNC] = rpmsgfs_default_handler,
|
||||
[RPMSGFS_DUP] = rpmsgfs_default_handler,
|
||||
[RPMSGFS_FSTAT] = rpmsgfs_stat_handler,
|
||||
@ -156,6 +160,25 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
|
||||
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,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv)
|
||||
@ -353,6 +376,19 @@ fail:
|
||||
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
|
||||
****************************************************************************/
|
||||
@ -483,15 +519,34 @@ off_t rpmsgfs_client_lseek(FAR void *handle, int fd,
|
||||
int rpmsgfs_client_ioctl(FAR void *handle, int fd,
|
||||
int request, unsigned long arg)
|
||||
{
|
||||
struct rpmsgfs_ioctl_s msg =
|
||||
{
|
||||
.fd = fd,
|
||||
.request = request,
|
||||
.arg = arg,
|
||||
};
|
||||
size_t arglen = rpmsgfs_ioctl_arglen(request);
|
||||
FAR struct rpmsgfs_s *priv = handle;
|
||||
FAR struct rpmsgfs_ioctl_s *msg;
|
||||
uint32_t space;
|
||||
size_t len;
|
||||
|
||||
return rpmsgfs_send_recv(handle, RPMSGFS_IOCTL, true,
|
||||
(struct rpmsgfs_header_s *)&msg, sizeof(msg), NULL);
|
||||
len = sizeof(*msg) + arglen;
|
||||
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)
|
||||
|
@ -443,7 +443,8 @@ static int rpmsgfs_ioctl_handler(FAR struct rpmsg_endpoint *ept,
|
||||
filep = rpmsgfs_get_file(priv, msg->fd);
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user