From 7179d57026696f97393e79a161ad945633c8150b Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 3 Jan 2023 01:27:25 +0800 Subject: [PATCH] fs: Check offset and length more carefully in mmap callback Signed-off-by: Xiang Xiao --- drivers/video/fb.c | 3 ++- drivers/video/video.c | 19 ++++++++++++++----- fs/romfs/fs_romfs.c | 6 +++--- fs/rpmsgfs/rpmsgfs.c | 8 ++++---- fs/tmpfs/fs_tmpfs.c | 3 ++- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/video/fb.c b/drivers/video/fb.c index 05f86e81de..9a0a764ca7 100644 --- a/drivers/video/fb.c +++ b/drivers/video/fb.c @@ -686,7 +686,8 @@ static int fb_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map) /* Return the address corresponding to the start of frame buffer. */ - if (map->offset + map->length <= fb->fblen) + if (map->offset >= 0 && map->offset < fb->fblen && + map->length && map->offset + map->length <= fb->fblen) { map->vaddr = (FAR char *)fb->fbmem + map->offset; ret = OK; diff --git a/drivers/video/video.c b/drivers/video/video.c index 7d6612ba43..3c45408603 100644 --- a/drivers/video/video.c +++ b/drivers/video/video.c @@ -1582,6 +1582,12 @@ static size_t get_bufsize(FAR video_format_t *vf) } } +static size_t get_heapsize(FAR video_type_inf_t *type_inf) +{ + return type_inf->bufinf.container_size * + get_bufsize(&type_inf->fmt[VIDEO_FMT_MAIN]); +} + static int video_try_fmt(FAR struct video_mng_s *priv, FAR struct v4l2_format *v4l2) { @@ -3195,13 +3201,16 @@ static int video_ioctl(FAR struct file *filep, int cmd, unsigned long arg) static int video_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map) { - FAR struct inode *inode = filep->f_inode; - FAR video_mng_t *priv = (FAR video_mng_t *)inode->i_private; - int ret = -EINVAL; + FAR struct inode *inode = filep->f_inode; + FAR video_mng_t *priv = (FAR video_mng_t *)inode->i_private; + FAR video_type_inf_t *type_inf = &priv->video_inf; + size_t heapsize = get_heapsize(type_inf); + int ret = -EINVAL; - if (map) + if (map->offset >= 0 && map->offset < heapsize && + map->length && map->offset + map->length <= heapsize) { - map->vaddr = priv->video_inf.bufheap + map->offset; + map->vaddr = type_inf->bufheap + map->offset; ret = OK; } diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c index 10e9cd25c5..bafcdd25bd 100644 --- a/fs/romfs/fs_romfs.c +++ b/fs/romfs/fs_romfs.c @@ -580,7 +580,7 @@ errout_with_lock: static int romfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { - FAR struct romfs_file_s *rf; + FAR struct romfs_file_s *rf; finfo("cmd: %d arg: %08lx\n", cmd, arg); @@ -625,8 +625,8 @@ static int romfs_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map) * the file. */ - if (map && rm && rm->rm_xipbase && rf && - map->offset + map->length <= rf->rf_size) + if (rm->rm_xipbase && map->offset >= 0 && map->offset < rf->rf_size && + map->length != 0 && map->offset + map->length <= rf->rf_size) { map->vaddr = rm->rm_xipbase + rf->rf_startoffset + map->offset; ret = OK; diff --git a/fs/rpmsgfs/rpmsgfs.c b/fs/rpmsgfs/rpmsgfs.c index 7f0c4f69cc..63cfc29003 100644 --- a/fs/rpmsgfs/rpmsgfs.c +++ b/fs/rpmsgfs/rpmsgfs.c @@ -109,7 +109,7 @@ static int rpmsgfs_fstat(FAR const struct file *filep, FAR struct stat *buf); static int rpmsgfs_fchstat(FAR const struct file *filep, FAR const struct stat *buf, int flags); -static int rpmsgfs_ftruncate(FAR struct file *filep, +static int rpmsgfs_truncate(FAR struct file *filep, off_t length); static int rpmsgfs_opendir(FAR struct inode *mountpt, @@ -162,7 +162,7 @@ const struct mountpt_operations rpmsgfs_operations = rpmsgfs_seek, /* seek */ rpmsgfs_ioctl, /* ioctl */ NULL, /* mmap */ - rpmsgfs_ftruncate, /* ftruncate */ + rpmsgfs_truncate, /* truncate */ rpmsgfs_sync, /* sync */ rpmsgfs_dup, /* dup */ @@ -804,7 +804,7 @@ static int rpmsgfs_fchstat(FAR const struct file *filep, } /**************************************************************************** - * Name: rpmsgfs_ftruncate + * Name: rpmsgfs_truncate * * Description: * Set the length of the open, regular file associated with the file @@ -812,7 +812,7 @@ static int rpmsgfs_fchstat(FAR const struct file *filep, * ****************************************************************************/ -static int rpmsgfs_ftruncate(FAR struct file *filep, off_t length) +static int rpmsgfs_truncate(FAR struct file *filep, off_t length) { FAR struct inode *inode; FAR struct rpmsgfs_mountpt_s *fs; diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c index d152d69293..56dbd39fa5 100644 --- a/fs/tmpfs/fs_tmpfs.c +++ b/fs/tmpfs/fs_tmpfs.c @@ -1655,7 +1655,8 @@ static int tmpfs_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map) DEBUGASSERT(tfo != NULL); - if (map && map->offset + map->length <= tfo->tfo_size) + if (map->offset >= 0 && map->offset < tfo->tfo_size && + map->length && map->offset + map->length <= tfo->tfo_size) { map->vaddr = tfo->tfo_data + map->offset; ret = OK;