|
@@ -829,31 +829,6 @@ static inline void i_size_write(struct inode *inode, loff_t i_size)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-/* Helper functions so that in most cases filesystems will
|
|
|
- * not need to deal directly with kuid_t and kgid_t and can
|
|
|
- * instead deal with the raw numeric values that are stored
|
|
|
- * in the filesystem.
|
|
|
- */
|
|
|
-static inline uid_t i_uid_read(const struct inode *inode)
|
|
|
-{
|
|
|
- return from_kuid(&init_user_ns, inode->i_uid);
|
|
|
-}
|
|
|
-
|
|
|
-static inline gid_t i_gid_read(const struct inode *inode)
|
|
|
-{
|
|
|
- return from_kgid(&init_user_ns, inode->i_gid);
|
|
|
-}
|
|
|
-
|
|
|
-static inline void i_uid_write(struct inode *inode, uid_t uid)
|
|
|
-{
|
|
|
- inode->i_uid = make_kuid(&init_user_ns, uid);
|
|
|
-}
|
|
|
-
|
|
|
-static inline void i_gid_write(struct inode *inode, gid_t gid)
|
|
|
-{
|
|
|
- inode->i_gid = make_kgid(&init_user_ns, gid);
|
|
|
-}
|
|
|
-
|
|
|
static inline unsigned iminor(const struct inode *inode)
|
|
|
{
|
|
|
return MINOR(inode->i_rdev);
|
|
@@ -1320,6 +1295,10 @@ struct mm_struct;
|
|
|
/* sb->s_iflags */
|
|
|
#define SB_I_CGROUPWB 0x00000001 /* cgroup-aware writeback enabled */
|
|
|
#define SB_I_NOEXEC 0x00000002 /* Ignore executables on this fs */
|
|
|
+#define SB_I_NODEV 0x00000004 /* Ignore devices on this fs */
|
|
|
+
|
|
|
+/* sb->s_iflags to limit user namespace mounts */
|
|
|
+#define SB_I_USERNS_VISIBLE 0x00000010 /* fstype already mounted */
|
|
|
|
|
|
/* Possible states of 'frozen' field */
|
|
|
enum {
|
|
@@ -1422,6 +1401,13 @@ struct super_block {
|
|
|
struct workqueue_struct *s_dio_done_wq;
|
|
|
struct hlist_head s_pins;
|
|
|
|
|
|
+ /*
|
|
|
+ * Owning user namespace and default context in which to
|
|
|
+ * interpret filesystem uids, gids, quotas, device nodes,
|
|
|
+ * xattrs and security labels.
|
|
|
+ */
|
|
|
+ struct user_namespace *s_user_ns;
|
|
|
+
|
|
|
/*
|
|
|
* Keep the lru lists last in the structure so they always sit on their
|
|
|
* own individual cachelines.
|
|
@@ -1446,6 +1432,31 @@ struct super_block {
|
|
|
struct list_head s_inodes_wb; /* writeback inodes */
|
|
|
};
|
|
|
|
|
|
+/* Helper functions so that in most cases filesystems will
|
|
|
+ * not need to deal directly with kuid_t and kgid_t and can
|
|
|
+ * instead deal with the raw numeric values that are stored
|
|
|
+ * in the filesystem.
|
|
|
+ */
|
|
|
+static inline uid_t i_uid_read(const struct inode *inode)
|
|
|
+{
|
|
|
+ return from_kuid(inode->i_sb->s_user_ns, inode->i_uid);
|
|
|
+}
|
|
|
+
|
|
|
+static inline gid_t i_gid_read(const struct inode *inode)
|
|
|
+{
|
|
|
+ return from_kgid(inode->i_sb->s_user_ns, inode->i_gid);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void i_uid_write(struct inode *inode, uid_t uid)
|
|
|
+{
|
|
|
+ inode->i_uid = make_kuid(inode->i_sb->s_user_ns, uid);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void i_gid_write(struct inode *inode, gid_t gid)
|
|
|
+{
|
|
|
+ inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid);
|
|
|
+}
|
|
|
+
|
|
|
extern struct timespec current_fs_time(struct super_block *sb);
|
|
|
|
|
|
/*
|
|
@@ -1588,6 +1599,7 @@ extern int vfs_whiteout(struct inode *, struct dentry *);
|
|
|
*/
|
|
|
extern void inode_init_owner(struct inode *inode, const struct inode *dir,
|
|
|
umode_t mode);
|
|
|
+extern bool may_open_dev(const struct path *path);
|
|
|
/*
|
|
|
* VFS FS_IOC_FIEMAP helper definitions.
|
|
|
*/
|
|
@@ -1858,6 +1870,11 @@ struct super_operations {
|
|
|
#define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
|
|
|
(inode)->i_rdev == WHITEOUT_DEV)
|
|
|
|
|
|
+static inline bool HAS_UNMAPPED_ID(struct inode *inode)
|
|
|
+{
|
|
|
+ return !uid_valid(inode->i_uid) || !gid_valid(inode->i_gid);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Inode state bits. Protected by inode->i_lock
|
|
|
*
|
|
@@ -2006,8 +2023,6 @@ struct file_system_type {
|
|
|
#define FS_BINARY_MOUNTDATA 2
|
|
|
#define FS_HAS_SUBTYPE 4
|
|
|
#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
|
|
|
-#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */
|
|
|
-#define FS_USERNS_VISIBLE 32 /* FS must already be visible */
|
|
|
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
|
|
|
struct dentry *(*mount) (struct file_system_type *, int,
|
|
|
const char *, void *);
|
|
@@ -2028,8 +2043,9 @@ struct file_system_type {
|
|
|
|
|
|
#define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME)
|
|
|
|
|
|
-extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
|
|
|
- void *data, int (*fill_super)(struct super_block *, void *, int));
|
|
|
+extern struct dentry *mount_ns(struct file_system_type *fs_type,
|
|
|
+ int flags, void *data, void *ns, struct user_namespace *user_ns,
|
|
|
+ int (*fill_super)(struct super_block *, void *, int));
|
|
|
extern struct dentry *mount_bdev(struct file_system_type *fs_type,
|
|
|
int flags, const char *dev_name, void *data,
|
|
|
int (*fill_super)(struct super_block *, void *, int));
|
|
@@ -2049,6 +2065,11 @@ void deactivate_locked_super(struct super_block *sb);
|
|
|
int set_anon_super(struct super_block *s, void *data);
|
|
|
int get_anon_bdev(dev_t *);
|
|
|
void free_anon_bdev(dev_t);
|
|
|
+struct super_block *sget_userns(struct file_system_type *type,
|
|
|
+ int (*test)(struct super_block *,void *),
|
|
|
+ int (*set)(struct super_block *,void *),
|
|
|
+ int flags, struct user_namespace *user_ns,
|
|
|
+ void *data);
|
|
|
struct super_block *sget(struct file_system_type *type,
|
|
|
int (*test)(struct super_block *,void *),
|
|
|
int (*set)(struct super_block *,void *),
|