diff options
author | Ahmad Fatoum <ahmad@a3f.at> | 2021-07-07 08:52:51 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-07-09 22:53:40 +0200 |
commit | 3a0c4a41d0659e94be8628522746206fb1215769 (patch) | |
tree | 96cd1e63ea72c831003280b9cbcf3e6dd9b23d46 /fs | |
parent | 30a5e60e7d23fba9c5c12ff93c022a6c236dd01f (diff) | |
download | barebox-3a0c4a41d0659e94be8628522746206fb1215769.tar.gz barebox-3a0c4a41d0659e94be8628522746206fb1215769.tar.xz |
fs: fix NULL pointer dereference of fsdrv->truncate for read-only FS
fsdrv->truncate is dereferenced at times without checking for NULL before,
leading to crashes, e.g. doing:
edit -o /mnt/myext4/FILE some text
on ext4 crashes. Fix this by returning -EROFS when truncate is unimplemented.
Reported-by: Xogium <contact@xogium.me>
Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
Link: https://lore.barebox.org/20210707065251.760827-1-ahmad@a3f.at
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fs.c | 16 |
1 files changed, 10 insertions, 6 deletions
@@ -208,9 +208,15 @@ int creat(const char *pathname, mode_t mode) } EXPORT_SYMBOL(creat); +static int fsdev_truncate(struct device_d *dev, FILE *f, loff_t length) +{ + struct fs_driver_d *fsdrv = f->fsdev->driver; + + return fsdrv->truncate ? fsdrv->truncate(dev, f, length) : -EROFS; +} + int ftruncate(int fd, loff_t length) { - struct fs_driver_d *fsdrv; FILE *f = fd_to_file(fd); int ret; @@ -220,9 +226,7 @@ int ftruncate(int fd, loff_t length) if (f->size == FILE_SIZE_STREAM) return 0; - fsdrv = f->fsdev->driver; - - ret = fsdrv->truncate(&f->fsdev->dev, f, length); + ret = fsdev_truncate(&f->fsdev->dev, f, length); if (ret) { errno = -ret; return ret; @@ -332,7 +336,7 @@ static ssize_t __write(FILE *f, const void *buf, size_t count) assert_command_context(); if (f->size != FILE_SIZE_STREAM && f->pos + count > f->size) { - ret = fsdrv->truncate(&f->fsdev->dev, f, f->pos + count); + ret = fsdev_truncate(&f->fsdev->dev, f, f->pos + count); if (ret) { if (ret != -ENOSPC) goto out; @@ -2463,7 +2467,7 @@ int open(const char *pathname, int flags, ...) } if (flags & O_TRUNC) { - error = fsdrv->truncate(&fsdev->dev, f, 0); + error = fsdev_truncate(&fsdev->dev, f, 0); f->size = 0; inode->i_size = 0; if (error) |