Re: [PATCH 3/9] anon_inode: explicitly block ->setattr()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon 07-04-25 11:54:17, Christian Brauner wrote:
> It is currently possible to change the mode and owner of the single
> anonymous inode in the kernel:
> 
> int main(int argc, char *argv[])
> {
>         int ret, sfd;
>         sigset_t mask;
>         struct signalfd_siginfo fdsi;
> 
>         sigemptyset(&mask);
>         sigaddset(&mask, SIGINT);
>         sigaddset(&mask, SIGQUIT);
> 
>         ret = sigprocmask(SIG_BLOCK, &mask, NULL);
>         if (ret < 0)
>                 _exit(1);
> 
>         sfd = signalfd(-1, &mask, 0);
>         if (sfd < 0)
>                 _exit(2);
> 
>         ret = fchown(sfd, 5555, 5555);
>         if (ret < 0)
>                 _exit(3);
> 
>         ret = fchmod(sfd, 0777);
>         if (ret < 0)
>                 _exit(3);
> 
>         _exit(4);
> }
> 
> This is a bug. It's not really a meaningful one because anonymous inodes
> don't really figure into path lookup and they cannot be reopened via
> /proc/<pid>/fd/<nr> and can't be used for lookup itself. So they can
> only ever serve as direct references.
> 
> But it is still completely bogus to allow the mode and ownership or any
> of the properties of the anonymous inode to be changed. Block this!
> 
> Cc: <stable@xxxxxxxxxxxxxxx> # all LTS kernels
> Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx>

Definitely. Feel free to add:

Reviewed-by: Jan Kara <jack@xxxxxxx>

								Honza

> ---
>  fs/anon_inodes.c | 7 +++++++
>  fs/internal.h    | 2 ++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
> index 42e4b9c34f89..cb51a90bece0 100644
> --- a/fs/anon_inodes.c
> +++ b/fs/anon_inodes.c
> @@ -57,8 +57,15 @@ int anon_inode_getattr(struct mnt_idmap *idmap, const struct path *path,
>  	return 0;
>  }
>  
> +int anon_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +		       struct iattr *attr)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
>  static const struct inode_operations anon_inode_operations = {
>  	.getattr = anon_inode_getattr,
> +	.setattr = anon_inode_setattr,
>  };
>  
>  /*
> diff --git a/fs/internal.h b/fs/internal.h
> index 717dc9eb6185..f545400ce607 100644
> --- a/fs/internal.h
> +++ b/fs/internal.h
> @@ -346,3 +346,5 @@ int statmount_mnt_idmap(struct mnt_idmap *idmap, struct seq_file *seq, bool uid_
>  int anon_inode_getattr(struct mnt_idmap *idmap, const struct path *path,
>  		       struct kstat *stat, u32 request_mask,
>  		       unsigned int query_flags);
> +int anon_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> +		       struct iattr *attr);
> 
> -- 
> 2.47.2
> 
-- 
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux