* Generic approach to avoid truncation of file on pseudo fs
@ 2026-02-19 13:37 Christian Göttsche
2026-02-26 11:29 ` Jan Kara
0 siblings, 1 reply; 3+ messages in thread
From: Christian Göttsche @ 2026-02-19 13:37 UTC (permalink / raw)
To: linux-fsdevel; +Cc: SElinux list, Alexander Viro, Christian Brauner, Jan Kara
Hi all,
SELinux offers a memory mapping for userspace for status changes via
the pseudo file /sys/fs/selinux/status.
Currently this file can be truncated by a privileged process, leading
to other userland processes getting signalled a bus error (SIGBUS).
This affects for example systemd [1].
I proposed a targeted fix [2], overriding the inode setattr handler
and filtering O_TRUNC on open.
Is there there a general solution how to prevent truncation of pseudo
files backed up by real memory?
Are there more ways a file can be truncated that should be handled?
If there is no generic way would the following patch be acceptable?
diff --git a/fs/libfs.c b/fs/libfs.c
index 9264523be85c..76f7fec136cb 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1089,6 +1089,7 @@ int simple_fill_super(struct super_block *s,
unsigned long magic,
}
inode->i_mode = S_IFREG | files->mode;
simple_inode_init_ts(inode);
+ inode->i_op = files->iops;
inode->i_fop = files->ops;
inode->i_ino = i;
d_make_persistent(dentry, inode);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 04ceeca12a0d..9f1a9f0a9b48 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3225,7 +3225,7 @@ extern const struct file_operations simple_dir_operations;
extern const struct inode_operations simple_dir_inode_operations;
extern void make_empty_dir_inode(struct inode *inode);
extern bool is_empty_dir_inode(struct inode *inode);
-struct tree_descr { const char *name; const struct file_operations
*ops; int mode; };
+struct tree_descr { const char *name; const struct file_operations
*ops; int mode; const struct inode_operations *iops; };
struct dentry *d_alloc_name(struct dentry *, const char *);
extern int simple_fill_super(struct super_block *, unsigned long,
const struct tree_descr *);
and then adding the hook would just be
- [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
+ [SEL_STATUS] = {"status", &sel_handle_status_ops,
S_IRUGO, &sel_handle_status_iops},
Best regards,
Christian Göttsche
Link [1]: https://github.com/systemd/systemd/issues/37349
Link [2]: https://lore.kernel.org/selinux/20260130171140.90966-1-cgoettsche@seltendoof.de/
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: Generic approach to avoid truncation of file on pseudo fs
2026-02-19 13:37 Generic approach to avoid truncation of file on pseudo fs Christian Göttsche
@ 2026-02-26 11:29 ` Jan Kara
2026-02-26 13:38 ` Christian Brauner
0 siblings, 1 reply; 3+ messages in thread
From: Jan Kara @ 2026-02-26 11:29 UTC (permalink / raw)
To: Christian Göttsche
Cc: linux-fsdevel, SElinux list, Alexander Viro, Christian Brauner,
Jan Kara
On Thu 19-02-26 14:37:05, Christian Göttsche wrote:
> Hi all,
>
> SELinux offers a memory mapping for userspace for status changes via
> the pseudo file /sys/fs/selinux/status.
> Currently this file can be truncated by a privileged process, leading
> to other userland processes getting signalled a bus error (SIGBUS).
> This affects for example systemd [1].
> I proposed a targeted fix [2], overriding the inode setattr handler
> and filtering O_TRUNC on open.
>
> Is there there a general solution how to prevent truncation of pseudo
> files backed up by real memory?
> Are there more ways a file can be truncated that should be handled?
>
>
> If there is no generic way would the following patch be acceptable?
OK, since my knowledge about this code is limited, I did some research :).
Firstly, I've checked how other virtual filesystems behave and the answer
is "it depends". E.g. those that are based on kernfs (e.g. sysfs) have
their own .setattr handler which just ignores ATTR_SIZE. From those that
are based on simple_fill_super as is the case for selinux (but also
debugfs, nfsctl, tracefs, fusectl, binfmt) all of them just allow the file
size to be changed which likely has some potential for confusing userspace
for some of them. So I don't see a problem with allowing to pass
inode_operations to use by simple_fill_super() but I'm a bit undecided
whether it wouldn't be more sensible for pseudo_fs_fill_super() to just
set inode->i_op to inode operations that don't allow truncate because for
none of the filesystems using it, it looks useful to say the least.
Honze
> diff --git a/fs/libfs.c b/fs/libfs.c
>
> index 9264523be85c..76f7fec136cb 100644
> --- a/fs/libfs.c
> +++ b/fs/libfs.c
> @@ -1089,6 +1089,7 @@ int simple_fill_super(struct super_block *s,
> unsigned long magic,
> }
> inode->i_mode = S_IFREG | files->mode;
> simple_inode_init_ts(inode);
> + inode->i_op = files->iops;
> inode->i_fop = files->ops;
> inode->i_ino = i;
> d_make_persistent(dentry, inode);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 04ceeca12a0d..9f1a9f0a9b48 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -3225,7 +3225,7 @@ extern const struct file_operations simple_dir_operations;
> extern const struct inode_operations simple_dir_inode_operations;
> extern void make_empty_dir_inode(struct inode *inode);
> extern bool is_empty_dir_inode(struct inode *inode);
> -struct tree_descr { const char *name; const struct file_operations
> *ops; int mode; };
> +struct tree_descr { const char *name; const struct file_operations
> *ops; int mode; const struct inode_operations *iops; };
> struct dentry *d_alloc_name(struct dentry *, const char *);
> extern int simple_fill_super(struct super_block *, unsigned long,
> const struct tree_descr *);
>
>
> and then adding the hook would just be
>
> - [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
> + [SEL_STATUS] = {"status", &sel_handle_status_ops,
> S_IRUGO, &sel_handle_status_iops},
>
>
> Best regards,
> Christian Göttsche
>
>
> Link [1]: https://github.com/systemd/systemd/issues/37349
> Link [2]: https://lore.kernel.org/selinux/20260130171140.90966-1-cgoettsche@seltendoof.de/
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Generic approach to avoid truncation of file on pseudo fs
2026-02-26 11:29 ` Jan Kara
@ 2026-02-26 13:38 ` Christian Brauner
0 siblings, 0 replies; 3+ messages in thread
From: Christian Brauner @ 2026-02-26 13:38 UTC (permalink / raw)
To: Jan Kara
Cc: Christian Göttsche, linux-fsdevel, SElinux list,
Alexander Viro
On Thu, Feb 26, 2026 at 12:29:33PM +0100, Jan Kara wrote:
> On Thu 19-02-26 14:37:05, Christian Göttsche wrote:
> > Hi all,
> >
> > SELinux offers a memory mapping for userspace for status changes via
> > the pseudo file /sys/fs/selinux/status.
> > Currently this file can be truncated by a privileged process, leading
> > to other userland processes getting signalled a bus error (SIGBUS).
> > This affects for example systemd [1].
> > I proposed a targeted fix [2], overriding the inode setattr handler
> > and filtering O_TRUNC on open.
> >
> > Is there there a general solution how to prevent truncation of pseudo
> > files backed up by real memory?
> > Are there more ways a file can be truncated that should be handled?
> >
> >
> > If there is no generic way would the following patch be acceptable?
>
> OK, since my knowledge about this code is limited, I did some research :).
> Firstly, I've checked how other virtual filesystems behave and the answer
> is "it depends". E.g. those that are based on kernfs (e.g. sysfs) have
> their own .setattr handler which just ignores ATTR_SIZE. From those that
> are based on simple_fill_super as is the case for selinux (but also
> debugfs, nfsctl, tracefs, fusectl, binfmt) all of them just allow the file
> size to be changed which likely has some potential for confusing userspace
> for some of them. So I don't see a problem with allowing to pass
> inode_operations to use by simple_fill_super() but I'm a bit undecided
> whether it wouldn't be more sensible for pseudo_fs_fill_super() to just
> set inode->i_op to inode operations that don't allow truncate because for
> none of the filesystems using it, it looks useful to say the least.
It would at least be worth trying. For backwards compat we must probably
ignore it instead of reporting an error though.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-02-26 13:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 13:37 Generic approach to avoid truncation of file on pseudo fs Christian Göttsche
2026-02-26 11:29 ` Jan Kara
2026-02-26 13:38 ` Christian Brauner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox