[PATCH 6/6] fs: ubootvarfs: handle removal of variables that are still open
Ahmad Fatoum
a.fatoum at pengutronix.de
Fri Oct 2 04:40:09 PDT 2026
From: Ahmad Fatoum <a.fatoum at barebox.org>
Removing a variable frees it and clears the inode's pointer to it, but
an open file keeps the inode around with the old size. Reading, writing
or truncating it then dereferences the NULL pointer. The shell can get
there with a loop mount: after mount -o loop on a variable and rm of
it, md on /dev/loop0 or reading a file from the mount crashes.
Let's set the size of a removed variable to zero and return -ENOENT
for any further access to it.
Fixes: 8daaa21b3949 ("fs: Add a driver to access U-Boot environment variables")
Assisted-by: Claude:opus-5.5
Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
---
fs/ubootvarfs.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/fs/ubootvarfs.c b/fs/ubootvarfs.c
index b0353d7cedef..e2d2a2f4aa77 100644
--- a/fs/ubootvarfs.c
+++ b/fs/ubootvarfs.c
@@ -266,7 +266,9 @@ static int ubootvarfs_unlink(struct inode *dir, struct dentry *dentry)
list_del(&var->list);
free(var);
+ /* open files keep the inode, see ubootvarfs_io() */
node->var = NULL;
+ inode->i_size = 0;
}
return simple_unlink(dir, dentry);
@@ -348,7 +350,13 @@ static int ubootvarfs_io(struct file *f, void *buf, size_t insize, bool read)
{
struct inode *inode = f->f_inode;
struct ubootvarfs_inode *node = inode_to_node(inode);
- void *ptr = node->var->start + f->f_pos;
+ void *ptr;
+
+ /* the variable was removed while the file was open */
+ if (!node->var)
+ return -ENOENT;
+
+ ptr = node->var->start + f->f_pos;
if (read)
memcpy(buf, ptr, insize);
@@ -376,6 +384,9 @@ static int ubootvarfs_truncate(struct file *f, loff_t size)
struct ubootvarfs_var *var = node->var;
loff_t delta;
+ if (!var)
+ return -ENOENT;
+
if (size < 0)
return -EINVAL;
--
2.47.3
More information about the barebox
mailing list