b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) /* SPDX-License-Identifier: GPL-2.0 */
b2dba1af3c415 (Al Viro 2011-11-23 19:26:23 -0500 2) #include <linux/mount.h>
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 3) #include <linux/seq_file.h>
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 4) #include <linux/poll.h>
435d5f4bb2ccb (Al Viro 2014-10-31 22:56:04 -0400 5) #include <linux/ns_common.h>
87b95ce0964c0 (Al Viro 2015-01-10 19:01:08 -0500 6) #include <linux/fs_pin.h>
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 7)
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 8) struct mnt_namespace {
435d5f4bb2ccb (Al Viro 2014-10-31 22:56:04 -0400 9) struct ns_common ns;
be08d6d260b6e (Al Viro 2011-12-06 13:32:36 -0500 10) struct mount * root;
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 11) /*
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 12) * Traversal and modification of .list is protected by either
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 13) * - taking namespace_sem for write, OR
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 14) * - taking namespace_sem for read AND taking .ns_lock.
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 15) */
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 16) struct list_head list;
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 17) spinlock_t ns_lock;
771b1371686e0 (Eric W. Biederman 2012-07-26 21:08:32 -0700 18) struct user_namespace *user_ns;
537f7ccb39680 (Eric W. Biederman 2016-08-08 14:37:37 -0500 19) struct ucounts *ucounts;
8823c079ba713 (Eric W. Biederman 2010-03-07 18:49:36 -0800 20) u64 seq; /* Sequence number to prevent loops */
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 21) wait_queue_head_t poll;
c7999c3627bc6 (Al Viro 2014-02-27 14:40:10 -0500 22) u64 event;
d29216842a85c (Eric W. Biederman 2016-09-28 00:27:17 -0500 23) unsigned int mounts; /* # of mounts in the namespace */
d29216842a85c (Eric W. Biederman 2016-09-28 00:27:17 -0500 24) unsigned int pending_mounts;
3859a271a003a (Kees Cook 2016-10-28 01:22:25 -0700 25) } __randomize_layout;
b2dba1af3c415 (Al Viro 2011-11-23 19:26:23 -0500 26)
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 27) struct mnt_pcp {
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 28) int mnt_count;
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 29) int mnt_writers;
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 30) };
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 31)
84d17192d2afd (Al Viro 2013-03-15 10:53:28 -0400 32) struct mountpoint {
0818bf27c05b2 (Al Viro 2014-02-28 13:46:44 -0500 33) struct hlist_node m_hash;
84d17192d2afd (Al Viro 2013-03-15 10:53:28 -0400 34) struct dentry *m_dentry;
0a5eb7c818992 (Eric W. Biederman 2013-09-22 19:37:01 -0700 35) struct hlist_head m_list;
84d17192d2afd (Al Viro 2013-03-15 10:53:28 -0400 36) int m_count;
84d17192d2afd (Al Viro 2013-03-15 10:53:28 -0400 37) };
84d17192d2afd (Al Viro 2013-03-15 10:53:28 -0400 38)
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 39) struct mount {
38129a13e6e71 (Al Viro 2014-03-20 21:10:51 -0400 40) struct hlist_node mnt_hash;
0714a533805a0 (Al Viro 2011-11-24 22:19:58 -0500 41) struct mount *mnt_parent;
a73324da7af40 (Al Viro 2011-11-24 22:25:07 -0500 42) struct dentry *mnt_mountpoint;
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 43) struct vfsmount mnt;
9ea459e110df3 (Al Viro 2014-08-08 13:08:20 -0400 44) union {
9ea459e110df3 (Al Viro 2014-08-08 13:08:20 -0400 45) struct rcu_head mnt_rcu;
9ea459e110df3 (Al Viro 2014-08-08 13:08:20 -0400 46) struct llist_node mnt_llist;
9ea459e110df3 (Al Viro 2014-08-08 13:08:20 -0400 47) };
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 48) #ifdef CONFIG_SMP
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 49) struct mnt_pcp __percpu *mnt_pcp;
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 50) #else
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 51) int mnt_count;
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 52) int mnt_writers;
68e8a9feab251 (Al Viro 2011-11-24 22:53:09 -0500 53) #endif
6b41d536f7c84 (Al Viro 2011-11-24 23:24:33 -0500 54) struct list_head mnt_mounts; /* list of children, anchored here */
6b41d536f7c84 (Al Viro 2011-11-24 23:24:33 -0500 55) struct list_head mnt_child; /* and going through their mnt_child */
39f7c4db1d2d9 (Miklos Szeredi 2011-11-21 12:11:30 +0100 56) struct list_head mnt_instance; /* mount instance on sb->s_mounts */
52ba1621de147 (Al Viro 2011-11-25 02:25:17 -0500 57) const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
1a4eeaf2a8c07 (Al Viro 2011-11-25 02:19:55 -0500 58) struct list_head mnt_list;
6776db3d32b2a (Al Viro 2011-11-25 00:22:05 -0500 59) struct list_head mnt_expire; /* link in fs-specific expiry list */
6776db3d32b2a (Al Viro 2011-11-25 00:22:05 -0500 60) struct list_head mnt_share; /* circular list of shared mounts */
6776db3d32b2a (Al Viro 2011-11-25 00:22:05 -0500 61) struct list_head mnt_slave_list;/* list of slave mounts */
6776db3d32b2a (Al Viro 2011-11-25 00:22:05 -0500 62) struct list_head mnt_slave; /* slave list entry */
32301920f44a9 (Al Viro 2011-11-25 00:10:28 -0500 63) struct mount *mnt_master; /* slave is on master->mnt_slave_list */
143c8c91cee7e (Al Viro 2011-11-25 00:46:35 -0500 64) struct mnt_namespace *mnt_ns; /* containing namespace */
84d17192d2afd (Al Viro 2013-03-15 10:53:28 -0400 65) struct mountpoint *mnt_mp; /* where is it mounted */
56cbb429d9119 (Al Viro 2019-07-04 16:57:51 -0400 66) union {
56cbb429d9119 (Al Viro 2019-07-04 16:57:51 -0400 67) struct hlist_node mnt_mp_list; /* list mounts with the same mountpoint */
56cbb429d9119 (Al Viro 2019-07-04 16:57:51 -0400 68) struct hlist_node mnt_umount;
56cbb429d9119 (Al Viro 2019-07-04 16:57:51 -0400 69) };
99b19d16471e9 (Eric W. Biederman 2016-10-24 16:16:13 -0500 70) struct list_head mnt_umounting; /* list entry for umount propagation */
c63181e6b6df8 (Al Viro 2011-11-25 02:35:16 -0500 71) #ifdef CONFIG_FSNOTIFY
08991e83b7286 (Jan Kara 2017-02-01 09:21:58 +0100 72) struct fsnotify_mark_connector __rcu *mnt_fsnotify_marks;
c63181e6b6df8 (Al Viro 2011-11-25 02:35:16 -0500 73) __u32 mnt_fsnotify_mask;
c63181e6b6df8 (Al Viro 2011-11-25 02:35:16 -0500 74) #endif
15169fe784a98 (Al Viro 2011-11-25 00:50:41 -0500 75) int mnt_id; /* mount identifier */
15169fe784a98 (Al Viro 2011-11-25 00:50:41 -0500 76) int mnt_group_id; /* peer group identifier */
863d684f946eb (Al Viro 2011-11-25 00:57:42 -0500 77) int mnt_expiry_mark; /* true if marked for expiry */
215752fce31c8 (Al Viro 2014-08-07 06:23:41 -0400 78) struct hlist_head mnt_pins;
56cbb429d9119 (Al Viro 2019-07-04 16:57:51 -0400 79) struct hlist_head mnt_stuck_children;
3859a271a003a (Kees Cook 2016-10-28 01:22:25 -0700 80) } __randomize_layout;
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 81)
f7a99c5b7c8bd (Al Viro 2012-06-09 00:59:08 -0400 82) #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
f7a99c5b7c8bd (Al Viro 2012-06-09 00:59:08 -0400 83)
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 84) static inline struct mount *real_mount(struct vfsmount *mnt)
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 85) {
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 86) return container_of(mnt, struct mount, mnt);
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 87) }
7d6fec45a5131 (Al Viro 2011-11-23 12:14:10 -0500 88)
676da58df740f (Al Viro 2011-11-24 21:47:05 -0500 89) static inline int mnt_has_parent(struct mount *mnt)
b2dba1af3c415 (Al Viro 2011-11-23 19:26:23 -0500 90) {
0714a533805a0 (Al Viro 2011-11-24 22:19:58 -0500 91) return mnt != mnt->mnt_parent;
b2dba1af3c415 (Al Viro 2011-11-23 19:26:23 -0500 92) }
c71053659e3bb (Al Viro 2011-11-24 18:22:03 -0500 93)
f7a99c5b7c8bd (Al Viro 2012-06-09 00:59:08 -0400 94) static inline int is_mounted(struct vfsmount *mnt)
f7a99c5b7c8bd (Al Viro 2012-06-09 00:59:08 -0400 95) {
f7a99c5b7c8bd (Al Viro 2012-06-09 00:59:08 -0400 96) /* neither detached nor internal? */
260a459d2e397 (Eric W. Biederman 2014-01-20 15:26:15 -0800 97) return !IS_ERR_OR_NULL(real_mount(mnt)->mnt_ns);
f7a99c5b7c8bd (Al Viro 2012-06-09 00:59:08 -0400 98) }
f7a99c5b7c8bd (Al Viro 2012-06-09 00:59:08 -0400 99)
474279dc0f774 (Al Viro 2013-10-01 16:11:26 -0400 100) extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *);
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 101)
294d71ff2f020 (Al Viro 2015-05-08 11:43:53 -0400 102) extern int __legitimize_mnt(struct vfsmount *, unsigned);
48a066e72d970 (Al Viro 2013-09-29 22:06:07 -0400 103) extern bool legitimize_mnt(struct vfsmount *, unsigned);
48a066e72d970 (Al Viro 2013-09-29 22:06:07 -0400 104)
c6609c0a1c34f (Ian Kent 2016-11-24 08:03:41 +1100 105) static inline bool __path_is_mountpoint(const struct path *path)
c6609c0a1c34f (Ian Kent 2016-11-24 08:03:41 +1100 106) {
c6609c0a1c34f (Ian Kent 2016-11-24 08:03:41 +1100 107) struct mount *m = __lookup_mnt(path->mnt, path->dentry);
c6609c0a1c34f (Ian Kent 2016-11-24 08:03:41 +1100 108) return m && likely(!(m->mnt.mnt_flags & MNT_SYNC_UMOUNT));
c6609c0a1c34f (Ian Kent 2016-11-24 08:03:41 +1100 109) }
c6609c0a1c34f (Ian Kent 2016-11-24 08:03:41 +1100 110)
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 111) extern void __detach_mounts(struct dentry *dentry);
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 112)
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 113) static inline void detach_mounts(struct dentry *dentry)
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 114) {
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 115) if (!d_mountpoint(dentry))
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 116) return;
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 117) __detach_mounts(dentry);
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 118) }
80b5dce8c59b0 (Eric W. Biederman 2013-10-03 01:31:18 -0700 119)
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 120) static inline void get_mnt_ns(struct mnt_namespace *ns)
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 121) {
1a7b8969e664d (Kirill Tkhai 2020-08-03 13:16:42 +0300 122) refcount_inc(&ns->ns.count);
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 123) }
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 124)
48a066e72d970 (Al Viro 2013-09-29 22:06:07 -0400 125) extern seqlock_t mount_lock;
719ea2fbb553a (Al Viro 2013-09-29 11:24:49 -0400 126)
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 127) struct proc_mounts {
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 128) struct mnt_namespace *ns;
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 129) struct path root;
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 130) int (*show)(struct seq_file *, struct vfsmount *);
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 131) struct mount cursor;
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 132) };
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 133)
0226f4923f6c9 (Al Viro 2011-12-06 12:21:54 -0500 134) extern const struct seq_operations mounts_op;
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 135)
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 136) extern bool __is_local_mountpoint(struct dentry *dentry);
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 137) static inline bool is_local_mountpoint(struct dentry *dentry)
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 138) {
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 139) if (!d_mountpoint(dentry))
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 140) return false;
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 141)
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 142) return __is_local_mountpoint(dentry);
7af1364ffa64d (Eric W. Biederman 2013-10-04 19:15:13 -0700 143) }
74e831221cfd7 (Al Viro 2019-01-30 13:30:21 -0500 144)
74e831221cfd7 (Al Viro 2019-01-30 13:30:21 -0500 145) static inline bool is_anon_ns(struct mnt_namespace *ns)
74e831221cfd7 (Al Viro 2019-01-30 13:30:21 -0500 146) {
74e831221cfd7 (Al Viro 2019-01-30 13:30:21 -0500 147) return ns->seq == 0;
74e831221cfd7 (Al Viro 2019-01-30 13:30:21 -0500 148) }
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 149)
9f6c61f96f2d9 (Miklos Szeredi 2020-05-14 16:44:24 +0200 150) extern void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor);