Merge 7d6beb71da ("Merge tag 'idmapped-mounts-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux") into android-mainline

Steps on the way to 5.12-rc1.

Resolves conflicts in:
	fs/overlayfs/inode.c

Note, incfs is broken here, will mark it as BROKEN in another patch to
make it more obvious.

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I95a5938fc3cfa27d521c5d4fd18b2adfb13a6d84
This commit is contained in:
Greg Kroah-Hartman
2021-03-05 15:39:41 +01:00
343 changed files with 4902 additions and 1762 deletions

View File

@@ -126,9 +126,10 @@ prototypes::
int (*get)(const struct xattr_handler *handler, struct dentry *dentry,
struct inode *inode, const char *name, void *buffer,
size_t size);
int (*set)(const struct xattr_handler *handler, struct dentry *dentry,
struct inode *inode, const char *name, const void *buffer,
size_t size, int flags);
int (*set)(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode, const char *name,
const void *buffer, size_t size, int flags);
locking rules:
all may block

View File

@@ -717,6 +717,8 @@ be removed. Switch while you still can; the old one won't stay.
**mandatory**
->setxattr() and xattr_handler.set() get dentry and inode passed separately.
The xattr_handler.set() gets passed the user namespace of the mount the inode
is seen from so filesystems can idmap the i_uid and i_gid accordingly.
dentry might be yet to be attached to inode, so do _not_ use its ->d_inode
in the instances. Rationale: !@#!@# security_d_instantiate() needs to be
called before we attach dentry to inode and !@#!@##!@$!$#!@#$!@$!@$ smack

View File

@@ -418,28 +418,29 @@ As of kernel 2.6.22, the following members are defined:
.. code-block:: c
struct inode_operations {
int (*create) (struct inode *,struct dentry *, umode_t, bool);
int (*create) (struct user_namespace *, struct inode *,struct dentry *, umode_t, bool);
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
int (*mkdir) (struct inode *,struct dentry *,umode_t);
int (*symlink) (struct user_namespace *, struct inode *,struct dentry *,const char *);
int (*mkdir) (struct user_namespace *, struct inode *,struct dentry *,umode_t);
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
int (*rename) (struct inode *, struct dentry *,
int (*mknod) (struct user_namespace *, struct inode *,struct dentry *,umode_t,dev_t);
int (*rename) (struct user_namespace *, struct inode *, struct dentry *,
struct inode *, struct dentry *, unsigned int);
int (*readlink) (struct dentry *, char __user *,int);
const char *(*get_link) (struct dentry *, struct inode *,
struct delayed_call *);
int (*permission) (struct inode *, int);
int (*permission) (struct user_namespace *, struct inode *, int);
int (*get_acl)(struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (const struct path *, struct kstat *, u32, unsigned int);
int (*setattr) (struct user_namespace *, struct dentry *, struct iattr *);
int (*getattr) (struct user_namespace *, const struct path *, struct kstat *, u32, unsigned int);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
void (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
unsigned open_flag, umode_t create_mode);
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
int (*tmpfile) (struct user_namespace *, struct inode *, struct dentry *, umode_t);
int (*set_acl)(struct user_namespace *, struct inode *, struct posix_acl *, int);
};
Again, all methods are called without any locks being held, unless

View File

@@ -481,3 +481,4 @@
549 common faccessat2 sys_faccessat2
550 common process_madvise sys_process_madvise
551 common epoll_pwait2 sys_epoll_pwait2
552 common mount_setattr sys_mount_setattr

View File

@@ -455,3 +455,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -38,7 +38,7 @@
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5)
#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)
#define __NR_compat_syscalls 442
#define __NR_compat_syscalls 443
#endif
#define __ARCH_WANT_SYS_CLONE

View File

@@ -891,6 +891,8 @@ __SYSCALL(__NR_faccessat2, sys_faccessat2)
__SYSCALL(__NR_process_madvise, sys_process_madvise)
#define __NR_epoll_pwait2 441
__SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2)
#define __NR_mount_setattr 442
__SYSCALL(__NR_mount_setattr, sys_mount_setattr)
/*
* Please add new compat syscalls above this comment and update

View File

@@ -362,3 +362,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -441,3 +441,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -447,3 +447,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -380,3 +380,4 @@
439 n32 faccessat2 sys_faccessat2
440 n32 process_madvise sys_process_madvise
441 n32 epoll_pwait2 compat_sys_epoll_pwait2
442 n32 mount_setattr sys_mount_setattr

View File

@@ -356,3 +356,4 @@
439 n64 faccessat2 sys_faccessat2
440 n64 process_madvise sys_process_madvise
441 n64 epoll_pwait2 sys_epoll_pwait2
442 n64 mount_setattr sys_mount_setattr

View File

@@ -429,3 +429,4 @@
439 o32 faccessat2 sys_faccessat2
440 o32 process_madvise sys_process_madvise
441 o32 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 o32 mount_setattr sys_mount_setattr

View File

@@ -439,3 +439,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -521,3 +521,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -91,14 +91,15 @@ out:
}
static int
spufs_setattr(struct dentry *dentry, struct iattr *attr)
spufs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
if ((attr->ia_valid & ATTR_SIZE) &&
(attr->ia_size != inode->i_size))
return -EINVAL;
setattr_copy(inode, attr);
setattr_copy(&init_user_ns, inode, attr);
mark_inode_dirty(inode);
return 0;
}

View File

@@ -444,3 +444,4 @@
439 common faccessat2 sys_faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr sys_mount_setattr

View File

@@ -444,3 +444,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -487,3 +487,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -446,3 +446,4 @@
439 i386 faccessat2 sys_faccessat2
440 i386 process_madvise sys_process_madvise
441 i386 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 i386 mount_setattr sys_mount_setattr

View File

@@ -363,6 +363,7 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
#
# Due to a historical design error, certain syscalls are numbered differently

View File

@@ -412,3 +412,4 @@
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr

View File

@@ -355,7 +355,8 @@ static inline bool is_binderfs_control_device(const struct dentry *dentry)
return info->control_dentry == dentry;
}
static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry,
static int binderfs_rename(struct user_namespace *mnt_userns,
struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
{
@@ -363,7 +364,8 @@ static int binderfs_rename(struct inode *old_dir, struct dentry *old_dentry,
is_binderfs_control_device(new_dentry))
return -EPERM;
return simple_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
return simple_rename(&init_user_ns, old_dir, old_dentry, new_dir,
new_dentry, flags);
}
static int binderfs_unlink(struct inode *dir, struct dentry *dentry)

View File

@@ -162,7 +162,7 @@ static int dev_mkdir(const char *name, umode_t mode)
if (IS_ERR(dentry))
return PTR_ERR(dentry);
err = vfs_mkdir(d_inode(path.dentry), dentry, mode);
err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode);
if (!err)
/* mark as kernel-created inode */
d_inode(dentry)->i_private = &thread;
@@ -212,7 +212,8 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid,
if (IS_ERR(dentry))
return PTR_ERR(dentry);
err = vfs_mknod(d_inode(path.dentry), dentry, mode, dev->devt);
err = vfs_mknod(&init_user_ns, d_inode(path.dentry), dentry, mode,
dev->devt);
if (!err) {
struct iattr newattrs;
@@ -221,7 +222,7 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid,
newattrs.ia_gid = gid;
newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID;
inode_lock(d_inode(dentry));
notify_change(dentry, &newattrs, NULL);
notify_change(&init_user_ns, dentry, &newattrs, NULL);
inode_unlock(d_inode(dentry));
/* mark as kernel-created inode */
@@ -242,7 +243,8 @@ static int dev_rmdir(const char *name)
return PTR_ERR(dentry);
if (d_really_is_positive(dentry)) {
if (d_inode(dentry)->i_private == &thread)
err = vfs_rmdir(d_inode(parent.dentry), dentry);
err = vfs_rmdir(&init_user_ns, d_inode(parent.dentry),
dentry);
else
err = -EPERM;
} else {
@@ -328,9 +330,10 @@ static int handle_remove(const char *nodename, struct device *dev)
newattrs.ia_valid =
ATTR_UID|ATTR_GID|ATTR_MODE;
inode_lock(d_inode(dentry));
notify_change(dentry, &newattrs, NULL);
notify_change(&init_user_ns, dentry, &newattrs, NULL);
inode_unlock(d_inode(dentry));
err = vfs_unlink(d_inode(parent.dentry), dentry, NULL);
err = vfs_unlink(&init_user_ns, d_inode(parent.dentry),
dentry, NULL);
if (!err || err == -ENOENT)
deleted = 1;
}

View File

@@ -239,6 +239,7 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
}
static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)
@@ -258,7 +259,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EPERM;
if (value) {
/* update the cached acl value */
@@ -279,7 +280,8 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
struct iattr iattr = { 0 };
struct posix_acl *old_acl = acl;
retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
retval = posix_acl_update_mode(&init_user_ns, inode,
&iattr.ia_mode, &acl);
if (retval)
goto err_out;
if (!acl) {
@@ -297,7 +299,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
* What is the following setxattr update the
* mode ?
*/
v9fs_vfs_setattr_dotl(dentry, &iattr);
v9fs_vfs_setattr_dotl(&init_user_ns, dentry, &iattr);
}
break;
case ACL_TYPE_DEFAULT:

View File

@@ -135,7 +135,8 @@ extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags);
extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
extern int v9fs_vfs_rename(struct user_namespace *mnt_userns,
struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags);
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,

View File

@@ -59,7 +59,8 @@ void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
int v9fs_uflags2omode(int uflags, int extended);
void v9fs_blank_wstat(struct p9_wstat *wstat);
int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
int v9fs_vfs_setattr_dotl(struct user_namespace *, struct dentry *,
struct iattr *);
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
int datasync);
int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);

View File

@@ -251,7 +251,7 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
{
int err = 0;
inode_init_owner(inode, NULL, mode);
inode_init_owner(&init_user_ns,inode, NULL, mode);
inode->i_blocks = 0;
inode->i_rdev = rdev;
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
@@ -676,8 +676,8 @@ error:
*/
static int
v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl)
v9fs_vfs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
u32 perm = unixmode2p9mode(v9ses, mode);
@@ -702,7 +702,8 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
*
*/
static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
static int v9fs_vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
int err;
u32 perm;
@@ -907,9 +908,9 @@ int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
*/
int
v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
int retval;
struct inode *old_inode;
@@ -1016,8 +1017,8 @@ done:
*/
static int
v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
v9fs_vfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct v9fs_session_info *v9ses;
@@ -1027,7 +1028,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
v9ses = v9fs_dentry2v9ses(dentry);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
generic_fillattr(d_inode(dentry), stat);
generic_fillattr(&init_user_ns, d_inode(dentry), stat);
return 0;
}
fid = v9fs_fid_lookup(dentry);
@@ -1040,7 +1041,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
return PTR_ERR(st);
v9fs_stat2inode(st, d_inode(dentry), dentry->d_sb, 0);
generic_fillattr(d_inode(dentry), stat);
generic_fillattr(&init_user_ns, d_inode(dentry), stat);
p9stat_free(st);
kfree(st);
@@ -1054,7 +1055,8 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
*
*/
static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
static int v9fs_vfs_setattr(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *iattr)
{
int retval, use_dentry = 0;
struct v9fs_session_info *v9ses;
@@ -1062,7 +1064,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
struct p9_wstat wstat;
p9_debug(P9_DEBUG_VFS, "\n");
retval = setattr_prepare(dentry, iattr);
retval = setattr_prepare(&init_user_ns, dentry, iattr);
if (retval)
return retval;
@@ -1118,7 +1120,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
v9fs_invalidate_inode_attr(d_inode(dentry));
setattr_copy(d_inode(dentry), iattr);
setattr_copy(&init_user_ns, d_inode(dentry), iattr);
mark_inode_dirty(d_inode(dentry));
return 0;
}
@@ -1295,7 +1297,8 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
*/
static int
v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
v9fs_vfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *symname)
{
p9_debug(P9_DEBUG_VFS, " %lu,%pd,%s\n",
dir->i_ino, dentry, symname);
@@ -1348,7 +1351,8 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
*/
static int
v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
v9fs_vfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev)
{
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
int retval;

View File

@@ -33,8 +33,8 @@
#include "acl.h"
static int
v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
dev_t rdev);
v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t omode, dev_t rdev);
/**
* v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
@@ -218,10 +218,10 @@ int v9fs_open_to_dotl_flags(int flags)
*/
static int
v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
bool excl)
v9fs_vfs_create_dotl(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t omode, bool excl)
{
return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
return v9fs_vfs_mknod_dotl(mnt_userns, dir, dentry, omode, 0);
}
static int
@@ -367,8 +367,9 @@ err_clunk_old_fid:
*
*/
static int v9fs_vfs_mkdir_dotl(struct inode *dir,
struct dentry *dentry, umode_t omode)
static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
umode_t omode)
{
int err;
struct v9fs_session_info *v9ses;
@@ -457,7 +458,8 @@ error:
}
static int
v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
v9fs_vfs_getattr_dotl(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
@@ -468,7 +470,7 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
v9ses = v9fs_dentry2v9ses(dentry);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
generic_fillattr(d_inode(dentry), stat);
generic_fillattr(&init_user_ns, d_inode(dentry), stat);
return 0;
}
fid = v9fs_fid_lookup(dentry);
@@ -485,7 +487,7 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
return PTR_ERR(st);
v9fs_stat2inode_dotl(st, d_inode(dentry), 0);
generic_fillattr(d_inode(dentry), stat);
generic_fillattr(&init_user_ns, d_inode(dentry), stat);
/* Change block size to what the server returned */
stat->blksize = st->st_blksize;
@@ -540,7 +542,8 @@ static int v9fs_mapped_iattr_valid(int iattr_valid)
*
*/
int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *iattr)
{
int retval, use_dentry = 0;
struct p9_fid *fid = NULL;
@@ -549,7 +552,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
p9_debug(P9_DEBUG_VFS, "\n");
retval = setattr_prepare(dentry, iattr);
retval = setattr_prepare(&init_user_ns, dentry, iattr);
if (retval)
return retval;
@@ -590,7 +593,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
truncate_setsize(inode, iattr->ia_size);
v9fs_invalidate_inode_attr(inode);
setattr_copy(inode, iattr);
setattr_copy(&init_user_ns, inode, iattr);
mark_inode_dirty(inode);
if (iattr->ia_valid & ATTR_MODE) {
/* We also want to update ACL when we update mode bits */
@@ -684,8 +687,8 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
}
static int
v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
const char *symname)
v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int err;
kgid_t gid;
@@ -824,8 +827,8 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
*
*/
static int
v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
dev_t rdev)
v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t omode, dev_t rdev)
{
int err;
kgid_t gid;

View File

@@ -157,6 +157,7 @@ static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
}
static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)

View File

@@ -144,7 +144,8 @@ struct adfs_discmap {
/* Inode stuff */
struct inode *adfs_iget(struct super_block *sb, struct object_info *obj);
int adfs_write_inode(struct inode *inode, struct writeback_control *wbc);
int adfs_notify_change(struct dentry *dentry, struct iattr *attr);
int adfs_notify_change(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr);
/* map.c */
int adfs_map_lookup(struct super_block *sb, u32 frag_id, unsigned int offset);

View File

@@ -292,14 +292,15 @@ out:
* later.
*/
int
adfs_notify_change(struct dentry *dentry, struct iattr *attr)
adfs_notify_change(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
struct super_block *sb = inode->i_sb;
unsigned int ia_valid = attr->ia_valid;
int error;
error = setattr_prepare(dentry, attr);
error = setattr_prepare(&init_user_ns, dentry, attr);
/*
* we can't change the UID or GID of any file -

View File

@@ -167,27 +167,33 @@ extern const struct export_operations affs_export_ops;
extern int affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int);
extern int affs_unlink(struct inode *dir, struct dentry *dentry);
extern int affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool);
extern int affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
extern int affs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool);
extern int affs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode);
extern int affs_rmdir(struct inode *dir, struct dentry *dentry);
extern int affs_link(struct dentry *olddentry, struct inode *dir,
struct dentry *dentry);
extern int affs_symlink(struct inode *dir, struct dentry *dentry,
extern int affs_symlink(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
const char *symname);
extern int affs_rename2(struct inode *old_dir, struct dentry *old_dentry,
extern int affs_rename2(struct user_namespace *mnt_userns,
struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags);
/* inode.c */
extern struct inode *affs_new_inode(struct inode *dir);
extern int affs_notify_change(struct dentry *dentry, struct iattr *attr);
extern int affs_notify_change(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *attr);
extern void affs_evict_inode(struct inode *inode);
extern struct inode *affs_iget(struct super_block *sb,
unsigned long ino);
extern int affs_write_inode(struct inode *inode,
struct writeback_control *wbc);
extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type);
extern int affs_add_entry(struct inode *dir, struct inode *inode,
struct dentry *dentry, s32 type);
/* file.c */

View File

@@ -216,14 +216,15 @@ affs_write_inode(struct inode *inode, struct writeback_control *wbc)
}
int
affs_notify_change(struct dentry *dentry, struct iattr *attr)
affs_notify_change(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
int error;
pr_debug("notify_change(%lu,0x%x)\n", inode->i_ino, attr->ia_valid);
error = setattr_prepare(dentry, attr);
error = setattr_prepare(&init_user_ns, dentry, attr);
if (error)
goto out;
@@ -249,7 +250,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
affs_truncate(inode);
}
setattr_copy(inode, attr);
setattr_copy(&init_user_ns, inode, attr);
mark_inode_dirty(inode);
if (attr->ia_valid & ATTR_MODE)

View File

@@ -242,7 +242,8 @@ affs_unlink(struct inode *dir, struct dentry *dentry)
}
int
affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
affs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
struct super_block *sb = dir->i_sb;
struct inode *inode;
@@ -273,7 +274,8 @@ affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
}
int
affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
affs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct inode *inode;
int error;
@@ -311,7 +313,8 @@ affs_rmdir(struct inode *dir, struct dentry *dentry)
}
int
affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
affs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct super_block *sb = dir->i_sb;
struct buffer_head *bh;
@@ -500,9 +503,9 @@ done:
return retval;
}
int affs_rename2(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
int affs_rename2(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))

View File

@@ -28,18 +28,19 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int
loff_t fpos, u64 ino, unsigned dtype);
static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
loff_t fpos, u64 ino, unsigned dtype);
static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl);
static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
static int afs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl);
static int afs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode);
static int afs_rmdir(struct inode *dir, struct dentry *dentry);
static int afs_unlink(struct inode *dir, struct dentry *dentry);
static int afs_link(struct dentry *from, struct inode *dir,
struct dentry *dentry);
static int afs_symlink(struct inode *dir, struct dentry *dentry,
const char *content);
static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags);
static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *content);
static int afs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags);
static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags);
static void afs_dir_invalidatepage(struct page *page, unsigned int offset,
unsigned int length);
@@ -1325,7 +1326,8 @@ static const struct afs_operation_ops afs_mkdir_operation = {
/*
* create a directory on an AFS filesystem
*/
static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
static int afs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct afs_operation *op;
struct afs_vnode *dvnode = AFS_FS_I(dir);
@@ -1619,8 +1621,8 @@ static const struct afs_operation_ops afs_create_operation = {
/*
* create a regular file on an AFS filesystem
*/
static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl)
static int afs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
struct afs_operation *op;
struct afs_vnode *dvnode = AFS_FS_I(dir);
@@ -1741,8 +1743,8 @@ static const struct afs_operation_ops afs_symlink_operation = {
/*
* create a symlink in an AFS filesystem
*/
static int afs_symlink(struct inode *dir, struct dentry *dentry,
const char *content)
static int afs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *content)
{
struct afs_operation *op;
struct afs_vnode *dvnode = AFS_FS_I(dir);
@@ -1876,9 +1878,9 @@ static const struct afs_operation_ops afs_rename_operation = {
/*
* rename a file in an AFS filesystem and/or move it between directories
*/
static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
static int afs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
struct afs_operation *op;
struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;

View File

@@ -734,8 +734,8 @@ error_unlock:
/*
* read the attributes of an inode
*/
int afs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
int afs_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 afs_vnode *vnode = AFS_FS_I(inode);
@@ -745,7 +745,7 @@ int afs_getattr(const struct path *path, struct kstat *stat,
do {
read_seqbegin_or_lock(&vnode->cb_lock, &seq);
generic_fillattr(inode, stat);
generic_fillattr(&init_user_ns, inode, stat);
if (test_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags) &&
stat->nlink > 0)
stat->nlink -= 1;
@@ -857,7 +857,8 @@ static const struct afs_operation_ops afs_setattr_operation = {
/*
* set the attributes of an inode
*/
int afs_setattr(struct dentry *dentry, struct iattr *attr)
int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct afs_operation *op;
struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));

View File

@@ -1149,8 +1149,9 @@ extern struct inode *afs_iget(struct afs_operation *, struct afs_vnode_param *);
extern struct inode *afs_root_iget(struct super_block *, struct key *);
extern bool afs_check_validity(struct afs_vnode *);
extern int afs_validate(struct afs_vnode *, struct key *);
extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern int afs_setattr(struct dentry *, struct iattr *);
extern int afs_getattr(struct user_namespace *mnt_userns, const struct path *,
struct kstat *, u32, unsigned int);
extern int afs_setattr(struct user_namespace *mnt_userns, struct dentry *, struct iattr *);
extern void afs_evict_inode(struct inode *);
extern int afs_drop_inode(struct inode *);
@@ -1361,7 +1362,7 @@ extern void afs_zap_permits(struct rcu_head *);
extern struct key *afs_request_key(struct afs_cell *);
extern struct key *afs_request_key_rcu(struct afs_cell *);
extern int afs_check_permit(struct afs_vnode *, struct key *, afs_access_t *);
extern int afs_permission(struct inode *, int);
extern int afs_permission(struct user_namespace *, struct inode *, int);
extern void __exit afs_clean_up_permit_cache(void);
/*

View File

@@ -396,7 +396,8 @@ int afs_check_permit(struct afs_vnode *vnode, struct key *key,
* - AFS ACLs are attached to directories only, and a file is controlled by its
* parent directory's ACL
*/
int afs_permission(struct inode *inode, int mask)
int afs_permission(struct user_namespace *mnt_userns, struct inode *inode,
int mask)
{
struct afs_vnode *vnode = AFS_FS_I(inode);
afs_access_t access;

View File

@@ -120,6 +120,7 @@ static const struct afs_operation_ops afs_store_acl_operation = {
* Set a file's AFS3 ACL.
*/
static int afs_xattr_set_acl(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *dentry,
struct inode *inode, const char *name,
const void *buffer, size_t size, int flags)
@@ -248,6 +249,7 @@ static const struct afs_operation_ops yfs_store_opaque_acl2_operation = {
* Set a file's YFS ACL.
*/
static int afs_xattr_set_yfs(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *dentry,
struct inode *inode, const char *name,
const void *buffer, size_t size, int flags)

124
fs/attr.c
View File

@@ -18,27 +18,55 @@
#include <linux/evm.h>
#include <linux/ima.h>
static bool chown_ok(const struct inode *inode, kuid_t uid)
/**
* chown_ok - verify permissions to chown inode
* @mnt_userns: user namespace of the mount @inode was found from
* @inode: inode to check permissions on
* @uid: uid to chown @inode to
*
* If the inode has been found through an idmapped mount the user namespace of
* the vfsmount must be passed through @mnt_userns. This function will then
* take care to map the inode according to @mnt_userns before checking
* permissions. On non-idmapped mounts or if permission checking is to be
* performed on the raw inode simply passs init_user_ns.
*/
static bool chown_ok(struct user_namespace *mnt_userns,
const struct inode *inode,
kuid_t uid)
{
if (uid_eq(current_fsuid(), inode->i_uid) &&
uid_eq(uid, inode->i_uid))
kuid_t kuid = i_uid_into_mnt(mnt_userns, inode);
if (uid_eq(current_fsuid(), kuid) && uid_eq(uid, kuid))
return true;
if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
return true;
if (uid_eq(inode->i_uid, INVALID_UID) &&
if (uid_eq(kuid, INVALID_UID) &&
ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
return true;
return false;
}
static bool chgrp_ok(const struct inode *inode, kgid_t gid)
/**
* chgrp_ok - verify permissions to chgrp inode
* @mnt_userns: user namespace of the mount @inode was found from
* @inode: inode to check permissions on
* @gid: gid to chown @inode to
*
* If the inode has been found through an idmapped mount the user namespace of
* the vfsmount must be passed through @mnt_userns. This function will then
* take care to map the inode according to @mnt_userns before checking
* permissions. On non-idmapped mounts or if permission checking is to be
* performed on the raw inode simply passs init_user_ns.
*/
static bool chgrp_ok(struct user_namespace *mnt_userns,
const struct inode *inode, kgid_t gid)
{
if (uid_eq(current_fsuid(), inode->i_uid) &&
(in_group_p(gid) || gid_eq(gid, inode->i_gid)))
kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)) &&
(in_group_p(gid) || gid_eq(gid, kgid)))
return true;
if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
return true;
if (gid_eq(inode->i_gid, INVALID_GID) &&
if (gid_eq(kgid, INVALID_GID) &&
ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
return true;
return false;
@@ -46,6 +74,7 @@ static bool chgrp_ok(const struct inode *inode, kgid_t gid)
/**
* setattr_prepare - check if attribute changes to a dentry are allowed
* @mnt_userns: user namespace of the mount the inode was found from
* @dentry: dentry to check
* @attr: attributes to change
*
@@ -55,10 +84,17 @@ static bool chgrp_ok(const struct inode *inode, kgid_t gid)
* SGID bit from mode if user is not allowed to set it. Also file capabilities
* and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
*
* If the inode has been found through an idmapped mount the user namespace of
* the vfsmount must be passed through @mnt_userns. This function will then
* take care to map the inode according to @mnt_userns before checking
* permissions. On non-idmapped mounts or if permission checking is to be
* performed on the raw inode simply passs init_user_ns.
*
* Should be called as the first thing in ->setattr implementations,
* possibly after taking additional locks.
*/
int setattr_prepare(struct dentry *dentry, struct iattr *attr)
int setattr_prepare(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
unsigned int ia_valid = attr->ia_valid;
@@ -78,27 +114,27 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr)
goto kill_priv;
/* Make sure a caller can chown. */
if ((ia_valid & ATTR_UID) && !chown_ok(inode, attr->ia_uid))
if ((ia_valid & ATTR_UID) && !chown_ok(mnt_userns, inode, attr->ia_uid))
return -EPERM;
/* Make sure caller can chgrp. */
if ((ia_valid & ATTR_GID) && !chgrp_ok(inode, attr->ia_gid))
if ((ia_valid & ATTR_GID) && !chgrp_ok(mnt_userns, inode, attr->ia_gid))
return -EPERM;
/* Make sure a caller can chmod. */
if (ia_valid & ATTR_MODE) {
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(mnt_userns, inode))
return -EPERM;
/* Also check the setgid bit! */
if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
inode->i_gid) &&
!capable_wrt_inode_uidgid(inode, CAP_FSETID))
i_gid_into_mnt(mnt_userns, inode)) &&
!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
attr->ia_mode &= ~S_ISGID;
}
/* Check for setting the inode time. */
if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(mnt_userns, inode))
return -EPERM;
}
@@ -107,7 +143,7 @@ kill_priv:
if (ia_valid & ATTR_KILL_PRIV) {
int error;
error = security_inode_killpriv(dentry);
error = security_inode_killpriv(mnt_userns, dentry);
if (error)
return error;
}
@@ -162,20 +198,33 @@ EXPORT_SYMBOL(inode_newsize_ok);
/**
* setattr_copy - copy simple metadata updates into the generic inode
* @mnt_userns: user namespace of the mount the inode was found from
* @inode: the inode to be updated
* @attr: the new attributes
*
* setattr_copy must be called with i_mutex held.
*
* setattr_copy updates the inode's metadata with that specified
* in attr. Noticeably missing is inode size update, which is more complex
* in attr on idmapped mounts. If file ownership is changed setattr_copy
* doesn't map ia_uid and ia_gid. It will asssume the caller has already
* provided the intended values. Necessary permission checks to determine
* whether or not the S_ISGID property needs to be removed are performed with
* the correct idmapped mount permission helpers.
* Noticeably missing is inode size update, which is more complex
* as it requires pagecache updates.
*
* If the inode has been found through an idmapped mount the user namespace of
* the vfsmount must be passed through @mnt_userns. This function will then
* take care to map the inode according to @mnt_userns before checking
* permissions. On non-idmapped mounts or if permission checking is to be
* performed on the raw inode simply passs init_user_ns.
*
* The inode is not marked as dirty after this operation. The rationale is
* that for "simple" filesystems, the struct inode is the inode storage.
* The caller is free to mark the inode dirty afterwards if needed.
*/
void setattr_copy(struct inode *inode, const struct iattr *attr)
void setattr_copy(struct user_namespace *mnt_userns, struct inode *inode,
const struct iattr *attr)
{
unsigned int ia_valid = attr->ia_valid;
@@ -191,9 +240,9 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
inode->i_ctime = attr->ia_ctime;
if (ia_valid & ATTR_MODE) {
umode_t mode = attr->ia_mode;
if (!in_group_p(inode->i_gid) &&
!capable_wrt_inode_uidgid(inode, CAP_FSETID))
kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
if (!in_group_p(kgid) &&
!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
mode &= ~S_ISGID;
inode->i_mode = mode;
}
@@ -202,6 +251,7 @@ EXPORT_SYMBOL(setattr_copy);
/**
* notify_change - modify attributes of a filesytem object
* @mnt_userns: user namespace of the mount the inode was found from
* @dentry: object affected
* @attr: new attributes
* @delegated_inode: returns inode, if the inode is delegated
@@ -214,13 +264,23 @@ EXPORT_SYMBOL(setattr_copy);
* retry. Because breaking a delegation may take a long time, the
* caller should drop the i_mutex before doing so.
*
* If file ownership is changed notify_change() doesn't map ia_uid and
* ia_gid. It will asssume the caller has already provided the intended values.
*
* Alternatively, a caller may pass NULL for delegated_inode. This may
* be appropriate for callers that expect the underlying filesystem not
* to be NFS exported. Also, passing NULL is fine for callers holding
* the file open for write, as there can be no conflicting delegation in
* that case.
*
* If the inode has been found through an idmapped mount the user namespace of
* the vfsmount must be passed through @mnt_userns. This function will then
* take care to map the inode according to @mnt_userns before checking
* permissions. On non-idmapped mounts or if permission checking is to be
* performed on the raw inode simply passs init_user_ns.
*/
int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode)
int notify_change(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr, struct inode **delegated_inode)
{
struct inode *inode = dentry->d_inode;
umode_t mode = inode->i_mode;
@@ -243,8 +303,8 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
if (IS_IMMUTABLE(inode))
return -EPERM;
if (!inode_owner_or_capable(inode)) {
error = inode_permission(inode, MAY_WRITE);
if (!inode_owner_or_capable(mnt_userns, inode)) {
error = inode_permission(mnt_userns, inode, MAY_WRITE);
if (error)
return error;
}
@@ -320,9 +380,11 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
/* Don't allow modifications of files with invalid uids or
* gids unless those uids & gids are being made valid.
*/
if (!(ia_valid & ATTR_UID) && !uid_valid(inode->i_uid))
if (!(ia_valid & ATTR_UID) &&
!uid_valid(i_uid_into_mnt(mnt_userns, inode)))
return -EOVERFLOW;
if (!(ia_valid & ATTR_GID) && !gid_valid(inode->i_gid))
if (!(ia_valid & ATTR_GID) &&
!gid_valid(i_gid_into_mnt(mnt_userns, inode)))
return -EOVERFLOW;
error = security_inode_setattr(dentry, attr);
@@ -333,13 +395,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
return error;
if (inode->i_op->setattr)
error = inode->i_op->setattr(dentry, attr);
error = inode->i_op->setattr(mnt_userns, dentry, attr);
else
error = simple_setattr(dentry, attr);
error = simple_setattr(mnt_userns, dentry, attr);
if (!error) {
fsnotify_change(dentry, ia_valid);
ima_inode_post_setattr(dentry);
ima_inode_post_setattr(mnt_userns, dentry);
evm_inode_post_setattr(dentry, ia_valid);
}

View File

@@ -10,10 +10,12 @@
#include "autofs_i.h"
static int autofs_dir_symlink(struct inode *, struct dentry *, const char *);
static int autofs_dir_symlink(struct user_namespace *, struct inode *,
struct dentry *, const char *);
static int autofs_dir_unlink(struct inode *, struct dentry *);
static int autofs_dir_rmdir(struct inode *, struct dentry *);
static int autofs_dir_mkdir(struct inode *, struct dentry *, umode_t);
static int autofs_dir_mkdir(struct user_namespace *, struct inode *,
struct dentry *, umode_t);
static long autofs_root_ioctl(struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT
static long autofs_root_compat_ioctl(struct file *,
@@ -524,8 +526,8 @@ static struct dentry *autofs_lookup(struct inode *dir,
return NULL;
}
static int autofs_dir_symlink(struct inode *dir,
struct dentry *dentry,
static int autofs_dir_symlink(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
const char *symname)
{
struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
@@ -715,8 +717,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
return 0;
}
static int autofs_dir_mkdir(struct inode *dir,
struct dentry *dentry, umode_t mode)
static int autofs_dir_mkdir(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
umode_t mode)
{
struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
struct autofs_info *ino = autofs_dentry_ino(dentry);

View File

@@ -27,7 +27,8 @@ static const struct file_operations bad_file_ops =
.open = bad_file_open,
};
static int bad_inode_create (struct inode *dir, struct dentry *dentry,
static int bad_inode_create(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
umode_t mode, bool excl)
{
return -EIO;
@@ -50,14 +51,15 @@ static int bad_inode_unlink(struct inode *dir, struct dentry *dentry)
return -EIO;
}
static int bad_inode_symlink (struct inode *dir, struct dentry *dentry,
static int bad_inode_symlink(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
const char *symname)
{
return -EIO;
}
static int bad_inode_mkdir(struct inode *dir, struct dentry *dentry,
umode_t mode)
static int bad_inode_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
return -EIO;
}
@@ -67,13 +69,14 @@ static int bad_inode_rmdir (struct inode *dir, struct dentry *dentry)
return -EIO;
}
static int bad_inode_mknod (struct inode *dir, struct dentry *dentry,
umode_t mode, dev_t rdev)
static int bad_inode_mknod(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev)
{
return -EIO;
}
static int bad_inode_rename2(struct inode *old_dir, struct dentry *old_dentry,
static int bad_inode_rename2(struct user_namespace *mnt_userns,
struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
{
@@ -86,18 +89,21 @@ static int bad_inode_readlink(struct dentry *dentry, char __user *buffer,
return -EIO;
}
static int bad_inode_permission(struct inode *inode, int mask)
static int bad_inode_permission(struct user_namespace *mnt_userns,
struct inode *inode, int mask)
{
return -EIO;
}
static int bad_inode_getattr(const struct path *path, struct kstat *stat,
static int bad_inode_getattr(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{
return -EIO;
}
static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs)
static int bad_inode_setattr(struct user_namespace *mnt_userns,
struct dentry *direntry, struct iattr *attrs)
{
return -EIO;
}
@@ -140,13 +146,15 @@ static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry,
return -EIO;
}
static int bad_inode_tmpfile(struct inode *inode, struct dentry *dentry,
static int bad_inode_tmpfile(struct user_namespace *mnt_userns,
struct inode *inode, struct dentry *dentry,
umode_t mode)
{
return -EIO;
}
static int bad_inode_set_acl(struct inode *inode, struct posix_acl *acl,
static int bad_inode_set_acl(struct user_namespace *mnt_userns,
struct inode *inode, struct posix_acl *acl,
int type)
{
return -EIO;

View File

@@ -75,8 +75,8 @@ const struct file_operations bfs_dir_operations = {
.llseek = generic_file_llseek,
};
static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl)
static int bfs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
int err;
struct inode *inode;
@@ -96,7 +96,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
}
set_bit(ino, info->si_imap);
info->si_freei--;
inode_init_owner(inode, dir, mode);
inode_init_owner(&init_user_ns, inode, dir, mode);
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
inode->i_blocks = 0;
inode->i_op = &bfs_file_inops;
@@ -199,9 +199,9 @@ out_brelse:
return error;
}
static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
static int bfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
struct inode *old_inode, *new_inode;
struct buffer_head *old_bh, *new_bh;

View File

@@ -107,13 +107,15 @@ out:
return ret;
}
int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
struct posix_acl *acl, int type)
{
int ret;
umode_t old_mode = inode->i_mode;
if (type == ACL_TYPE_ACCESS && acl) {
ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
ret = posix_acl_update_mode(&init_user_ns, inode,
&inode->i_mode, &acl);
if (ret)
return ret;
}

View File

@@ -3635,7 +3635,8 @@ static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag)
/* acl.c */
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
struct posix_acl *btrfs_get_acl(struct inode *inode, int type);
int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
struct posix_acl *acl, int type);
int btrfs_init_acl(struct btrfs_trans_handle *trans,
struct inode *inode, struct inode *dir);
#else

View File

@@ -5212,7 +5212,8 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)
return ret;
}
static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
static int btrfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -5221,7 +5222,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
if (btrfs_root_readonly(root))
return -EROFS;
err = setattr_prepare(dentry, attr);
err = setattr_prepare(&init_user_ns, dentry, attr);
if (err)
return err;
@@ -5232,12 +5233,13 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
}
if (attr->ia_valid) {
setattr_copy(inode, attr);
setattr_copy(&init_user_ns, inode, attr);
inode_inc_iversion(inode);
err = btrfs_dirty_inode(inode);
if (!err && attr->ia_valid & ATTR_MODE)
err = posix_acl_chmod(inode, inode->i_mode);
err = posix_acl_chmod(&init_user_ns, inode,
inode->i_mode);
}
return err;
@@ -6357,7 +6359,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
if (ret != 0)
goto fail_unlock;
inode_init_owner(inode, dir, mode);
inode_init_owner(&init_user_ns, inode, dir, mode);
inode_set_bytes(inode, 0);
inode->i_mtime = current_time(inode);
@@ -6518,8 +6520,8 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
return err;
}
static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
umode_t mode, dev_t rdev)
static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev)
{
struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
struct btrfs_trans_handle *trans;
@@ -6582,8 +6584,8 @@ out_unlock:
return err;
}
static int btrfs_create(struct inode *dir, struct dentry *dentry,
umode_t mode, bool excl)
static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
struct btrfs_trans_handle *trans;
@@ -6727,7 +6729,8 @@ fail:
return err;
}
static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
struct inode *inode = NULL;
@@ -9017,7 +9020,8 @@ fail:
return -ENOMEM;
}
static int btrfs_getattr(const struct path *path, struct kstat *stat,
static int btrfs_getattr(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
u64 delalloc_bytes;
@@ -9043,7 +9047,7 @@ static int btrfs_getattr(const struct path *path, struct kstat *stat,
STATX_ATTR_IMMUTABLE |
STATX_ATTR_NODUMP);
generic_fillattr(inode, stat);
generic_fillattr(&init_user_ns, inode, stat);
stat->dev = BTRFS_I(inode)->root->anon_dev;
spin_lock(&BTRFS_I(inode)->lock);
@@ -9534,9 +9538,9 @@ out_notrans:
return ret;
}
static int btrfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
static int btrfs_rename2(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
return -EINVAL;
@@ -9744,8 +9748,8 @@ out:
return ret;
}
static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
const char *symname)
static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *symname)
{
struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
struct btrfs_trans_handle *trans;
@@ -10079,7 +10083,8 @@ static int btrfs_set_page_dirty(struct page *page)
return __set_page_dirty_nobuffers(page);
}
static int btrfs_permission(struct inode *inode, int mask)
static int btrfs_permission(struct user_namespace *mnt_userns,
struct inode *inode, int mask)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
umode_t mode = inode->i_mode;
@@ -10091,10 +10096,11 @@ static int btrfs_permission(struct inode *inode, int mask)
if (BTRFS_I(inode)->flags & BTRFS_INODE_READONLY)
return -EACCES;
}
return generic_permission(inode, mask);
return generic_permission(&init_user_ns, inode, mask);
}
static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
struct btrfs_trans_handle *trans;

View File

@@ -213,7 +213,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
const char *comp = NULL;
u32 binode_flags;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EPERM;
if (btrfs_root_readonly(root))
@@ -429,7 +429,7 @@ static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg)
unsigned old_i_flags;
int ret = 0;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EPERM;
if (btrfs_root_readonly(root))
@@ -925,13 +925,14 @@ static int btrfs_may_delete(struct inode *dir, struct dentry *victim, int isdir)
BUG_ON(d_inode(victim->d_parent) != dir);
audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
error = inode_permission(&init_user_ns, dir, MAY_WRITE | MAY_EXEC);
if (error)
return error;
if (IS_APPEND(dir))
return -EPERM;
if (check_sticky(dir, d_inode(victim)) || IS_APPEND(d_inode(victim)) ||
IS_IMMUTABLE(d_inode(victim)) || IS_SWAPFILE(d_inode(victim)))
if (check_sticky(&init_user_ns, dir, d_inode(victim)) ||
IS_APPEND(d_inode(victim)) || IS_IMMUTABLE(d_inode(victim)) ||
IS_SWAPFILE(d_inode(victim)))
return -EPERM;
if (isdir) {
if (!d_is_dir(victim))
@@ -954,7 +955,7 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child)
return -EEXIST;
if (IS_DEADDIR(dir))
return -ENOENT;
return inode_permission(dir, MAY_WRITE | MAY_EXEC);
return inode_permission(&init_user_ns, dir, MAY_WRITE | MAY_EXEC);
}
/*
@@ -1871,7 +1872,7 @@ static noinline int __btrfs_ioctl_snap_create(struct file *file,
btrfs_info(BTRFS_I(file_inode(file))->root->fs_info,
"Snapshot src from another FS");
ret = -EXDEV;
} else if (!inode_owner_or_capable(src_inode)) {
} else if (!inode_owner_or_capable(&init_user_ns, src_inode)) {
/*
* Subvolume creation is not restricted, but snapshots
* are limited to own subvolumes only
@@ -1991,7 +1992,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
u64 flags;
int ret = 0;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EPERM;
ret = mnt_want_write_file(file);
@@ -2547,7 +2548,8 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
ret = PTR_ERR(temp_inode);
goto out_put;
}
ret = inode_permission(temp_inode, MAY_READ | MAY_EXEC);
ret = inode_permission(&init_user_ns, temp_inode,
MAY_READ | MAY_EXEC);
iput(temp_inode);
if (ret) {
ret = -EACCES;
@@ -3077,7 +3079,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
if (root == dest)
goto out_dput;
err = inode_permission(inode, MAY_WRITE | MAY_EXEC);
err = inode_permission(&init_user_ns, inode,
MAY_WRITE | MAY_EXEC);
if (err)
goto out_dput;
}
@@ -3148,7 +3151,7 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
* running and allows defrag on files open in read-only mode.
*/
if (!capable(CAP_SYS_ADMIN) &&
inode_permission(inode, MAY_WRITE)) {
inode_permission(&init_user_ns, inode, MAY_WRITE)) {
ret = -EPERM;
goto out;
}
@@ -4460,7 +4463,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file,
int ret = 0;
int received_uuid_changed;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EPERM;
ret = mnt_want_write_file(file);

View File

@@ -62,7 +62,7 @@ struct inode *btrfs_new_test_inode(void)
BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
BTRFS_I(inode)->location.offset = 0;
inode_init_owner(inode, NULL, S_IFREG);
inode_init_owner(&init_user_ns, inode, NULL, S_IFREG);
return inode;
}

View File

@@ -362,6 +362,7 @@ static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
}
static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *unused, struct inode *inode,
const char *name, const void *buffer,
size_t size, int flags)
@@ -371,6 +372,7 @@ static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
}
static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *unused, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)

View File

@@ -470,14 +470,14 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
_debug("discard tail %llx", oi_size);
newattrs.ia_valid = ATTR_SIZE;
newattrs.ia_size = oi_size & PAGE_MASK;
ret = notify_change(object->backer, &newattrs, NULL);
ret = notify_change(&init_user_ns, object->backer, &newattrs, NULL);
if (ret < 0)
goto truncate_failed;
}
newattrs.ia_valid = ATTR_SIZE;
newattrs.ia_size = ni_size;
ret = notify_change(object->backer, &newattrs, NULL);
ret = notify_change(&init_user_ns, object->backer, &newattrs, NULL);
truncate_failed:
inode_unlock(d_inode(object->backer));

View File

@@ -311,7 +311,8 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
cachefiles_io_error(cache, "Unlink security error");
} else {
trace_cachefiles_unlink(object, rep, why);
ret = vfs_unlink(d_inode(dir), rep, NULL);
ret = vfs_unlink(&init_user_ns, d_inode(dir), rep,
NULL);
if (preemptive)
cachefiles_mark_object_buried(cache, rep, why);
@@ -412,9 +413,16 @@ try_again:
if (ret < 0) {
cachefiles_io_error(cache, "Rename security error %d", ret);
} else {
struct renamedata rd = {
.old_mnt_userns = &init_user_ns,
.old_dir = d_inode(dir),
.old_dentry = rep,
.new_mnt_userns = &init_user_ns,
.new_dir = d_inode(cache->graveyard),
.new_dentry = grave,
};
trace_cachefiles_rename(object, rep, grave, why);
ret = vfs_rename(d_inode(dir), rep,
d_inode(cache->graveyard), grave, NULL, 0);
ret = vfs_rename(&rd);
if (ret != 0 && ret != -ENOMEM)
cachefiles_io_error(cache,
"Rename failed with error %d", ret);
@@ -561,7 +569,7 @@ lookup_again:
if (ret < 0)
goto create_error;
start = jiffies;
ret = vfs_mkdir(d_inode(dir), next, 0);
ret = vfs_mkdir(&init_user_ns, d_inode(dir), next, 0);
cachefiles_hist(cachefiles_mkdir_histogram, start);
if (!key)
trace_cachefiles_mkdir(object, next, ret);
@@ -597,7 +605,8 @@ lookup_again:
if (ret < 0)
goto create_error;
start = jiffies;
ret = vfs_create(d_inode(dir), next, S_IFREG, true);
ret = vfs_create(&init_user_ns, d_inode(dir), next,
S_IFREG, true);
cachefiles_hist(cachefiles_create_histogram, start);
trace_cachefiles_create(object, next, ret);
if (ret < 0)
@@ -791,7 +800,7 @@ retry:
ret = security_path_mkdir(&path, subdir, 0700);
if (ret < 0)
goto mkdir_error;
ret = vfs_mkdir(d_inode(dir), subdir, 0700);
ret = vfs_mkdir(&init_user_ns, d_inode(dir), subdir, 0700);
if (ret < 0)
goto mkdir_error;

View File

@@ -39,8 +39,8 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
_enter("%p{%s}", object, type);
/* attempt to install a type label directly */
ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
XATTR_CREATE);
ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, type,
2, XATTR_CREATE);
if (ret == 0) {
_debug("SET"); /* we succeeded */
goto error;
@@ -54,7 +54,8 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
}
/* read the current type label */
ret = vfs_getxattr(dentry, cachefiles_xattr_cache, xtype, 3);
ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, xtype,
3);
if (ret < 0) {
if (ret == -ERANGE)
goto bad_type_length;
@@ -110,9 +111,8 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
_debug("SET #%u", auxdata->len);
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
&auxdata->type, auxdata->len,
XATTR_CREATE);
ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
&auxdata->type, auxdata->len, XATTR_CREATE);
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -140,9 +140,8 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
_debug("SET #%u", auxdata->len);
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
&auxdata->type, auxdata->len,
XATTR_REPLACE);
ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
&auxdata->type, auxdata->len, XATTR_REPLACE);
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -171,7 +170,7 @@ int cachefiles_check_auxdata(struct cachefiles_object *object)
if (!auxbuf)
return -ENOMEM;
xlen = vfs_getxattr(dentry, cachefiles_xattr_cache,
xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
&auxbuf->type, 512 + 1);
ret = -ESTALE;
if (xlen < 1 ||
@@ -213,7 +212,7 @@ int cachefiles_check_object_xattr(struct cachefiles_object *object,
}
/* read the current type label */
ret = vfs_getxattr(dentry, cachefiles_xattr_cache,
ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
&auxbuf->type, 512 + 1);
if (ret < 0) {
if (ret == -ENODATA)
@@ -270,9 +269,9 @@ int cachefiles_check_object_xattr(struct cachefiles_object *object,
}
/* update the current label */
ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
&auxdata->type, auxdata->len,
XATTR_REPLACE);
ret = vfs_setxattr(&init_user_ns, dentry,
cachefiles_xattr_cache, &auxdata->type,
auxdata->len, XATTR_REPLACE);
if (ret < 0) {
cachefiles_io_error_obj(object,
"Can't update xattr on %lu"
@@ -309,7 +308,7 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
{
int ret;
ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
ret = vfs_removexattr(&init_user_ns, dentry, cachefiles_xattr_cache);
if (ret < 0) {
if (ret == -ENOENT || ret == -ENODATA)
ret = 0;

View File

@@ -82,7 +82,8 @@ retry:
return acl;
}
int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
int ceph_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
struct posix_acl *acl, int type)
{
int ret = 0, size = 0;
const char *name = NULL;
@@ -100,7 +101,8 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
case ACL_TYPE_ACCESS:
name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl) {
ret = posix_acl_update_mode(inode, &new_mode, &acl);
ret = posix_acl_update_mode(&init_user_ns, inode,
&new_mode, &acl);
if (ret)
goto out;
}

View File

@@ -823,8 +823,8 @@ int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry)
return PTR_ERR(result);
}
static int ceph_mknod(struct inode *dir, struct dentry *dentry,
umode_t mode, dev_t rdev)
static int ceph_mknod(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev)
{
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
struct ceph_mds_request *req;
@@ -878,14 +878,14 @@ out:
return err;
}
static int ceph_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl)
static int ceph_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
return ceph_mknod(dir, dentry, mode, 0);
return ceph_mknod(mnt_userns, dir, dentry, mode, 0);
}
static int ceph_symlink(struct inode *dir, struct dentry *dentry,
const char *dest)
static int ceph_symlink(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *dest)
{
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
struct ceph_mds_request *req;
@@ -937,7 +937,8 @@ out:
return err;
}
static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
static int ceph_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
struct ceph_mds_request *req;
@@ -1183,9 +1184,9 @@ out:
return err;
}
static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
static int ceph_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(old_dir->i_sb);
struct ceph_mds_request *req;

View File

@@ -2201,7 +2201,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
/*
* setattr
*/
int ceph_setattr(struct dentry *dentry, struct iattr *attr)
int ceph_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
@@ -2210,7 +2211,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
if (ceph_snap(inode) != CEPH_NOSNAP)
return -EROFS;
err = setattr_prepare(dentry, attr);
err = setattr_prepare(&init_user_ns, dentry, attr);
if (err != 0)
return err;
@@ -2225,7 +2226,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
err = __ceph_setattr(inode, attr);
if (err >= 0 && (attr->ia_valid & ATTR_MODE))
err = posix_acl_chmod(inode, attr->ia_mode);
err = posix_acl_chmod(&init_user_ns, inode, attr->ia_mode);
return err;
}
@@ -2284,7 +2285,8 @@ int __ceph_do_getattr(struct inode *inode, struct page *locked_page,
* Check inode permissions. We verify we have a valid value for
* the AUTH cap, then call the generic handler.
*/
int ceph_permission(struct inode *inode, int mask)
int ceph_permission(struct user_namespace *mnt_userns, struct inode *inode,
int mask)
{
int err;
@@ -2294,7 +2296,7 @@ int ceph_permission(struct inode *inode, int mask)
err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED, false);
if (!err)
err = generic_permission(inode, mask);
err = generic_permission(&init_user_ns, inode, mask);
return err;
}
@@ -2331,8 +2333,8 @@ static int statx_to_caps(u32 want, umode_t mode)
* Get all the attributes. If we have sufficient caps for the requested attrs,
* then we can avoid talking to the MDS at all.
*/
int ceph_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
struct inode *inode = d_inode(path->dentry);
struct ceph_inode_info *ci = ceph_inode(inode);
@@ -2348,7 +2350,7 @@ int ceph_getattr(const struct path *path, struct kstat *stat,
return err;
}
generic_fillattr(inode, stat);
generic_fillattr(&init_user_ns, inode, stat);
stat->ino = ceph_present_inode(inode);
/*

View File

@@ -1000,10 +1000,13 @@ static inline int ceph_do_getattr(struct inode *inode, int mask, bool force)
{
return __ceph_do_getattr(inode, NULL, mask, force);
}
extern int ceph_permission(struct inode *inode, int mask);
extern int ceph_permission(struct user_namespace *mnt_userns,
struct inode *inode, int mask);
extern int __ceph_setattr(struct inode *inode, struct iattr *attr);
extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
extern int ceph_getattr(const struct path *path, struct kstat *stat,
extern int ceph_setattr(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *attr);
extern int ceph_getattr(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags);
/* xattr.c */
@@ -1064,7 +1067,8 @@ void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx);
#ifdef CONFIG_CEPH_FS_POSIX_ACL
struct posix_acl *ceph_get_acl(struct inode *, int);
int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type);
int ceph_set_acl(struct user_namespace *mnt_userns,
struct inode *inode, struct posix_acl *acl, int type);
int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
struct ceph_acl_sec_ctx *as_ctx);
void ceph_init_inode_acls(struct inode *inode,

View File

@@ -1238,6 +1238,7 @@ static int ceph_get_xattr_handler(const struct xattr_handler *handler,
}
static int ceph_set_xattr_handler(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *unused, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)

View File

@@ -305,7 +305,8 @@ static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
return -EOPNOTSUPP;
}
static int cifs_permission(struct inode *inode, int mask)
static int cifs_permission(struct user_namespace *mnt_userns,
struct inode *inode, int mask)
{
struct cifs_sb_info *cifs_sb;
@@ -320,7 +321,7 @@ static int cifs_permission(struct inode *inode, int mask)
on the client (above and beyond ACL on servers) for
servers which do not support setting and viewing mode bits,
so allowing client to check permissions is useful */
return generic_permission(inode, mask);
return generic_permission(&init_user_ns, inode, mask);
}
static struct kmem_cache *cifs_inode_cachep;

View File

@@ -62,19 +62,22 @@ extern void cifs_sb_deactive(struct super_block *sb);
/* Functions related to inodes */
extern const struct inode_operations cifs_dir_inode_ops;
extern struct inode *cifs_root_iget(struct super_block *);
extern int cifs_create(struct inode *, struct dentry *, umode_t,
bool excl);
extern int cifs_create(struct user_namespace *, struct inode *,
struct dentry *, umode_t, bool excl);
extern int cifs_atomic_open(struct inode *, struct dentry *,
struct file *, unsigned, umode_t);
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
unsigned int);
extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
extern int cifs_mkdir(struct inode *, struct dentry *, umode_t);
extern int cifs_mknod(struct user_namespace *, struct inode *, struct dentry *,
umode_t, dev_t);
extern int cifs_mkdir(struct user_namespace *, struct inode *, struct dentry *,
umode_t);
extern int cifs_rmdir(struct inode *, struct dentry *);
extern int cifs_rename2(struct inode *, struct dentry *, struct inode *,
struct dentry *, unsigned int);
extern int cifs_rename2(struct user_namespace *, struct inode *,
struct dentry *, struct inode *, struct dentry *,
unsigned int);
extern int cifs_revalidate_file_attr(struct file *filp);
extern int cifs_revalidate_dentry_attr(struct dentry *);
extern int cifs_revalidate_file(struct file *filp);
@@ -82,8 +85,10 @@ extern int cifs_revalidate_dentry(struct dentry *);
extern int cifs_invalidate_mapping(struct inode *inode);
extern int cifs_revalidate_mapping(struct inode *inode);
extern int cifs_zap_mapping(struct inode *inode);
extern int cifs_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern int cifs_setattr(struct dentry *, struct iattr *);
extern int cifs_getattr(struct user_namespace *, const struct path *,
struct kstat *, u32, unsigned int);
extern int cifs_setattr(struct user_namespace *, struct dentry *,
struct iattr *);
extern int cifs_fiemap(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
@@ -132,8 +137,8 @@ extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
/* Functions related to symlinks */
extern const char *cifs_get_link(struct dentry *, struct inode *,
struct delayed_call *);
extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
const char *symname);
extern int cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode,
struct dentry *direntry, const char *symname);
#ifdef CONFIG_CIFS_XATTR
extern const struct xattr_handler *cifs_xattr_handlers[];

View File

@@ -567,8 +567,8 @@ out_free_xid:
return rc;
}
int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
bool excl)
int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
struct dentry *direntry, umode_t mode, bool excl)
{
int rc;
unsigned int xid = get_xid();
@@ -611,8 +611,8 @@ out_free_xid:
return rc;
}
int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
dev_t device_number)
int cifs_mknod(struct user_namespace *mnt_userns, struct inode *inode,
struct dentry *direntry, umode_t mode, dev_t device_number)
{
int rc = -EPERM;
unsigned int xid;

View File

@@ -1857,7 +1857,8 @@ posix_mkdir_get_info:
goto posix_mkdir_out;
}
int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode,
struct dentry *direntry, umode_t mode)
{
int rc = 0;
unsigned int xid;
@@ -2067,9 +2068,9 @@ do_rename_exit:
}
int
cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
struct inode *target_dir, struct dentry *target_dentry,
unsigned int flags)
cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
struct dentry *source_dentry, struct inode *target_dir,
struct dentry *target_dentry, unsigned int flags)
{
char *from_name = NULL;
char *to_name = NULL;
@@ -2370,8 +2371,8 @@ int cifs_revalidate_dentry(struct dentry *dentry)
return cifs_revalidate_mapping(inode);
}
int cifs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
int cifs_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
@@ -2408,7 +2409,7 @@ int cifs_getattr(const struct path *path, struct kstat *stat,
return rc;
}
generic_fillattr(inode, stat);
generic_fillattr(&init_user_ns, inode, stat);
stat->blksize = cifs_sb->ctx->bsize;
stat->ino = CIFS_I(inode)->uniqueid;
@@ -2610,7 +2611,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
attrs->ia_valid |= ATTR_FORCE;
rc = setattr_prepare(direntry, attrs);
rc = setattr_prepare(&init_user_ns, direntry, attrs);
if (rc < 0)
goto out;
@@ -2715,7 +2716,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
attrs->ia_size != i_size_read(inode))
truncate_setsize(inode, attrs->ia_size);
setattr_copy(inode, attrs);
setattr_copy(&init_user_ns, inode, attrs);
mark_inode_dirty(inode);
/* force revalidate when any of these times are set since some
@@ -2757,7 +2758,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
attrs->ia_valid |= ATTR_FORCE;
rc = setattr_prepare(direntry, attrs);
rc = setattr_prepare(&init_user_ns, direntry, attrs);
if (rc < 0) {
free_xid(xid);
return rc;
@@ -2913,7 +2914,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
attrs->ia_size != i_size_read(inode))
truncate_setsize(inode, attrs->ia_size);
setattr_copy(inode, attrs);
setattr_copy(&init_user_ns, inode, attrs);
mark_inode_dirty(inode);
cifs_setattr_exit:
@@ -2923,7 +2924,8 @@ cifs_setattr_exit:
}
int
cifs_setattr(struct dentry *direntry, struct iattr *attrs)
cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry,
struct iattr *attrs)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);

View File

@@ -661,7 +661,8 @@ cifs_get_link(struct dentry *direntry, struct inode *inode,
}
int
cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode,
struct dentry *direntry, const char *symname)
{
int rc = -EOPNOTSUPP;
unsigned int xid;

View File

@@ -101,6 +101,7 @@ static int cifs_creation_time_set(unsigned int xid, struct cifs_tcon *pTcon,
}
static int cifs_xattr_set(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)

View File

@@ -46,10 +46,12 @@ extern const struct file_operations coda_ioctl_operations;
/* operations shared over more than one file */
int coda_open(struct inode *i, struct file *f);
int coda_release(struct inode *i, struct file *f);
int coda_permission(struct inode *inode, int mask);
int coda_permission(struct user_namespace *mnt_userns, struct inode *inode,
int mask);
int coda_revalidate_inode(struct inode *);
int coda_getattr(const struct path *, struct kstat *, u32, unsigned int);
int coda_setattr(struct dentry *, struct iattr *);
int coda_getattr(struct user_namespace *, const struct path *, struct kstat *,
u32, unsigned int);
int coda_setattr(struct user_namespace *, struct dentry *, struct iattr *);
/* this file: heloers */
char *coda_f2s(struct CodaFid *f);

View File

@@ -73,7 +73,8 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsig
}
int coda_permission(struct inode *inode, int mask)
int coda_permission(struct user_namespace *mnt_userns, struct inode *inode,
int mask)
{
int error;
@@ -132,7 +133,8 @@ static inline void coda_dir_drop_nlink(struct inode *dir)
}
/* creation routines: create, mknod, mkdir, link, symlink */
static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl)
static int coda_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *de, umode_t mode, bool excl)
{
int error;
const char *name=de->d_name.name;
@@ -164,7 +166,8 @@ err_out:
return error;
}
static int coda_mkdir(struct inode *dir, struct dentry *de, umode_t mode)
static int coda_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *de, umode_t mode)
{
struct inode *inode;
struct coda_vattr attrs;
@@ -225,7 +228,8 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
}
static int coda_symlink(struct inode *dir_inode, struct dentry *de,
static int coda_symlink(struct user_namespace *mnt_userns,
struct inode *dir_inode, struct dentry *de,
const char *symname)
{
const char *name = de->d_name.name;
@@ -291,9 +295,9 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
}
/* rename */
static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
static int coda_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
const char *old_name = old_dentry->d_name.name;
const char *new_name = new_dentry->d_name.name;

View File

@@ -251,16 +251,17 @@ static void coda_evict_inode(struct inode *inode)
coda_cache_clear_inode(inode);
}
int coda_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
int coda_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
int err = coda_revalidate_inode(d_inode(path->dentry));
if (!err)
generic_fillattr(d_inode(path->dentry), stat);
generic_fillattr(&init_user_ns, d_inode(path->dentry), stat);
return err;
}
int coda_setattr(struct dentry *de, struct iattr *iattr)
int coda_setattr(struct user_namespace *mnt_userns, struct dentry *de,
struct iattr *iattr)
{
struct inode *inode = d_inode(de);
struct coda_vattr vattr;

View File

@@ -24,7 +24,8 @@
#include "coda_linux.h"
/* pioctl ops */
static int coda_ioctl_permission(struct inode *inode, int mask);
static int coda_ioctl_permission(struct user_namespace *mnt_userns,
struct inode *inode, int mask);
static long coda_pioctl(struct file *filp, unsigned int cmd,
unsigned long user_data);
@@ -40,7 +41,8 @@ const struct file_operations coda_ioctl_operations = {
};
/* the coda pioctl inode ops */
static int coda_ioctl_permission(struct inode *inode, int mask)
static int coda_ioctl_permission(struct user_namespace *mnt_userns,
struct inode *inode, int mask)
{
return (mask & MAY_EXEC) ? -EACCES : 0;
}

View File

@@ -79,7 +79,8 @@ extern void configfs_hash_and_remove(struct dentry * dir, const char * name);
extern const unsigned char * configfs_get_name(struct configfs_dirent *sd);
extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent);
extern int configfs_setattr(struct dentry *dentry, struct iattr *iattr);
extern int configfs_setattr(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *iattr);
extern struct dentry *configfs_pin_fs(void);
extern void configfs_release_fs(void);
@@ -92,7 +93,8 @@ extern const struct inode_operations configfs_root_inode_operations;
extern const struct inode_operations configfs_symlink_inode_operations;
extern const struct dentry_operations configfs_dentry_ops;
extern int configfs_symlink(struct inode *dir, struct dentry *dentry,
extern int configfs_symlink(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
const char *symname);
extern int configfs_unlink(struct inode *dir, struct dentry *dentry);

View File

@@ -1268,7 +1268,8 @@ out_root_unlock:
}
EXPORT_SYMBOL(configfs_depend_item_unlocked);
static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
static int configfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
int ret = 0;
int module_got = 0;

View File

@@ -40,7 +40,8 @@ static const struct inode_operations configfs_inode_operations ={
.setattr = configfs_setattr,
};
int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
int configfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *iattr)
{
struct inode * inode = d_inode(dentry);
struct configfs_dirent * sd = dentry->d_fsdata;
@@ -67,7 +68,7 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
}
/* attributes were changed atleast once in past */
error = simple_setattr(dentry, iattr);
error = simple_setattr(mnt_userns, dentry, iattr);
if (error)
return error;

View File

@@ -139,7 +139,8 @@ static int get_target(const char *symname, struct path *path,
}
int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
int configfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, const char *symname)
{
int ret;
struct path path;
@@ -197,7 +198,8 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
if (dentry->d_inode || d_unhashed(dentry))
ret = -EEXIST;
else
ret = inode_permission(dir, MAY_WRITE | MAY_EXEC);
ret = inode_permission(&init_user_ns, dir,
MAY_WRITE | MAY_EXEC);
if (!ret)
ret = type->ct_item_ops->allow_link(parent_item, target_item);
if (!ret) {

View File

@@ -703,6 +703,7 @@ void do_coredump(const kernel_siginfo_t *siginfo)
goto close_fail;
}
} else {
struct user_namespace *mnt_userns;
struct inode *inode;
int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW |
O_LARGEFILE | O_EXCL;
@@ -780,13 +781,15 @@ void do_coredump(const kernel_siginfo_t *siginfo)
* a process dumps core while its cwd is e.g. on a vfat
* filesystem.
*/
if (!uid_eq(inode->i_uid, current_fsuid()))
mnt_userns = file_mnt_user_ns(cprm.file);
if (!uid_eq(i_uid_into_mnt(mnt_userns, inode), current_fsuid()))
goto close_fail;
if ((inode->i_mode & 0677) != 0600)
goto close_fail;
if (!(cprm.file->f_mode & FMODE_CAN_WRITE))
goto close_fail;
if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
if (do_truncate(mnt_userns, cprm.file->f_path.dentry,
0, 0, cprm.file))
goto close_fail;
}
@@ -931,7 +934,8 @@ void dump_truncate(struct coredump_params *cprm)
if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
offset = file->f_op->llseek(file, 0, SEEK_CUR);
if (i_size_read(file->f_mapping->host) < offset)
do_truncate(file->f_path.dentry, offset, 0, file);
do_truncate(file_mnt_user_ns(file), file->f_path.dentry,
offset, 0, file);
}
}
EXPORT_SYMBOL(dump_truncate);

View File

@@ -465,7 +465,7 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
return -EFAULT;
policy.version = version;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EACCES;
ret = mnt_want_write_file(filp);

View File

@@ -42,13 +42,14 @@ static unsigned int debugfs_allow = DEFAULT_DEBUGFS_ALLOW_BITS;
* so that we can use the file mode as part of a heuristic to determine whether
* to lock down individual files.
*/
static int debugfs_setattr(struct dentry *dentry, struct iattr *ia)
static int debugfs_setattr(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *ia)
{
int ret = security_locked_down(LOCKDOWN_DEBUGFS);
if (ret && (ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
return ret;
return simple_setattr(dentry, ia);
return simple_setattr(&init_user_ns, dentry, ia);
}
static const struct inode_operations debugfs_file_inode_operations = {
@@ -775,8 +776,8 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
take_dentry_name_snapshot(&old_name, old_dentry);
error = simple_rename(d_inode(old_dir), old_dentry, d_inode(new_dir),
dentry, 0);
error = simple_rename(&init_user_ns, d_inode(old_dir), old_dentry,
d_inode(new_dir), dentry, 0);
if (error) {
release_dentry_name_snapshot(&old_name);
goto exit;

View File

@@ -1110,8 +1110,8 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
}
inode_lock(lower_inode);
rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
page_virt, size, 0);
rc = __vfs_setxattr(&init_user_ns, lower_dentry, lower_inode,
ECRYPTFS_XATTR_NAME, page_virt, size, 0);
if (!rc && ecryptfs_inode)
fsstack_copy_attr_all(ecryptfs_inode, lower_inode);
inode_unlock(lower_inode);

View File

@@ -141,7 +141,8 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
else if (d_unhashed(lower_dentry))
rc = -EINVAL;
else
rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
rc = vfs_unlink(&init_user_ns, lower_dir_inode, lower_dentry,
NULL);
if (rc) {
printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
goto out_unlock;
@@ -180,7 +181,8 @@ ecryptfs_do_create(struct inode *directory_inode,
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
lower_dir_dentry = lock_parent(lower_dentry);
rc = vfs_create(d_inode(lower_dir_dentry), lower_dentry, mode, true);
rc = vfs_create(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
mode, true);
if (rc) {
printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
"rc = [%d]\n", __func__, rc);
@@ -190,7 +192,8 @@ ecryptfs_do_create(struct inode *directory_inode,
inode = __ecryptfs_get_inode(d_inode(lower_dentry),
directory_inode->i_sb);
if (IS_ERR(inode)) {
vfs_unlink(d_inode(lower_dir_dentry), lower_dentry, NULL);
vfs_unlink(&init_user_ns, d_inode(lower_dir_dentry),
lower_dentry, NULL);
goto out_lock;
}
fsstack_copy_attr_times(directory_inode, d_inode(lower_dir_dentry));
@@ -254,7 +257,8 @@ out:
* Returns zero on success; non-zero on error condition
*/
static int
ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
ecryptfs_create(struct user_namespace *mnt_userns,
struct inode *directory_inode, struct dentry *ecryptfs_dentry,
umode_t mode, bool excl)
{
struct inode *ecryptfs_inode;
@@ -436,8 +440,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
dget(lower_old_dentry);
dget(lower_new_dentry);
lower_dir_dentry = lock_parent(lower_new_dentry);
rc = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry),
lower_new_dentry, NULL);
rc = vfs_link(lower_old_dentry, &init_user_ns,
d_inode(lower_dir_dentry), lower_new_dentry, NULL);
if (rc || d_really_is_negative(lower_new_dentry))
goto out_lock;
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
@@ -460,7 +464,8 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
return ecryptfs_do_unlink(dir, dentry, d_inode(dentry));
}
static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
static int ecryptfs_symlink(struct user_namespace *mnt_userns,
struct inode *dir, struct dentry *dentry,
const char *symname)
{
int rc;
@@ -481,7 +486,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
strlen(symname));
if (rc)
goto out_lock;
rc = vfs_symlink(d_inode(lower_dir_dentry), lower_dentry,
rc = vfs_symlink(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
encoded_symname);
kfree(encoded_symname);
if (rc || d_really_is_negative(lower_dentry))
@@ -499,7 +504,8 @@ out_lock:
return rc;
}
static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
static int ecryptfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
int rc;
struct dentry *lower_dentry;
@@ -507,7 +513,8 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
lower_dentry = ecryptfs_dentry_to_lower(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
rc = vfs_mkdir(d_inode(lower_dir_dentry), lower_dentry, mode);
rc = vfs_mkdir(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
mode);
if (rc || d_really_is_negative(lower_dentry))
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
@@ -541,7 +548,7 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
else if (d_unhashed(lower_dentry))
rc = -EINVAL;
else
rc = vfs_rmdir(lower_dir_inode, lower_dentry);
rc = vfs_rmdir(&init_user_ns, lower_dir_inode, lower_dentry);
if (!rc) {
clear_nlink(d_inode(dentry));
fsstack_copy_attr_times(dir, lower_dir_inode);
@@ -555,7 +562,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
}
static int
ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
ecryptfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t dev)
{
int rc;
struct dentry *lower_dentry;
@@ -563,7 +571,8 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev
lower_dentry = ecryptfs_dentry_to_lower(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
rc = vfs_mknod(d_inode(lower_dir_dentry), lower_dentry, mode, dev);
rc = vfs_mknod(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry,
mode, dev);
if (rc || d_really_is_negative(lower_dentry))
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
@@ -579,9 +588,9 @@ out:
}
static int
ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
ecryptfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
{
int rc;
struct dentry *lower_old_dentry;
@@ -590,6 +599,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct dentry *lower_new_dir_dentry;
struct dentry *trap;
struct inode *target_inode;
struct renamedata rd = {};
if (flags)
return -EINVAL;
@@ -619,9 +629,14 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
rc = -ENOTEMPTY;
goto out_lock;
}
rc = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
d_inode(lower_new_dir_dentry), lower_new_dentry,
NULL, 0);
rd.old_mnt_userns = &init_user_ns;
rd.old_dir = d_inode(lower_old_dir_dentry);
rd.old_dentry = lower_old_dentry;
rd.new_mnt_userns = &init_user_ns;
rd.new_dir = d_inode(lower_new_dir_dentry);
rd.new_dentry = lower_new_dentry;
rc = vfs_rename(&rd);
if (rc)
goto out_lock;
if (target_inode)
@@ -855,16 +870,19 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
inode_lock(d_inode(lower_dentry));
rc = notify_change(lower_dentry, &lower_ia, NULL);
rc = notify_change(&init_user_ns, lower_dentry,
&lower_ia, NULL);
inode_unlock(d_inode(lower_dentry));
}
return rc;
}
static int
ecryptfs_permission(struct inode *inode, int mask)
ecryptfs_permission(struct user_namespace *mnt_userns, struct inode *inode,
int mask)
{
return inode_permission(ecryptfs_inode_to_lower(inode), mask);
return inode_permission(&init_user_ns,
ecryptfs_inode_to_lower(inode), mask);
}
/**
@@ -879,7 +897,8 @@ ecryptfs_permission(struct inode *inode, int mask)
* All other metadata changes will be passed right to the lower filesystem,
* and we will just update our inode to look like the lower.
*/
static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
static int ecryptfs_setattr(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *ia)
{
int rc = 0;
struct dentry *lower_dentry;
@@ -933,7 +952,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
}
mutex_unlock(&crypt_stat->cs_mutex);
rc = setattr_prepare(dentry, ia);
rc = setattr_prepare(&init_user_ns, dentry, ia);
if (rc)
goto out;
if (ia->ia_valid & ATTR_SIZE) {
@@ -959,14 +978,15 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
lower_ia.ia_valid &= ~ATTR_MODE;
inode_lock(d_inode(lower_dentry));
rc = notify_change(lower_dentry, &lower_ia, NULL);
rc = notify_change(&init_user_ns, lower_dentry, &lower_ia, NULL);
inode_unlock(d_inode(lower_dentry));
out:
fsstack_copy_attr_all(inode, lower_inode);
return rc;
}
static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat,
static int ecryptfs_getattr_link(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
@@ -975,7 +995,7 @@ static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat,
mount_crypt_stat = &ecryptfs_superblock_to_private(
dentry->d_sb)->mount_crypt_stat;
generic_fillattr(d_inode(dentry), stat);
generic_fillattr(&init_user_ns, d_inode(dentry), stat);
if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
char *target;
size_t targetsiz;
@@ -991,7 +1011,8 @@ static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat,
return rc;
}
static int ecryptfs_getattr(const struct path *path, struct kstat *stat,
static int ecryptfs_getattr(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
@@ -1003,7 +1024,7 @@ static int ecryptfs_getattr(const struct path *path, struct kstat *stat,
if (!rc) {
fsstack_copy_attr_all(d_inode(dentry),
ecryptfs_inode_to_lower(d_inode(dentry)));
generic_fillattr(d_inode(dentry), stat);
generic_fillattr(&init_user_ns, d_inode(dentry), stat);
stat->blocks = lower_stat.blocks;
}
return rc;
@@ -1025,7 +1046,7 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
goto out;
}
inode_lock(lower_inode);
rc = __vfs_setxattr_locked(lower_dentry, name, value, size, flags, NULL);
rc = __vfs_setxattr_locked(&init_user_ns, lower_dentry, name, value, size, flags, NULL);
inode_unlock(lower_inode);
if (!rc && inode)
fsstack_copy_attr_all(inode, lower_inode);
@@ -1091,7 +1112,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
goto out;
}
inode_lock(lower_inode);
rc = __vfs_removexattr(lower_dentry, name);
rc = __vfs_removexattr(&init_user_ns, lower_dentry, name);
inode_unlock(lower_inode);
out:
return rc;
@@ -1135,6 +1156,7 @@ static int ecryptfs_xattr_get(const struct xattr_handler *handler,
}
static int ecryptfs_xattr_set(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value, size_t size,
int flags)

View File

@@ -531,6 +531,12 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
goto out_free;
}
if (mnt_user_ns(path.mnt) != &init_user_ns) {
rc = -EINVAL;
printk(KERN_ERR "Mounting on idmapped mounts currently disallowed\n");
goto out_free;
}
if (check_ruid && !uid_eq(d_inode(path.dentry)->i_uid, current_uid())) {
rc = -EPERM;
printk(KERN_ERR "Mount of device (uid: %d) not owned by "

View File

@@ -426,8 +426,8 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
if (size < 0)
size = 8;
put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
xattr_virt, size, 0);
rc = __vfs_setxattr(&init_user_ns, lower_dentry, lower_inode,
ECRYPTFS_XATTR_NAME, xattr_virt, size, 0);
inode_unlock(lower_inode);
if (rc)
printk(KERN_ERR "Error whilst attempting to write inode size "

View File

@@ -137,7 +137,7 @@ efivarfs_ioc_setxflags(struct file *file, void __user *arg)
unsigned int oldflags = efivarfs_getflags(inode);
int error;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EACCES;
if (copy_from_user(&flags, arg, sizeof(flags)))

View File

@@ -66,8 +66,8 @@ bool efivarfs_valid_name(const char *str, int len)
return uuid_is_valid(s);
}
static int efivarfs_create(struct inode *dir, struct dentry *dentry,
umode_t mode, bool excl)
static int efivarfs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
struct inode *inode = NULL;
struct efivar_entry *var;

View File

@@ -331,8 +331,9 @@ struct inode *erofs_iget(struct super_block *sb,
return inode;
}
int erofs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
int erofs_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, u32 request_mask,
unsigned int query_flags)
{
struct inode *const inode = d_inode(path->dentry);
@@ -343,7 +344,7 @@ int erofs_getattr(const struct path *path, struct kstat *stat,
stat->attributes_mask |= (STATX_ATTR_COMPRESSED |
STATX_ATTR_IMMUTABLE);
generic_fillattr(inode, stat);
generic_fillattr(&init_user_ns, inode, stat);
return 0;
}

View File

@@ -373,8 +373,9 @@ extern const struct inode_operations erofs_symlink_iops;
extern const struct inode_operations erofs_fast_symlink_iops;
struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir);
int erofs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags);
int erofs_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, u32 request_mask,
unsigned int query_flags);
/* namei.c */
extern const struct inode_operations erofs_dir_iops;

View File

@@ -1404,14 +1404,15 @@ EXPORT_SYMBOL(begin_new_exec);
void would_dump(struct linux_binprm *bprm, struct file *file)
{
struct inode *inode = file_inode(file);
if (inode_permission(inode, MAY_READ) < 0) {
struct user_namespace *mnt_userns = file_mnt_user_ns(file);
if (inode_permission(mnt_userns, inode, MAY_READ) < 0) {
struct user_namespace *old, *user_ns;
bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
/* Ensure mm->user_ns contains the executable */
user_ns = old = bprm->mm->user_ns;
while ((user_ns != &init_user_ns) &&
!privileged_wrt_inode_uidgid(user_ns, inode))
!privileged_wrt_inode_uidgid(user_ns, mnt_userns, inode))
user_ns = user_ns->parent;
if (old != user_ns) {
@@ -1579,6 +1580,7 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file)
{
/* Handle suid and sgid on files */
struct user_namespace *mnt_userns;
struct inode *inode;
unsigned int mode;
kuid_t uid;
@@ -1595,13 +1597,15 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file)
if (!(mode & (S_ISUID|S_ISGID)))
return;
mnt_userns = file_mnt_user_ns(file);
/* Be careful if suid/sgid is set */
inode_lock(inode);
/* reload atomically mode/uid/gid now that lock held */
mode = inode->i_mode;
uid = inode->i_uid;
gid = inode->i_gid;
uid = i_uid_into_mnt(mnt_userns, inode);
gid = i_gid_into_mnt(mnt_userns, inode);
inode_unlock(inode);
/* We ignore suid/sgid if there are no mappings for them in the ns */

View File

@@ -416,9 +416,11 @@ int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count);
extern const struct file_operations exfat_file_operations;
int __exfat_truncate(struct inode *inode, loff_t new_size);
void exfat_truncate(struct inode *inode, loff_t size);
int exfat_setattr(struct dentry *dentry, struct iattr *attr);
int exfat_getattr(const struct path *path, struct kstat *stat,
unsigned int request_mask, unsigned int query_flags);
int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr);
int exfat_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, unsigned int request_mask,
unsigned int query_flags);
int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
/* namei.c */

View File

@@ -267,13 +267,14 @@ write_size:
mutex_unlock(&sbi->s_lock);
}
int exfat_getattr(const struct path *path, struct kstat *stat,
unsigned int request_mask, unsigned int query_flags)
int exfat_getattr(struct user_namespace *mnt_uerns, const struct path *path,
struct kstat *stat, unsigned int request_mask,
unsigned int query_flags)
{
struct inode *inode = d_backing_inode(path->dentry);
struct exfat_inode_info *ei = EXFAT_I(inode);
generic_fillattr(inode, stat);
generic_fillattr(&init_user_ns, inode, stat);
exfat_truncate_atime(&stat->atime);
stat->result_mask |= STATX_BTIME;
stat->btime.tv_sec = ei->i_crtime.tv_sec;
@@ -282,7 +283,8 @@ int exfat_getattr(const struct path *path, struct kstat *stat,
return 0;
}
int exfat_setattr(struct dentry *dentry, struct iattr *attr)
int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *attr)
{
struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb);
struct inode *inode = dentry->d_inode;
@@ -305,7 +307,7 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr)
ATTR_TIMES_SET);
}
error = setattr_prepare(dentry, attr);
error = setattr_prepare(&init_user_ns, dentry, attr);
attr->ia_valid = ia_valid;
if (error)
goto out;
@@ -340,7 +342,7 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr)
up_write(&EXFAT_I(inode)->truncate_lock);
}
setattr_copy(inode, attr);
setattr_copy(&init_user_ns, inode, attr);
exfat_truncate_atime(&inode->i_atime);
mark_inode_dirty(inode);

View File

@@ -541,8 +541,8 @@ out:
return ret;
}
static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl)
static int exfat_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
{
struct super_block *sb = dir->i_sb;
struct inode *inode;
@@ -827,7 +827,8 @@ unlock:
return err;
}
static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
static int exfat_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct super_block *sb = dir->i_sb;
struct inode *inode;
@@ -1318,7 +1319,8 @@ out:
return ret;
}
static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
static int exfat_rename(struct user_namespace *mnt_userns,
struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
{

View File

@@ -216,14 +216,16 @@ __ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
* inode->i_mutex: down
*/
int
ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
ext2_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
struct posix_acl *acl, int type)
{
int error;
int update_mode = 0;
umode_t mode = inode->i_mode;
if (type == ACL_TYPE_ACCESS && acl) {
error = posix_acl_update_mode(inode, &mode, &acl);
error = posix_acl_update_mode(&init_user_ns, inode, &mode,
&acl);
if (error)
return error;
update_mode = 1;

View File

@@ -56,7 +56,8 @@ static inline int ext2_acl_count(size_t size)
/* acl.c */
extern struct posix_acl *ext2_get_acl(struct inode *inode, int type);
extern int ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
extern int ext2_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
struct posix_acl *acl, int type);
extern int ext2_init_acl (struct inode *, struct inode *);
#else

View File

@@ -764,8 +764,9 @@ extern struct inode *ext2_iget (struct super_block *, unsigned long);
extern int ext2_write_inode (struct inode *, struct writeback_control *);
extern void ext2_evict_inode(struct inode *);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern int ext2_setattr (struct dentry *, struct iattr *);
extern int ext2_getattr (const struct path *, struct kstat *, u32, unsigned int);
extern int ext2_setattr (struct user_namespace *, struct dentry *, struct iattr *);
extern int ext2_getattr (struct user_namespace *, const struct path *,
struct kstat *, u32, unsigned int);
extern void ext2_set_inode_flags(struct inode *inode);
extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len);

View File

@@ -551,7 +551,7 @@ got:
inode->i_uid = current_fsuid();
inode->i_gid = dir->i_gid;
} else
inode_init_owner(inode, dir, mode);
inode_init_owner(&init_user_ns, inode, dir, mode);
inode->i_ino = ino;
inode->i_blocks = 0;

View File

@@ -1638,8 +1638,8 @@ int ext2_write_inode(struct inode *inode, struct writeback_control *wbc)
return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
}
int ext2_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
int ext2_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 ext2_inode_info *ei = EXT2_I(inode);
@@ -1660,16 +1660,17 @@ int ext2_getattr(const struct path *path, struct kstat *stat,
STATX_ATTR_IMMUTABLE |
STATX_ATTR_NODUMP);
generic_fillattr(inode, stat);
generic_fillattr(&init_user_ns, inode, stat);
return 0;
}
int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
int ext2_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
struct iattr *iattr)
{
struct inode *inode = d_inode(dentry);
int error;
error = setattr_prepare(dentry, iattr);
error = setattr_prepare(&init_user_ns, dentry, iattr);
if (error)
return error;
@@ -1689,9 +1690,9 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
if (error)
return error;
}
setattr_copy(inode, iattr);
setattr_copy(&init_user_ns, inode, iattr);
if (iattr->ia_valid & ATTR_MODE)
error = posix_acl_chmod(inode, inode->i_mode);
error = posix_acl_chmod(&init_user_ns, inode, inode->i_mode);
mark_inode_dirty(inode);
return error;

View File

@@ -39,7 +39,7 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (ret)
return ret;
if (!inode_owner_or_capable(inode)) {
if (!inode_owner_or_capable(&init_user_ns, inode)) {
ret = -EACCES;
goto setflags_out;
}
@@ -84,7 +84,7 @@ setflags_out:
case EXT2_IOC_SETVERSION: {
__u32 generation;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EPERM;
ret = mnt_want_write_file(filp);
if (ret)
@@ -117,7 +117,7 @@ setversion_out:
if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
return -ENOTTY;
if (!inode_owner_or_capable(inode))
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EACCES;
if (get_user(rsv_window_size, (int __user *)arg))

View File

@@ -100,7 +100,9 @@ struct dentry *ext2_get_parent(struct dentry *child)
* If the create succeeds, we fill in the inode information
* with d_instantiate().
*/
static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl)
static int ext2_create (struct user_namespace * mnt_userns,
struct inode * dir, struct dentry * dentry,
umode_t mode, bool excl)
{
struct inode *inode;
int err;
@@ -118,7 +120,8 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode
return ext2_add_nondir(dentry, inode);
}
static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
static int ext2_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
{
struct inode *inode = ext2_new_inode(dir, mode, NULL);
if (IS_ERR(inode))
@@ -131,7 +134,8 @@ static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
return 0;
}
static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev)
static int ext2_mknod (struct user_namespace * mnt_userns, struct inode * dir,
struct dentry *dentry, umode_t mode, dev_t rdev)
{
struct inode * inode;
int err;
@@ -151,8 +155,8 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode,
return err;
}
static int ext2_symlink (struct inode * dir, struct dentry * dentry,
const char * symname)
static int ext2_symlink (struct user_namespace * mnt_userns, struct inode * dir,
struct dentry * dentry, const char * symname)
{
struct super_block * sb = dir->i_sb;
int err = -ENAMETOOLONG;
@@ -225,7 +229,8 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
return err;
}
static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
static int ext2_mkdir(struct user_namespace * mnt_userns,
struct inode * dir, struct dentry * dentry, umode_t mode)
{
struct inode * inode;
int err;
@@ -315,7 +320,8 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
return err;
}
static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
static int ext2_rename (struct user_namespace * mnt_userns,
struct inode * old_dir, struct dentry * old_dentry,
struct inode * new_dir, struct dentry * new_dentry,
unsigned int flags)
{

View File

@@ -19,6 +19,7 @@ ext2_xattr_security_get(const struct xattr_handler *handler,
static int
ext2_xattr_security_set(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *unused, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)

View File

@@ -26,6 +26,7 @@ ext2_xattr_trusted_get(const struct xattr_handler *handler,
static int
ext2_xattr_trusted_set(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *unused, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)

View File

@@ -30,6 +30,7 @@ ext2_xattr_user_get(const struct xattr_handler *handler,
static int
ext2_xattr_user_set(const struct xattr_handler *handler,
struct user_namespace *mnt_userns,
struct dentry *unused, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)

View File

@@ -222,7 +222,8 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
}
int
ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
ext4_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
struct posix_acl *acl, int type)
{
handle_t *handle;
int error, credits, retries = 0;
@@ -245,7 +246,7 @@ retry:
ext4_fc_start_update(inode);
if ((type == ACL_TYPE_ACCESS) && acl) {
error = posix_acl_update_mode(inode, &mode, &acl);
error = posix_acl_update_mode(mnt_userns, inode, &mode, &acl);
if (error)
goto out_stop;
if (mode != inode->i_mode)

View File

@@ -56,7 +56,8 @@ static inline int ext4_acl_count(size_t size)
/* acl.c */
struct posix_acl *ext4_get_acl(struct inode *inode, int type);
int ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type);
int ext4_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
struct posix_acl *acl, int type);
extern int ext4_init_acl(handle_t *, struct inode *, struct inode *);
#else /* CONFIG_EXT4_FS_POSIX_ACL */

View File

@@ -2800,18 +2800,19 @@ extern int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
/* ialloc.c */
extern int ext4_mark_inode_used(struct super_block *sb, int ino);
extern struct inode *__ext4_new_inode(handle_t *, struct inode *, umode_t,
extern struct inode *__ext4_new_inode(struct user_namespace *, handle_t *,
struct inode *, umode_t,
const struct qstr *qstr, __u32 goal,
uid_t *owner, __u32 i_flags,
int handle_type, unsigned int line_no,
int nblocks);
#define ext4_new_inode(handle, dir, mode, qstr, goal, owner, i_flags) \
__ext4_new_inode((handle), (dir), (mode), (qstr), (goal), (owner), \
i_flags, 0, 0, 0)
#define ext4_new_inode_start_handle(dir, mode, qstr, goal, owner, \
__ext4_new_inode(&init_user_ns, (handle), (dir), (mode), (qstr), \
(goal), (owner), i_flags, 0, 0, 0)
#define ext4_new_inode_start_handle(mnt_userns, dir, mode, qstr, goal, owner, \
type, nblocks) \
__ext4_new_inode(NULL, (dir), (mode), (qstr), (goal), (owner), \
__ext4_new_inode((mnt_userns), NULL, (dir), (mode), (qstr), (goal), (owner), \
0, (type), __LINE__, (nblocks))
@@ -2922,11 +2923,14 @@ extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
__ext4_iget((sb), (ino), (flags), __func__, __LINE__)
extern int ext4_write_inode(struct inode *, struct writeback_control *);
extern int ext4_setattr(struct dentry *, struct iattr *);
extern int ext4_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern int ext4_setattr(struct user_namespace *, struct dentry *,
struct iattr *);
extern int ext4_getattr(struct user_namespace *, const struct path *,
struct kstat *, u32, unsigned int);
extern void ext4_evict_inode(struct inode *);
extern void ext4_clear_inode(struct inode *);
extern int ext4_file_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern int ext4_file_getattr(struct user_namespace *, const struct path *,
struct kstat *, u32, unsigned int);
extern int ext4_sync_inode(handle_t *, struct inode *);
extern void ext4_dirty_inode(struct inode *, int);
extern int ext4_change_inode_journal_flag(struct inode *, int);

Some files were not shown because too many files have changed in this diff Show More