lkml.org 
[lkml]   [2023]   [Jan]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    SubjectRe: [PATCH v10 1/9] mm: Introduce memfd_restricted system call to create restricted user memory
    From

    > +static int restrictedmem_getattr(struct user_namespace *mnt_userns,
    > + const struct path *path, struct kstat *stat,
    > + u32 request_mask, unsigned int query_flags)
    > +{
    > + struct inode *inode = d_inode(path->dentry);
    > + struct restrictedmem_data *data = inode->i_mapping->private_data;
    > + struct file *memfd = data->memfd;
    > +
    > + return memfd->f_inode->i_op->getattr(mnt_userns, path, stat,
    > + request_mask, query_flags);

    Instead of calling shmem's getattr() with path, we should be using the
    the memfd's path.

    Otherwise, shmem's getattr() will use restrictedmem's inode instead of
    shmem's inode. The private fields will be of the wrong type, and the
    host will crash when shmem_is_huge() does SHMEM_SB(inode->i_sb)->huge),
    since inode->i_sb->s_fs_info is NULL for the restrictedmem's superblock.

    Here's the patch:

    diff --git a/mm/restrictedmem.c b/mm/restrictedmem.c
    index 37191cd9eed1..06b72d593bd8 100644
    --- a/mm/restrictedmem.c
    +++ b/mm/restrictedmem.c
    @@ -84,7 +84,7 @@ static int restrictedmem_getattr(struct user_namespace
    *mnt_userns,
    struct restrictedmem *rm = inode->i_mapping->private_data;
    struct file *memfd = rm->memfd;

    - return memfd->f_inode->i_op->getattr(mnt_userns, path, stat,
    + return memfd->f_inode->i_op->getattr(mnt_userns, &memfd->f_path, stat,
    request_mask, query_flags);
    }

    > +}
    > +
    > +static int restrictedmem_setattr(struct user_namespace *mnt_userns,
    > + struct dentry *dentry, struct iattr *attr)
    > +{
    > + struct inode *inode = d_inode(dentry);
    > + struct restrictedmem_data *data = inode->i_mapping->private_data;
    > + struct file *memfd = data->memfd;
    > + int ret;
    > +
    > + if (attr->ia_valid & ATTR_SIZE) {
    > + if (memfd->f_inode->i_size)
    > + return -EPERM;
    > +
    > + if (!PAGE_ALIGNED(attr->ia_size))
    > + return -EINVAL;
    > + }
    > +
    > + ret = memfd->f_inode->i_op->setattr(mnt_userns,
    > + file_dentry(memfd), attr);
    > + return ret;
    > +}
    > +
    > +static const struct inode_operations restrictedmem_iops = {
    > + .getattr = restrictedmem_getattr,
    > + .setattr = restrictedmem_setattr,
    > +};
    \
     
     \ /
      Last update: 2023-03-27 00:01    [W:4.312 / U:1.428 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site