diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/errno.h | 1 | ||||
| -rw-r--r-- | include/linux/fs.h | 14 | ||||
| -rw-r--r-- | include/linux/fs_context.h | 188 | ||||
| -rw-r--r-- | include/linux/fs_parser.h | 151 | ||||
| -rw-r--r-- | include/linux/kernfs.h | 39 | ||||
| -rw-r--r-- | include/linux/lsm_hooks.h | 21 | ||||
| -rw-r--r-- | include/linux/mount.h | 3 | ||||
| -rw-r--r-- | include/linux/security.h | 18 |
8 files changed, 412 insertions, 23 deletions
diff --git a/include/linux/errno.h b/include/linux/errno.h index 3cba627577d6..d73f597a2484 100644 --- a/include/linux/errno.h +++ b/include/linux/errno.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */ | 18 | #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */ |
| 19 | #define EPROBE_DEFER 517 /* Driver requests probe retry */ | 19 | #define EPROBE_DEFER 517 /* Driver requests probe retry */ |
| 20 | #define EOPENSTALE 518 /* open found a stale dentry */ | 20 | #define EOPENSTALE 518 /* open found a stale dentry */ |
| 21 | #define ENOPARAM 519 /* Parameter not supported */ | ||
| 21 | 22 | ||
| 22 | /* Defined for the NFSv3 protocol */ | 23 | /* Defined for the NFSv3 protocol */ |
| 23 | #define EBADHANDLE 521 /* Illegal NFS file handle */ | 24 | #define EBADHANDLE 521 /* Illegal NFS file handle */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 80c6a4093b46..8b42df09b04c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -64,6 +64,8 @@ struct workqueue_struct; | |||
| 64 | struct iov_iter; | 64 | struct iov_iter; |
| 65 | struct fscrypt_info; | 65 | struct fscrypt_info; |
| 66 | struct fscrypt_operations; | 66 | struct fscrypt_operations; |
| 67 | struct fs_context; | ||
| 68 | struct fs_parameter_description; | ||
| 67 | 69 | ||
| 68 | extern void __init inode_init(void); | 70 | extern void __init inode_init(void); |
| 69 | extern void __init inode_init_early(void); | 71 | extern void __init inode_init_early(void); |
| @@ -1349,6 +1351,7 @@ extern int send_sigurg(struct fown_struct *fown); | |||
| 1349 | 1351 | ||
| 1350 | /* These sb flags are internal to the kernel */ | 1352 | /* These sb flags are internal to the kernel */ |
| 1351 | #define SB_SUBMOUNT (1<<26) | 1353 | #define SB_SUBMOUNT (1<<26) |
| 1354 | #define SB_FORCE (1<<27) | ||
| 1352 | #define SB_NOSEC (1<<28) | 1355 | #define SB_NOSEC (1<<28) |
| 1353 | #define SB_BORN (1<<29) | 1356 | #define SB_BORN (1<<29) |
| 1354 | #define SB_ACTIVE (1<<30) | 1357 | #define SB_ACTIVE (1<<30) |
| @@ -1459,7 +1462,7 @@ struct super_block { | |||
| 1459 | * Filesystem subtype. If non-empty the filesystem type field | 1462 | * Filesystem subtype. If non-empty the filesystem type field |
| 1460 | * in /proc/mounts will be "type.subtype" | 1463 | * in /proc/mounts will be "type.subtype" |
| 1461 | */ | 1464 | */ |
| 1462 | char *s_subtype; | 1465 | const char *s_subtype; |
| 1463 | 1466 | ||
| 1464 | const struct dentry_operations *s_d_op; /* default d_op for dentries */ | 1467 | const struct dentry_operations *s_d_op; /* default d_op for dentries */ |
| 1465 | 1468 | ||
| @@ -2170,6 +2173,8 @@ struct file_system_type { | |||
| 2170 | #define FS_HAS_SUBTYPE 4 | 2173 | #define FS_HAS_SUBTYPE 4 |
| 2171 | #define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */ | 2174 | #define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */ |
| 2172 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ | 2175 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ |
| 2176 | int (*init_fs_context)(struct fs_context *); | ||
| 2177 | const struct fs_parameter_description *parameters; | ||
| 2173 | struct dentry *(*mount) (struct file_system_type *, int, | 2178 | struct dentry *(*mount) (struct file_system_type *, int, |
| 2174 | const char *, void *); | 2179 | const char *, void *); |
| 2175 | void (*kill_sb) (struct super_block *); | 2180 | void (*kill_sb) (struct super_block *); |
| @@ -2225,8 +2230,12 @@ void kill_litter_super(struct super_block *sb); | |||
| 2225 | void deactivate_super(struct super_block *sb); | 2230 | void deactivate_super(struct super_block *sb); |
| 2226 | void deactivate_locked_super(struct super_block *sb); | 2231 | void deactivate_locked_super(struct super_block *sb); |
| 2227 | int set_anon_super(struct super_block *s, void *data); | 2232 | int set_anon_super(struct super_block *s, void *data); |
| 2233 | int set_anon_super_fc(struct super_block *s, struct fs_context *fc); | ||
| 2228 | int get_anon_bdev(dev_t *); | 2234 | int get_anon_bdev(dev_t *); |
| 2229 | void free_anon_bdev(dev_t); | 2235 | void free_anon_bdev(dev_t); |
| 2236 | struct super_block *sget_fc(struct fs_context *fc, | ||
| 2237 | int (*test)(struct super_block *, struct fs_context *), | ||
| 2238 | int (*set)(struct super_block *, struct fs_context *)); | ||
| 2230 | struct super_block *sget_userns(struct file_system_type *type, | 2239 | struct super_block *sget_userns(struct file_system_type *type, |
| 2231 | int (*test)(struct super_block *,void *), | 2240 | int (*test)(struct super_block *,void *), |
| 2232 | int (*set)(struct super_block *,void *), | 2241 | int (*set)(struct super_block *,void *), |
| @@ -2269,8 +2278,7 @@ mount_pseudo(struct file_system_type *fs_type, char *name, | |||
| 2269 | 2278 | ||
| 2270 | extern int register_filesystem(struct file_system_type *); | 2279 | extern int register_filesystem(struct file_system_type *); |
| 2271 | extern int unregister_filesystem(struct file_system_type *); | 2280 | extern int unregister_filesystem(struct file_system_type *); |
| 2272 | extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data); | 2281 | extern struct vfsmount *kern_mount(struct file_system_type *); |
| 2273 | #define kern_mount(type) kern_mount_data(type, NULL) | ||
| 2274 | extern void kern_unmount(struct vfsmount *mnt); | 2282 | extern void kern_unmount(struct vfsmount *mnt); |
| 2275 | extern int may_umount_tree(struct vfsmount *); | 2283 | extern int may_umount_tree(struct vfsmount *); |
| 2276 | extern int may_umount(struct vfsmount *); | 2284 | extern int may_umount(struct vfsmount *); |
diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h new file mode 100644 index 000000000000..eaca452088fa --- /dev/null +++ b/include/linux/fs_context.h | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | /* Filesystem superblock creation and reconfiguration context. | ||
| 2 | * | ||
| 3 | * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public Licence | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the Licence, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _LINUX_FS_CONTEXT_H | ||
| 13 | #define _LINUX_FS_CONTEXT_H | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/security.h> | ||
| 18 | |||
| 19 | struct cred; | ||
| 20 | struct dentry; | ||
| 21 | struct file_operations; | ||
| 22 | struct file_system_type; | ||
| 23 | struct mnt_namespace; | ||
| 24 | struct net; | ||
| 25 | struct pid_namespace; | ||
| 26 | struct super_block; | ||
| 27 | struct user_namespace; | ||
| 28 | struct vfsmount; | ||
| 29 | struct path; | ||
| 30 | |||
| 31 | enum fs_context_purpose { | ||
| 32 | FS_CONTEXT_FOR_MOUNT, /* New superblock for explicit mount */ | ||
| 33 | FS_CONTEXT_FOR_SUBMOUNT, /* New superblock for automatic submount */ | ||
| 34 | FS_CONTEXT_FOR_RECONFIGURE, /* Superblock reconfiguration (remount) */ | ||
| 35 | }; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Type of parameter value. | ||
| 39 | */ | ||
| 40 | enum fs_value_type { | ||
| 41 | fs_value_is_undefined, | ||
| 42 | fs_value_is_flag, /* Value not given a value */ | ||
| 43 | fs_value_is_string, /* Value is a string */ | ||
| 44 | fs_value_is_blob, /* Value is a binary blob */ | ||
| 45 | fs_value_is_filename, /* Value is a filename* + dirfd */ | ||
| 46 | fs_value_is_filename_empty, /* Value is a filename* + dirfd + AT_EMPTY_PATH */ | ||
| 47 | fs_value_is_file, /* Value is a file* */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Configuration parameter. | ||
| 52 | */ | ||
| 53 | struct fs_parameter { | ||
| 54 | const char *key; /* Parameter name */ | ||
| 55 | enum fs_value_type type:8; /* The type of value here */ | ||
| 56 | union { | ||
| 57 | char *string; | ||
| 58 | void *blob; | ||
| 59 | struct filename *name; | ||
| 60 | struct file *file; | ||
| 61 | }; | ||
| 62 | size_t size; | ||
| 63 | int dirfd; | ||
| 64 | }; | ||
| 65 | |||
| 66 | /* | ||
| 67 | * Filesystem context for holding the parameters used in the creation or | ||
| 68 | * reconfiguration of a superblock. | ||
| 69 | * | ||
| 70 | * Superblock creation fills in ->root whereas reconfiguration begins with this | ||
| 71 | * already set. | ||
| 72 | * | ||
| 73 | * See Documentation/filesystems/mounting.txt | ||
| 74 | */ | ||
| 75 | struct fs_context { | ||
| 76 | const struct fs_context_operations *ops; | ||
| 77 | struct file_system_type *fs_type; | ||
| 78 | void *fs_private; /* The filesystem's context */ | ||
| 79 | struct dentry *root; /* The root and superblock */ | ||
| 80 | struct user_namespace *user_ns; /* The user namespace for this mount */ | ||
| 81 | struct net *net_ns; /* The network namespace for this mount */ | ||
| 82 | const struct cred *cred; /* The mounter's credentials */ | ||
| 83 | const char *source; /* The source name (eg. dev path) */ | ||
| 84 | const char *subtype; /* The subtype to set on the superblock */ | ||
| 85 | void *security; /* Linux S&M options */ | ||
| 86 | void *s_fs_info; /* Proposed s_fs_info */ | ||
| 87 | unsigned int sb_flags; /* Proposed superblock flags (SB_*) */ | ||
| 88 | unsigned int sb_flags_mask; /* Superblock flags that were changed */ | ||
| 89 | unsigned int lsm_flags; /* Information flags from the fs to the LSM */ | ||
| 90 | enum fs_context_purpose purpose:8; | ||
| 91 | bool need_free:1; /* Need to call ops->free() */ | ||
| 92 | bool global:1; /* Goes into &init_user_ns */ | ||
| 93 | }; | ||
| 94 | |||
| 95 | struct fs_context_operations { | ||
| 96 | void (*free)(struct fs_context *fc); | ||
| 97 | int (*dup)(struct fs_context *fc, struct fs_context *src_fc); | ||
| 98 | int (*parse_param)(struct fs_context *fc, struct fs_parameter *param); | ||
| 99 | int (*parse_monolithic)(struct fs_context *fc, void *data); | ||
| 100 | int (*get_tree)(struct fs_context *fc); | ||
| 101 | int (*reconfigure)(struct fs_context *fc); | ||
| 102 | }; | ||
| 103 | |||
| 104 | /* | ||
| 105 | * fs_context manipulation functions. | ||
| 106 | */ | ||
| 107 | extern struct fs_context *fs_context_for_mount(struct file_system_type *fs_type, | ||
| 108 | unsigned int sb_flags); | ||
| 109 | extern struct fs_context *fs_context_for_reconfigure(struct dentry *dentry, | ||
| 110 | unsigned int sb_flags, | ||
| 111 | unsigned int sb_flags_mask); | ||
| 112 | extern struct fs_context *fs_context_for_submount(struct file_system_type *fs_type, | ||
| 113 | struct dentry *reference); | ||
| 114 | |||
| 115 | extern struct fs_context *vfs_dup_fs_context(struct fs_context *fc); | ||
| 116 | extern int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param); | ||
| 117 | extern int vfs_parse_fs_string(struct fs_context *fc, const char *key, | ||
| 118 | const char *value, size_t v_size); | ||
| 119 | extern int generic_parse_monolithic(struct fs_context *fc, void *data); | ||
| 120 | extern int vfs_get_tree(struct fs_context *fc); | ||
| 121 | extern void put_fs_context(struct fs_context *fc); | ||
| 122 | |||
| 123 | /* | ||
| 124 | * sget() wrapper to be called from the ->get_tree() op. | ||
| 125 | */ | ||
| 126 | enum vfs_get_super_keying { | ||
| 127 | vfs_get_single_super, /* Only one such superblock may exist */ | ||
| 128 | vfs_get_keyed_super, /* Superblocks with different s_fs_info keys may exist */ | ||
| 129 | vfs_get_independent_super, /* Multiple independent superblocks may exist */ | ||
| 130 | }; | ||
| 131 | extern int vfs_get_super(struct fs_context *fc, | ||
| 132 | enum vfs_get_super_keying keying, | ||
| 133 | int (*fill_super)(struct super_block *sb, | ||
| 134 | struct fs_context *fc)); | ||
| 135 | |||
| 136 | extern const struct file_operations fscontext_fops; | ||
| 137 | |||
| 138 | #ifdef CONFIG_PRINTK | ||
| 139 | extern __attribute__((format(printf, 2, 3))) | ||
| 140 | void logfc(struct fs_context *fc, const char *fmt, ...); | ||
| 141 | #else | ||
| 142 | static inline __attribute__((format(printf, 2, 3))) | ||
| 143 | void logfc(struct fs_context *fc, const char *fmt, ...) | ||
| 144 | { | ||
| 145 | } | ||
| 146 | #endif | ||
| 147 | |||
| 148 | /** | ||
| 149 | * infof - Store supplementary informational message | ||
| 150 | * @fc: The context in which to log the informational message | ||
| 151 | * @fmt: The format string | ||
| 152 | * | ||
| 153 | * Store the supplementary informational message for the process if the process | ||
| 154 | * has enabled the facility. | ||
| 155 | */ | ||
| 156 | #define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); }) | ||
| 157 | |||
| 158 | /** | ||
| 159 | * warnf - Store supplementary warning message | ||
| 160 | * @fc: The context in which to log the error message | ||
| 161 | * @fmt: The format string | ||
| 162 | * | ||
| 163 | * Store the supplementary warning message for the process if the process has | ||
| 164 | * enabled the facility. | ||
| 165 | */ | ||
| 166 | #define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); }) | ||
| 167 | |||
| 168 | /** | ||
| 169 | * errorf - Store supplementary error message | ||
| 170 | * @fc: The context in which to log the error message | ||
| 171 | * @fmt: The format string | ||
| 172 | * | ||
| 173 | * Store the supplementary error message for the process if the process has | ||
| 174 | * enabled the facility. | ||
| 175 | */ | ||
| 176 | #define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); }) | ||
| 177 | |||
| 178 | /** | ||
| 179 | * invalf - Store supplementary invalid argument error message | ||
| 180 | * @fc: The context in which to log the error message | ||
| 181 | * @fmt: The format string | ||
| 182 | * | ||
| 183 | * Store the supplementary error message for the process if the process has | ||
| 184 | * enabled the facility and return -EINVAL. | ||
| 185 | */ | ||
| 186 | #define invalf(fc, fmt, ...) ({ errorf(fc, fmt, ## __VA_ARGS__); -EINVAL; }) | ||
| 187 | |||
| 188 | #endif /* _LINUX_FS_CONTEXT_H */ | ||
diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h new file mode 100644 index 000000000000..d966f96ffe62 --- /dev/null +++ b/include/linux/fs_parser.h | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | /* Filesystem parameter description and parser | ||
| 2 | * | ||
| 3 | * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public Licence | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the Licence, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _LINUX_FS_PARSER_H | ||
| 13 | #define _LINUX_FS_PARSER_H | ||
| 14 | |||
| 15 | #include <linux/fs_context.h> | ||
| 16 | |||
| 17 | struct path; | ||
| 18 | |||
| 19 | struct constant_table { | ||
| 20 | const char *name; | ||
| 21 | int value; | ||
| 22 | }; | ||
| 23 | |||
| 24 | /* | ||
| 25 | * The type of parameter expected. | ||
| 26 | */ | ||
| 27 | enum fs_parameter_type { | ||
| 28 | __fs_param_wasnt_defined, | ||
| 29 | fs_param_is_flag, | ||
| 30 | fs_param_is_bool, | ||
| 31 | fs_param_is_u32, | ||
| 32 | fs_param_is_u32_octal, | ||
| 33 | fs_param_is_u32_hex, | ||
| 34 | fs_param_is_s32, | ||
| 35 | fs_param_is_u64, | ||
| 36 | fs_param_is_enum, | ||
| 37 | fs_param_is_string, | ||
| 38 | fs_param_is_blob, | ||
| 39 | fs_param_is_blockdev, | ||
| 40 | fs_param_is_path, | ||
| 41 | fs_param_is_fd, | ||
| 42 | nr__fs_parameter_type, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Specification of the type of value a parameter wants. | ||
| 47 | * | ||
| 48 | * Note that the fsparam_flag(), fsparam_string(), fsparam_u32(), ... macros | ||
| 49 | * should be used to generate elements of this type. | ||
| 50 | */ | ||
| 51 | struct fs_parameter_spec { | ||
| 52 | const char *name; | ||
| 53 | u8 opt; /* Option number (returned by fs_parse()) */ | ||
| 54 | enum fs_parameter_type type:8; /* The desired parameter type */ | ||
| 55 | unsigned short flags; | ||
| 56 | #define fs_param_v_optional 0x0001 /* The value is optional */ | ||
| 57 | #define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */ | ||
| 58 | #define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */ | ||
| 59 | #define fs_param_deprecated 0x0008 /* The param is deprecated */ | ||
| 60 | }; | ||
| 61 | |||
| 62 | struct fs_parameter_enum { | ||
| 63 | u8 opt; /* Option number (as fs_parameter_spec::opt) */ | ||
| 64 | char name[14]; | ||
| 65 | u8 value; | ||
| 66 | }; | ||
| 67 | |||
| 68 | struct fs_parameter_description { | ||
| 69 | const char name[16]; /* Name for logging purposes */ | ||
| 70 | const struct fs_parameter_spec *specs; /* List of param specifications */ | ||
| 71 | const struct fs_parameter_enum *enums; /* Enum values */ | ||
| 72 | }; | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Result of parse. | ||
| 76 | */ | ||
| 77 | struct fs_parse_result { | ||
| 78 | bool negated; /* T if param was "noxxx" */ | ||
| 79 | bool has_value; /* T if value supplied to param */ | ||
| 80 | union { | ||
| 81 | bool boolean; /* For spec_bool */ | ||
| 82 | int int_32; /* For spec_s32/spec_enum */ | ||
| 83 | unsigned int uint_32; /* For spec_u32{,_octal,_hex}/spec_enum */ | ||
| 84 | u64 uint_64; /* For spec_u64 */ | ||
| 85 | }; | ||
| 86 | }; | ||
| 87 | |||
| 88 | extern int fs_parse(struct fs_context *fc, | ||
| 89 | const struct fs_parameter_description *desc, | ||
| 90 | struct fs_parameter *value, | ||
| 91 | struct fs_parse_result *result); | ||
| 92 | extern int fs_lookup_param(struct fs_context *fc, | ||
| 93 | struct fs_parameter *param, | ||
| 94 | bool want_bdev, | ||
| 95 | struct path *_path); | ||
| 96 | |||
| 97 | extern int __lookup_constant(const struct constant_table tbl[], size_t tbl_size, | ||
| 98 | const char *name, int not_found); | ||
| 99 | #define lookup_constant(t, n, nf) __lookup_constant(t, ARRAY_SIZE(t), (n), (nf)) | ||
| 100 | |||
| 101 | #ifdef CONFIG_VALIDATE_FS_PARSER | ||
| 102 | extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, | ||
| 103 | int low, int high, int special); | ||
| 104 | extern bool fs_validate_description(const struct fs_parameter_description *desc); | ||
| 105 | #else | ||
| 106 | static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, | ||
| 107 | int low, int high, int special) | ||
| 108 | { return true; } | ||
| 109 | static inline bool fs_validate_description(const struct fs_parameter_description *desc) | ||
| 110 | { return true; } | ||
| 111 | #endif | ||
| 112 | |||
| 113 | /* | ||
| 114 | * Parameter type, name, index and flags element constructors. Use as: | ||
| 115 | * | ||
| 116 | * fsparam_xxxx("foo", Opt_foo) | ||
| 117 | * | ||
| 118 | * If existing helpers are not enough, direct use of __fsparam() would | ||
| 119 | * work, but any such case is probably a sign that new helper is needed. | ||
| 120 | * Helpers will remain stable; low-level implementation may change. | ||
| 121 | */ | ||
| 122 | #define __fsparam(TYPE, NAME, OPT, FLAGS) \ | ||
| 123 | { \ | ||
| 124 | .name = NAME, \ | ||
| 125 | .opt = OPT, \ | ||
| 126 | .type = TYPE, \ | ||
| 127 | .flags = FLAGS \ | ||
| 128 | } | ||
| 129 | |||
| 130 | #define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0) | ||
| 131 | #define fsparam_flag_no(NAME, OPT) \ | ||
| 132 | __fsparam(fs_param_is_flag, NAME, OPT, \ | ||
| 133 | fs_param_neg_with_no) | ||
| 134 | #define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0) | ||
| 135 | #define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0) | ||
| 136 | #define fsparam_u32oct(NAME, OPT) \ | ||
| 137 | __fsparam(fs_param_is_u32_octal, NAME, OPT, 0) | ||
| 138 | #define fsparam_u32hex(NAME, OPT) \ | ||
| 139 | __fsparam(fs_param_is_u32_hex, NAME, OPT, 0) | ||
| 140 | #define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0) | ||
| 141 | #define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0) | ||
| 142 | #define fsparam_enum(NAME, OPT) __fsparam(fs_param_is_enum, NAME, OPT, 0) | ||
| 143 | #define fsparam_string(NAME, OPT) \ | ||
| 144 | __fsparam(fs_param_is_string, NAME, OPT, 0) | ||
| 145 | #define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0) | ||
| 146 | #define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0) | ||
| 147 | #define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0) | ||
| 148 | #define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0) | ||
| 149 | |||
| 150 | |||
| 151 | #endif /* _LINUX_FS_PARSER_H */ | ||
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 0cac1207bb00..c8893f663470 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h | |||
| @@ -26,7 +26,9 @@ struct vm_area_struct; | |||
| 26 | struct super_block; | 26 | struct super_block; |
| 27 | struct file_system_type; | 27 | struct file_system_type; |
| 28 | struct poll_table_struct; | 28 | struct poll_table_struct; |
| 29 | struct fs_context; | ||
| 29 | 30 | ||
| 31 | struct kernfs_fs_context; | ||
| 30 | struct kernfs_open_node; | 32 | struct kernfs_open_node; |
| 31 | struct kernfs_iattrs; | 33 | struct kernfs_iattrs; |
| 32 | 34 | ||
| @@ -168,7 +170,6 @@ struct kernfs_node { | |||
| 168 | * kernfs_node parameter. | 170 | * kernfs_node parameter. |
| 169 | */ | 171 | */ |
| 170 | struct kernfs_syscall_ops { | 172 | struct kernfs_syscall_ops { |
| 171 | int (*remount_fs)(struct kernfs_root *root, int *flags, char *data); | ||
| 172 | int (*show_options)(struct seq_file *sf, struct kernfs_root *root); | 173 | int (*show_options)(struct seq_file *sf, struct kernfs_root *root); |
| 173 | 174 | ||
| 174 | int (*mkdir)(struct kernfs_node *parent, const char *name, | 175 | int (*mkdir)(struct kernfs_node *parent, const char *name, |
| @@ -272,6 +273,18 @@ struct kernfs_ops { | |||
| 272 | #endif | 273 | #endif |
| 273 | }; | 274 | }; |
| 274 | 275 | ||
| 276 | /* | ||
| 277 | * The kernfs superblock creation/mount parameter context. | ||
| 278 | */ | ||
| 279 | struct kernfs_fs_context { | ||
| 280 | struct kernfs_root *root; /* Root of the hierarchy being mounted */ | ||
| 281 | void *ns_tag; /* Namespace tag of the mount (or NULL) */ | ||
| 282 | unsigned long magic; /* File system specific magic number */ | ||
| 283 | |||
| 284 | /* The following are set/used by kernfs_mount() */ | ||
| 285 | bool new_sb_created; /* Set to T if we allocated a new sb */ | ||
| 286 | }; | ||
| 287 | |||
| 275 | #ifdef CONFIG_KERNFS | 288 | #ifdef CONFIG_KERNFS |
| 276 | 289 | ||
| 277 | static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) | 290 | static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) |
| @@ -359,11 +372,9 @@ __poll_t kernfs_generic_poll(struct kernfs_open_file *of, | |||
| 359 | void kernfs_notify(struct kernfs_node *kn); | 372 | void kernfs_notify(struct kernfs_node *kn); |
| 360 | 373 | ||
| 361 | const void *kernfs_super_ns(struct super_block *sb); | 374 | const void *kernfs_super_ns(struct super_block *sb); |
| 362 | struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, | 375 | int kernfs_get_tree(struct fs_context *fc); |
| 363 | struct kernfs_root *root, unsigned long magic, | 376 | void kernfs_free_fs_context(struct fs_context *fc); |
| 364 | bool *new_sb_created, const void *ns); | ||
| 365 | void kernfs_kill_sb(struct super_block *sb); | 377 | void kernfs_kill_sb(struct super_block *sb); |
| 366 | struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns); | ||
| 367 | 378 | ||
| 368 | void kernfs_init(void); | 379 | void kernfs_init(void); |
| 369 | 380 | ||
| @@ -465,11 +476,10 @@ static inline void kernfs_notify(struct kernfs_node *kn) { } | |||
| 465 | static inline const void *kernfs_super_ns(struct super_block *sb) | 476 | static inline const void *kernfs_super_ns(struct super_block *sb) |
| 466 | { return NULL; } | 477 | { return NULL; } |
| 467 | 478 | ||
| 468 | static inline struct dentry * | 479 | static inline int kernfs_get_tree(struct fs_context *fc) |
| 469 | kernfs_mount_ns(struct file_system_type *fs_type, int flags, | 480 | { return -ENOSYS; } |
| 470 | struct kernfs_root *root, unsigned long magic, | 481 | |
| 471 | bool *new_sb_created, const void *ns) | 482 | static inline void kernfs_free_fs_context(struct fs_context *fc) { } |
| 472 | { return ERR_PTR(-ENOSYS); } | ||
| 473 | 483 | ||
| 474 | static inline void kernfs_kill_sb(struct super_block *sb) { } | 484 | static inline void kernfs_kill_sb(struct super_block *sb) { } |
| 475 | 485 | ||
| @@ -552,13 +562,4 @@ static inline int kernfs_rename(struct kernfs_node *kn, | |||
| 552 | return kernfs_rename_ns(kn, new_parent, new_name, NULL); | 562 | return kernfs_rename_ns(kn, new_parent, new_name, NULL); |
| 553 | } | 563 | } |
| 554 | 564 | ||
| 555 | static inline struct dentry * | ||
| 556 | kernfs_mount(struct file_system_type *fs_type, int flags, | ||
| 557 | struct kernfs_root *root, unsigned long magic, | ||
| 558 | bool *new_sb_created) | ||
| 559 | { | ||
| 560 | return kernfs_mount_ns(fs_type, flags, root, | ||
| 561 | magic, new_sb_created, NULL); | ||
| 562 | } | ||
| 563 | |||
| 564 | #endif /* __LINUX_KERNFS_H */ | 565 | #endif /* __LINUX_KERNFS_H */ |
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 85a301632cf1..a9b8ff578b6b 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
| @@ -76,6 +76,22 @@ | |||
| 76 | * changes on the process such as clearing out non-inheritable signal | 76 | * changes on the process such as clearing out non-inheritable signal |
| 77 | * state. This is called immediately after commit_creds(). | 77 | * state. This is called immediately after commit_creds(). |
| 78 | * | 78 | * |
| 79 | * Security hooks for mount using fs_context. | ||
| 80 | * [See also Documentation/filesystems/mounting.txt] | ||
| 81 | * | ||
| 82 | * @fs_context_dup: | ||
| 83 | * Allocate and attach a security structure to sc->security. This pointer | ||
| 84 | * is initialised to NULL by the caller. | ||
| 85 | * @fc indicates the new filesystem context. | ||
| 86 | * @src_fc indicates the original filesystem context. | ||
| 87 | * @fs_context_parse_param: | ||
| 88 | * Userspace provided a parameter to configure a superblock. The LSM may | ||
| 89 | * reject it with an error and may use it for itself, in which case it | ||
| 90 | * should return 0; otherwise it should return -ENOPARAM to pass it on to | ||
| 91 | * the filesystem. | ||
| 92 | * @fc indicates the filesystem context. | ||
| 93 | * @param The parameter | ||
| 94 | * | ||
| 79 | * Security hooks for filesystem operations. | 95 | * Security hooks for filesystem operations. |
| 80 | * | 96 | * |
| 81 | * @sb_alloc_security: | 97 | * @sb_alloc_security: |
| @@ -1460,6 +1476,9 @@ union security_list_options { | |||
| 1460 | void (*bprm_committing_creds)(struct linux_binprm *bprm); | 1476 | void (*bprm_committing_creds)(struct linux_binprm *bprm); |
| 1461 | void (*bprm_committed_creds)(struct linux_binprm *bprm); | 1477 | void (*bprm_committed_creds)(struct linux_binprm *bprm); |
| 1462 | 1478 | ||
| 1479 | int (*fs_context_dup)(struct fs_context *fc, struct fs_context *src_sc); | ||
| 1480 | int (*fs_context_parse_param)(struct fs_context *fc, struct fs_parameter *param); | ||
| 1481 | |||
| 1463 | int (*sb_alloc_security)(struct super_block *sb); | 1482 | int (*sb_alloc_security)(struct super_block *sb); |
| 1464 | void (*sb_free_security)(struct super_block *sb); | 1483 | void (*sb_free_security)(struct super_block *sb); |
| 1465 | void (*sb_free_mnt_opts)(void *mnt_opts); | 1484 | void (*sb_free_mnt_opts)(void *mnt_opts); |
| @@ -1800,6 +1819,8 @@ struct security_hook_heads { | |||
| 1800 | struct hlist_head bprm_check_security; | 1819 | struct hlist_head bprm_check_security; |
| 1801 | struct hlist_head bprm_committing_creds; | 1820 | struct hlist_head bprm_committing_creds; |
| 1802 | struct hlist_head bprm_committed_creds; | 1821 | struct hlist_head bprm_committed_creds; |
| 1822 | struct hlist_head fs_context_dup; | ||
| 1823 | struct hlist_head fs_context_parse_param; | ||
| 1803 | struct hlist_head sb_alloc_security; | 1824 | struct hlist_head sb_alloc_security; |
| 1804 | struct hlist_head sb_free_security; | 1825 | struct hlist_head sb_free_security; |
| 1805 | struct hlist_head sb_free_mnt_opts; | 1826 | struct hlist_head sb_free_mnt_opts; |
diff --git a/include/linux/mount.h b/include/linux/mount.h index 037eed52164b..9197ddbf35fb 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h | |||
| @@ -21,6 +21,7 @@ struct super_block; | |||
| 21 | struct vfsmount; | 21 | struct vfsmount; |
| 22 | struct dentry; | 22 | struct dentry; |
| 23 | struct mnt_namespace; | 23 | struct mnt_namespace; |
| 24 | struct fs_context; | ||
| 24 | 25 | ||
| 25 | #define MNT_NOSUID 0x01 | 26 | #define MNT_NOSUID 0x01 |
| 26 | #define MNT_NODEV 0x02 | 27 | #define MNT_NODEV 0x02 |
| @@ -88,6 +89,8 @@ struct path; | |||
| 88 | extern struct vfsmount *clone_private_mount(const struct path *path); | 89 | extern struct vfsmount *clone_private_mount(const struct path *path); |
| 89 | 90 | ||
| 90 | struct file_system_type; | 91 | struct file_system_type; |
| 92 | extern struct vfsmount *fc_mount(struct fs_context *fc); | ||
| 93 | extern struct vfsmount *vfs_create_mount(struct fs_context *fc); | ||
| 91 | extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, | 94 | extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, |
| 92 | int flags, const char *name, | 95 | int flags, const char *name, |
| 93 | void *data); | 96 | void *data); |
diff --git a/include/linux/security.h b/include/linux/security.h index 2b35a43d11d6..49f2685324b0 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -53,6 +53,9 @@ struct msg_msg; | |||
| 53 | struct xattr; | 53 | struct xattr; |
| 54 | struct xfrm_sec_ctx; | 54 | struct xfrm_sec_ctx; |
| 55 | struct mm_struct; | 55 | struct mm_struct; |
| 56 | struct fs_context; | ||
| 57 | struct fs_parameter; | ||
| 58 | enum fs_value_type; | ||
| 56 | 59 | ||
| 57 | /* Default (no) options for the capable function */ | 60 | /* Default (no) options for the capable function */ |
| 58 | #define CAP_OPT_NONE 0x0 | 61 | #define CAP_OPT_NONE 0x0 |
| @@ -61,7 +64,7 @@ struct mm_struct; | |||
| 61 | /* If capable is being called by a setid function */ | 64 | /* If capable is being called by a setid function */ |
| 62 | #define CAP_OPT_INSETID BIT(2) | 65 | #define CAP_OPT_INSETID BIT(2) |
| 63 | 66 | ||
| 64 | /* LSM Agnostic defines for sb_set_mnt_opts */ | 67 | /* LSM Agnostic defines for fs_context::lsm_flags */ |
| 65 | #define SECURITY_LSM_NATIVE_LABELS 1 | 68 | #define SECURITY_LSM_NATIVE_LABELS 1 |
| 66 | 69 | ||
| 67 | struct ctl_table; | 70 | struct ctl_table; |
| @@ -223,6 +226,8 @@ int security_bprm_set_creds(struct linux_binprm *bprm); | |||
| 223 | int security_bprm_check(struct linux_binprm *bprm); | 226 | int security_bprm_check(struct linux_binprm *bprm); |
| 224 | void security_bprm_committing_creds(struct linux_binprm *bprm); | 227 | void security_bprm_committing_creds(struct linux_binprm *bprm); |
| 225 | void security_bprm_committed_creds(struct linux_binprm *bprm); | 228 | void security_bprm_committed_creds(struct linux_binprm *bprm); |
| 229 | int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc); | ||
| 230 | int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param); | ||
| 226 | int security_sb_alloc(struct super_block *sb); | 231 | int security_sb_alloc(struct super_block *sb); |
| 227 | void security_sb_free(struct super_block *sb); | 232 | void security_sb_free(struct super_block *sb); |
| 228 | void security_free_mnt_opts(void **mnt_opts); | 233 | void security_free_mnt_opts(void **mnt_opts); |
| @@ -519,6 +524,17 @@ static inline void security_bprm_committed_creds(struct linux_binprm *bprm) | |||
| 519 | { | 524 | { |
| 520 | } | 525 | } |
| 521 | 526 | ||
| 527 | static inline int security_fs_context_dup(struct fs_context *fc, | ||
| 528 | struct fs_context *src_fc) | ||
| 529 | { | ||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | static inline int security_fs_context_parse_param(struct fs_context *fc, | ||
| 533 | struct fs_parameter *param) | ||
| 534 | { | ||
| 535 | return -ENOPARAM; | ||
| 536 | } | ||
| 537 | |||
| 522 | static inline int security_sb_alloc(struct super_block *sb) | 538 | static inline int security_sb_alloc(struct super_block *sb) |
| 523 | { | 539 | { |
| 524 | return 0; | 540 | return 0; |
