On Fri 21-06-24 09:45:03, Christian Brauner wrote: > On Thu, Jun 20, 2024 at 02:03:59PM GMT, Mateusz Guzik wrote: > > The routine is called for all directories on file creation and weirdly > > postpones the check if the dir is sticky to begin with. Instead it first > > checks fifos and regular files (in that order), while avoidably pulling > > globals. > > > > No functional changes. > > > > Signed-off-by: Mateusz Guzik <mjguzik@xxxxxxxxx> > > --- > > fs/namei.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > diff --git a/fs/namei.c b/fs/namei.c > > index 63d1fb06da6b..b1600060ecfb 100644 > > --- a/fs/namei.c > > +++ b/fs/namei.c > > @@ -1246,9 +1246,9 @@ static int may_create_in_sticky(struct mnt_idmap *idmap, > > umode_t dir_mode = nd->dir_mode; > > vfsuid_t dir_vfsuid = nd->dir_vfsuid; > > > > - if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) || > > - (!sysctl_protected_regular && S_ISREG(inode->i_mode)) || > > - likely(!(dir_mode & S_ISVTX)) || > > + if (likely(!(dir_mode & S_ISVTX)) || > > + (S_ISREG(inode->i_mode) && !sysctl_protected_regular) || > > + (S_ISFIFO(inode->i_mode) && !sysctl_protected_fifos) || > > vfsuid_eq(i_uid_into_vfsuid(idmap, inode), dir_vfsuid) || > > vfsuid_eq_kuid(i_uid_into_vfsuid(idmap, inode), current_fsuid())) > > return 0; > > I think we really need to unroll this unoly mess to make it more readable? I guess my neural network has adapted to these kind of things in the kernel :) > diff --git a/fs/namei.c b/fs/namei.c > index 3e23fbb8b029..1dd2d328bae3 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -1244,25 +1244,43 @@ static int may_create_in_sticky(struct mnt_idmap *idmap, > struct nameidata *nd, struct inode *const inode) > { > umode_t dir_mode = nd->dir_mode; > - vfsuid_t dir_vfsuid = nd->dir_vfsuid; > + vfsuid_t dir_vfsuid = nd->dir_vfsuid, i_vfsuid; > + int ret; > + > + if (likely(!(dir_mode & S_ISVTX))) > + return 0; > + > + if (S_ISREG(inode->i_mode) && !sysctl_protected_regular) > + return 0; > + > + if (S_ISFIFO(inode->i_mode) && !sysctl_protected_fifos) > + return 0; > + > + i_vfsuid = i_uid_into_vfsuid(idmap, inode); > + > + if (vfsuid_eq(i_vfsuid, dir_vfsuid)) > + return 0; > > - if (likely(!(dir_mode & S_ISVTX)) || > - (S_ISREG(inode->i_mode) && !sysctl_protected_regular) || > - (S_ISFIFO(inode->i_mode) && !sysctl_protected_fifos) || > - vfsuid_eq(i_uid_into_vfsuid(idmap, inode), dir_vfsuid) || > - vfsuid_eq_kuid(i_uid_into_vfsuid(idmap, inode), current_fsuid())) > + if (vfsuid_eq_kuid(i_vfsuid, current_fsuid())) > return 0; > > - if (likely(dir_mode & 0002) || > - (dir_mode & 0020 && > - ((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) || > - (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) { > - const char *operation = S_ISFIFO(inode->i_mode) ? > - "sticky_create_fifo" : > - "sticky_create_regular"; > - audit_log_path_denied(AUDIT_ANOM_CREAT, operation); > + if (likely(dir_mode & 0002)) { > + audit_log_path_denied(AUDIT_ANOM_CREAT, "sticky_create"); > return -EACCES; > } > + > + if (dir_mode & 0020) { > + if (sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) { > + audit_log_path_denied(AUDIT_ANOM_CREAT, "sticky_create_fifo"); > + return -EACCES; > + } > + > + if (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode)) { > + audit_log_path_denied(AUDIT_ANOM_CREAT, "sticky_create_regular"); > + return -EACCES; > + } > + } > + > return 0; > } But this definitely looks nicer to read... Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR