projects
/
cascardo
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
GMAC: modify CRU config for Rockchip RK3288 SoCs integrated GMAC
[cascardo/linux.git]
/
fs
/
namespace.c
diff --git
a/fs/namespace.c
b/fs/namespace.c
index
5b66b2b
..
cd1e968
100644
(file)
--- a/
fs/namespace.c
+++ b/
fs/namespace.c
@@
-963,7
+963,8
@@
static struct mount *clone_mnt(struct mount *old, struct dentry *root,
}
/* Don't allow unprivileged users to reveal what is under a mount */
}
/* Don't allow unprivileged users to reveal what is under a mount */
- if ((flag & CL_UNPRIVILEGED) && list_empty(&old->mnt_expire))
+ if ((flag & CL_UNPRIVILEGED) &&
+ (!(flag & CL_EXPIRE) || list_empty(&old->mnt_expire)))
mnt->mnt.mnt_flags |= MNT_LOCKED;
atomic_inc(&sb->s_active);
mnt->mnt.mnt_flags |= MNT_LOCKED;
atomic_inc(&sb->s_active);
@@
-1369,6
+1370,8
@@
void umount_tree(struct mount *mnt, int how)
}
if (last) {
last->mnt_hash.next = unmounted.first;
}
if (last) {
last->mnt_hash.next = unmounted.first;
+ if (unmounted.first)
+ unmounted.first->pprev = &last->mnt_hash.next;
unmounted.first = tmp_list.first;
unmounted.first->pprev = &unmounted.first;
}
unmounted.first = tmp_list.first;
unmounted.first->pprev = &unmounted.first;
}
@@
-1544,6
+1547,9
@@
SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
goto dput_and_out;
if (mnt->mnt.mnt_flags & MNT_LOCKED)
goto dput_and_out;
goto dput_and_out;
if (mnt->mnt.mnt_flags & MNT_LOCKED)
goto dput_and_out;
+ retval = -EPERM;
+ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
+ goto dput_and_out;
retval = do_umount(mnt, flags);
dput_and_out:
retval = do_umount(mnt, flags);
dput_and_out:
@@
-1569,17
+1575,13
@@
SYSCALL_DEFINE1(oldumount, char __user *, name)
static bool is_mnt_ns_file(struct dentry *dentry)
{
/* Is this a proxy for a mount namespace? */
static bool is_mnt_ns_file(struct dentry *dentry)
{
/* Is this a proxy for a mount namespace? */
- struct inode *inode = dentry->d_inode;
- struct proc_ns *ei;
-
- if (!proc_ns_inode(inode))
- return false;
-
- ei = get_proc_ns(inode);
- if (ei->ns_ops != &mntns_operations)
- return false;
+ return dentry->d_op == &ns_dentry_operations &&
+ dentry->d_fsdata == &mntns_operations;
+}
- return true;
+struct mnt_namespace *to_mnt_ns(struct ns_common *ns)
+{
+ return container_of(ns, struct mnt_namespace, ns);
}
static bool mnt_ns_loop(struct dentry *dentry)
}
static bool mnt_ns_loop(struct dentry *dentry)
@@
-1591,7
+1593,7
@@
static bool mnt_ns_loop(struct dentry *dentry)
if (!is_mnt_ns_file(dentry))
return false;
if (!is_mnt_ns_file(dentry))
return false;
- mnt_ns =
get_proc_ns(dentry->d_inode)->ns
;
+ mnt_ns =
to_mnt_ns(get_proc_ns(dentry->d_inode))
;
return current->nsproxy->mnt_ns->seq >= mnt_ns->seq;
}
return current->nsproxy->mnt_ns->seq >= mnt_ns->seq;
}
@@
-1610,7
+1612,6
@@
struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
if (IS_ERR(q))
return q;
if (IS_ERR(q))
return q;
- q->mnt.mnt_flags &= ~MNT_LOCKED;
q->mnt_mountpoint = mnt->mnt_mountpoint;
p = mnt;
q->mnt_mountpoint = mnt->mnt_mountpoint;
p = mnt;
@@
-2020,7
+2021,10
@@
static int do_loopback(struct path *path, const char *old_name,
if (IS_MNT_UNBINDABLE(old))
goto out2;
if (IS_MNT_UNBINDABLE(old))
goto out2;
- if (!check_mnt(parent) || !check_mnt(old))
+ if (!check_mnt(parent))
+ goto out2;
+
+ if (!check_mnt(old) && old_path.dentry->d_op != &ns_dentry_operations)
goto out2;
if (!recurse && has_locked_children(old, old_path.dentry))
goto out2;
if (!recurse && has_locked_children(old, old_path.dentry))
@@
-2098,7
+2102,13
@@
static int do_remount(struct path *path, int flags, int mnt_flags,
}
if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
!(mnt_flags & MNT_NODEV)) {
}
if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
!(mnt_flags & MNT_NODEV)) {
- return -EPERM;
+ /* Was the nodev implicitly added in mount? */
+ if ((mnt->mnt_ns->user_ns != &init_user_ns) &&
+ !(sb->s_type->fs_flags & FS_USERNS_DEV_MOUNT)) {
+ mnt_flags |= MNT_NODEV;
+ } else {
+ return -EPERM;
+ }
}
if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) &&
!(mnt_flags & MNT_NOSUID)) {
}
if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) &&
!(mnt_flags & MNT_NOSUID)) {
@@
-2640,7
+2650,7
@@
dput_out:
static void free_mnt_ns(struct mnt_namespace *ns)
{
static void free_mnt_ns(struct mnt_namespace *ns)
{
-
proc_free_inum(ns->proc_inum
);
+
ns_free_inum(&ns->ns
);
put_user_ns(ns->user_ns);
kfree(ns);
}
put_user_ns(ns->user_ns);
kfree(ns);
}
@@
-2662,11
+2672,12
@@
static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
if (!new_ns)
return ERR_PTR(-ENOMEM);
new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
if (!new_ns)
return ERR_PTR(-ENOMEM);
- ret =
proc_alloc_inum(&new_ns->proc_inum
);
+ ret =
ns_alloc_inum(&new_ns->ns
);
if (ret) {
kfree(new_ns);
return ERR_PTR(ret);
}
if (ret) {
kfree(new_ns);
return ERR_PTR(ret);
}
+ new_ns->ns.ops = &mntns_operations;
new_ns->seq = atomic64_add_return(1, &mnt_ns_seq);
atomic_set(&new_ns->count, 1);
new_ns->root = NULL;
new_ns->seq = atomic64_add_return(1, &mnt_ns_seq);
atomic_set(&new_ns->count, 1);
new_ns->root = NULL;
@@
-2958,6
+2969,8
@@
SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
/* mount new_root on / */
attach_mnt(new_mnt, real_mount(root_parent.mnt), root_mp);
touch_mnt_namespace(current->nsproxy->mnt_ns);
/* mount new_root on / */
attach_mnt(new_mnt, real_mount(root_parent.mnt), root_mp);
touch_mnt_namespace(current->nsproxy->mnt_ns);
+ /* A moved mount should not expire automatically */
+ list_del_init(&new_mnt->mnt_expire);
unlock_mount_hash();
chroot_fs_refs(&root, &new);
put_mountpoint(root_mp);
unlock_mount_hash();
chroot_fs_refs(&root, &new);
put_mountpoint(root_mp);
@@
-3002,6
+3015,7
@@
static void __init init_mount_tree(void)
root.mnt = mnt;
root.dentry = mnt->mnt_root;
root.mnt = mnt;
root.dentry = mnt->mnt_root;
+ mnt->mnt_flags |= MNT_LOCKED;
set_fs_pwd(current->fs, &root);
set_fs_root(current->fs, &root);
set_fs_pwd(current->fs, &root);
set_fs_root(current->fs, &root);
@@
-3144,31
+3158,31
@@
found:
return visible;
}
return visible;
}
-static
void
*mntns_get(struct task_struct *task)
+static
struct ns_common
*mntns_get(struct task_struct *task)
{
{
- struct
mnt_namespace
*ns = NULL;
+ struct
ns_common
*ns = NULL;
struct nsproxy *nsproxy;
task_lock(task);
nsproxy = task->nsproxy;
if (nsproxy) {
struct nsproxy *nsproxy;
task_lock(task);
nsproxy = task->nsproxy;
if (nsproxy) {
- ns =
nsproxy->mnt_
ns;
- get_mnt_ns(
ns
);
+ ns =
&nsproxy->mnt_ns->
ns;
+ get_mnt_ns(
to_mnt_ns(ns)
);
}
task_unlock(task);
return ns;
}
}
task_unlock(task);
return ns;
}
-static void mntns_put(
void
*ns)
+static void mntns_put(
struct ns_common
*ns)
{
{
- put_mnt_ns(
ns
);
+ put_mnt_ns(
to_mnt_ns(ns)
);
}
}
-static int mntns_install(struct nsproxy *nsproxy,
void
*ns)
+static int mntns_install(struct nsproxy *nsproxy,
struct ns_common
*ns)
{
struct fs_struct *fs = current->fs;
{
struct fs_struct *fs = current->fs;
- struct mnt_namespace *mnt_ns =
ns
;
+ struct mnt_namespace *mnt_ns =
to_mnt_ns(ns)
;
struct path root;
if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
struct path root;
if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
@@
-3198,17
+3212,10
@@
static int mntns_install(struct nsproxy *nsproxy, void *ns)
return 0;
}
return 0;
}
-static unsigned int mntns_inum(void *ns)
-{
- struct mnt_namespace *mnt_ns = ns;
- return mnt_ns->proc_inum;
-}
-
const struct proc_ns_operations mntns_operations = {
.name = "mnt",
.type = CLONE_NEWNS,
.get = mntns_get,
.put = mntns_put,
.install = mntns_install,
const struct proc_ns_operations mntns_operations = {
.name = "mnt",
.type = CLONE_NEWNS,
.get = mntns_get,
.put = mntns_put,
.install = mntns_install,
- .inum = mntns_inum,
};
};