Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'mount.part1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs mount API prep from Al Viro:
"Mount API prereqs.

Mostly that's LSM mount options cleanups. There are several minor
fixes in there, but nothing earth-shattering (leaks on failure exits,
mostly)"

* 'mount.part1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (27 commits)
mount_fs: suppress MAC on MS_SUBMOUNT as well as MS_KERNMOUNT
smack: rewrite smack_sb_eat_lsm_opts()
smack: get rid of match_token()
smack: take the guts of smack_parse_opts_str() into a new helper
LSM: new method: ->sb_add_mnt_opt()
selinux: rewrite selinux_sb_eat_lsm_opts()
selinux: regularize Opt_... names a bit
selinux: switch away from match_token()
selinux: new helper - selinux_add_opt()
LSM: bury struct security_mnt_opts
smack: switch to private smack_mnt_opts
selinux: switch to private struct selinux_mnt_opts
LSM: hide struct security_mnt_opts from any generic code
selinux: kill selinux_sb_get_mnt_opts()
LSM: turn sb_eat_lsm_opts() into a method
nfs_remount(): don't leak, don't ignore LSM options quietly
btrfs: sanitize security_mnt_opts use
selinux; don't open-code a loop in sb_finish_set_opts()
LSM: split ->sb_set_mnt_opts() out of ->sb_kern_mount()
new helper: security_sb_eat_lsm_opts()
...

+741 -1057
+1
arch/arc/kernel/setup.c
··· 19 19 #include <linux/of_fdt.h> 20 20 #include <linux/of.h> 21 21 #include <linux/cache.h> 22 + #include <uapi/linux/mount.h> 22 23 #include <asm/sections.h> 23 24 #include <asm/arcregs.h> 24 25 #include <asm/tlb.h>
+1
arch/arm/kernel/atags_parse.c
··· 24 24 #include <linux/root_dev.h> 25 25 #include <linux/screen_info.h> 26 26 #include <linux/memblock.h> 27 + #include <uapi/linux/mount.h> 27 28 28 29 #include <asm/setup.h> 29 30 #include <asm/system_info.h>
+1
arch/sh/kernel/setup.c
··· 32 32 #include <linux/of.h> 33 33 #include <linux/of_fdt.h> 34 34 #include <linux/uaccess.h> 35 + #include <uapi/linux/mount.h> 35 36 #include <asm/io.h> 36 37 #include <asm/page.h> 37 38 #include <asm/elf.h>
+1
arch/sparc/kernel/setup_32.c
··· 34 34 #include <linux/kdebug.h> 35 35 #include <linux/export.h> 36 36 #include <linux/start_kernel.h> 37 + #include <uapi/linux/mount.h> 37 38 38 39 #include <asm/io.h> 39 40 #include <asm/processor.h>
+1
arch/sparc/kernel/setup_64.c
··· 33 33 #include <linux/module.h> 34 34 #include <linux/start_kernel.h> 35 35 #include <linux/memblock.h> 36 + #include <uapi/linux/mount.h> 36 37 37 38 #include <asm/io.h> 38 39 #include <asm/processor.h>
+1
arch/x86/kernel/setup.c
··· 50 50 #include <linux/kvm_para.h> 51 51 #include <linux/dma-contiguous.h> 52 52 #include <xen/xen.h> 53 + #include <uapi/linux/mount.h> 53 54 54 55 #include <linux/errno.h> 55 56 #include <linux/kernel.h>
+1
drivers/base/devtmpfs.c
··· 25 25 #include <linux/sched.h> 26 26 #include <linux/slab.h> 27 27 #include <linux/kthread.h> 28 + #include <uapi/linux/mount.h> 28 29 #include "base.h" 29 30 30 31 static struct task_struct *thread;
-4
fs/btrfs/ctree.h
··· 1144 1144 struct mutex unused_bg_unpin_mutex; 1145 1145 struct mutex delete_unused_bgs_mutex; 1146 1146 1147 - /* For btrfs to record security options */ 1148 - struct security_mnt_opts security_opts; 1149 - 1150 1147 /* 1151 1148 * Chunks that can't be freed yet (under a trim/discard operation) 1152 1149 * and will be latter freed. Protected by fs_info->chunk_mutex. ··· 3018 3021 kfree(fs_info->free_space_root); 3019 3022 kfree(fs_info->super_copy); 3020 3023 kfree(fs_info->super_for_commit); 3021 - security_free_mnt_opts(&fs_info->security_opts); 3022 3024 kvfree(fs_info); 3023 3025 } 3024 3026
+11 -71
fs/btrfs/super.c
··· 1458 1458 return root; 1459 1459 } 1460 1460 1461 - static int parse_security_options(char *orig_opts, 1462 - struct security_mnt_opts *sec_opts) 1463 - { 1464 - char *secdata = NULL; 1465 - int ret = 0; 1466 - 1467 - secdata = alloc_secdata(); 1468 - if (!secdata) 1469 - return -ENOMEM; 1470 - ret = security_sb_copy_data(orig_opts, secdata); 1471 - if (ret) { 1472 - free_secdata(secdata); 1473 - return ret; 1474 - } 1475 - ret = security_sb_parse_opts_str(secdata, sec_opts); 1476 - free_secdata(secdata); 1477 - return ret; 1478 - } 1479 - 1480 - static int setup_security_options(struct btrfs_fs_info *fs_info, 1481 - struct super_block *sb, 1482 - struct security_mnt_opts *sec_opts) 1483 - { 1484 - int ret = 0; 1485 - 1486 - /* 1487 - * Call security_sb_set_mnt_opts() to check whether new sec_opts 1488 - * is valid. 1489 - */ 1490 - ret = security_sb_set_mnt_opts(sb, sec_opts, 0, NULL); 1491 - if (ret) 1492 - return ret; 1493 - 1494 - #ifdef CONFIG_SECURITY 1495 - if (!fs_info->security_opts.num_mnt_opts) { 1496 - /* first time security setup, copy sec_opts to fs_info */ 1497 - memcpy(&fs_info->security_opts, sec_opts, sizeof(*sec_opts)); 1498 - } else { 1499 - /* 1500 - * Since SELinux (the only one supporting security_mnt_opts) 1501 - * does NOT support changing context during remount/mount of 1502 - * the same sb, this must be the same or part of the same 1503 - * security options, just free it. 1504 - */ 1505 - security_free_mnt_opts(sec_opts); 1506 - } 1507 - #endif 1508 - return ret; 1509 - } 1510 - 1511 1461 /* 1512 1462 * Find a superblock for the given device / mount point. 1513 1463 * ··· 1472 1522 struct btrfs_device *device = NULL; 1473 1523 struct btrfs_fs_devices *fs_devices = NULL; 1474 1524 struct btrfs_fs_info *fs_info = NULL; 1475 - struct security_mnt_opts new_sec_opts; 1525 + void *new_sec_opts = NULL; 1476 1526 fmode_t mode = FMODE_READ; 1477 1527 int error = 0; 1478 1528 1479 1529 if (!(flags & SB_RDONLY)) 1480 1530 mode |= FMODE_WRITE; 1481 1531 1482 - security_init_mnt_opts(&new_sec_opts); 1483 1532 if (data) { 1484 - error = parse_security_options(data, &new_sec_opts); 1533 + error = security_sb_eat_lsm_opts(data, &new_sec_opts); 1485 1534 if (error) 1486 1535 return ERR_PTR(error); 1487 1536 } ··· 1499 1550 1500 1551 fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 1501 1552 fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); 1502 - security_init_mnt_opts(&fs_info->security_opts); 1503 1553 if (!fs_info->super_copy || !fs_info->super_for_commit) { 1504 1554 error = -ENOMEM; 1505 1555 goto error_fs_info; ··· 1549 1601 btrfs_sb(s)->bdev_holder = fs_type; 1550 1602 error = btrfs_fill_super(s, fs_devices, data); 1551 1603 } 1604 + if (!error) 1605 + error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL); 1606 + security_free_mnt_opts(&new_sec_opts); 1552 1607 if (error) { 1553 1608 deactivate_locked_super(s); 1554 - goto error_sec_opts; 1555 - } 1556 - 1557 - fs_info = btrfs_sb(s); 1558 - error = setup_security_options(fs_info, s, &new_sec_opts); 1559 - if (error) { 1560 - deactivate_locked_super(s); 1561 - goto error_sec_opts; 1609 + return ERR_PTR(error); 1562 1610 } 1563 1611 1564 1612 return dget(s->s_root); ··· 1723 1779 btrfs_remount_prepare(fs_info); 1724 1780 1725 1781 if (data) { 1726 - struct security_mnt_opts new_sec_opts; 1782 + void *new_sec_opts = NULL; 1727 1783 1728 - security_init_mnt_opts(&new_sec_opts); 1729 - ret = parse_security_options(data, &new_sec_opts); 1784 + ret = security_sb_eat_lsm_opts(data, &new_sec_opts); 1785 + if (!ret) 1786 + ret = security_sb_remount(sb, new_sec_opts); 1787 + security_free_mnt_opts(&new_sec_opts); 1730 1788 if (ret) 1731 1789 goto restore; 1732 - ret = setup_security_options(fs_info, sb, 1733 - &new_sec_opts); 1734 - if (ret) { 1735 - security_free_mnt_opts(&new_sec_opts); 1736 - goto restore; 1737 - } 1738 1790 } 1739 1791 1740 1792 ret = btrfs_parse_options(fs_info, data, *flags);
+29 -8
fs/exofs/super.c
··· 705 705 /* 706 706 * Read the superblock from the OSD and fill in the fields 707 707 */ 708 - static int exofs_fill_super(struct super_block *sb, void *data, int silent) 708 + static int exofs_fill_super(struct super_block *sb, 709 + struct exofs_mountopt *opts, 710 + struct exofs_sb_info *sbi, 711 + int silent) 709 712 { 710 713 struct inode *root; 711 - struct exofs_mountopt *opts = data; 712 - struct exofs_sb_info *sbi; /*extended info */ 713 714 struct osd_dev *od; /* Master device */ 714 715 struct exofs_fscb fscb; /*on-disk superblock info */ 715 716 struct ore_comp comp; 716 717 unsigned table_count; 717 718 int ret; 718 - 719 - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 720 - if (!sbi) 721 - return -ENOMEM; 722 719 723 720 /* use mount options to fill superblock */ 724 721 if (opts->is_osdname) { ··· 860 863 int flags, const char *dev_name, 861 864 void *data) 862 865 { 866 + struct super_block *s; 863 867 struct exofs_mountopt opts; 868 + struct exofs_sb_info *sbi; 864 869 int ret; 865 870 866 871 ret = parse_options(data, &opts); ··· 871 872 return ERR_PTR(ret); 872 873 } 873 874 875 + sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 876 + if (!sbi) { 877 + kfree(opts.dev_name); 878 + return ERR_PTR(-ENOMEM); 879 + } 880 + 881 + s = sget(type, NULL, set_anon_super, flags, NULL); 882 + 883 + if (IS_ERR(s)) { 884 + kfree(opts.dev_name); 885 + kfree(sbi); 886 + return ERR_CAST(s); 887 + } 888 + 874 889 if (!opts.dev_name) 875 890 opts.dev_name = dev_name; 876 - return mount_nodev(type, flags, &opts, exofs_fill_super); 891 + 892 + 893 + ret = exofs_fill_super(s, &opts, sbi, flags & SB_SILENT ? 1 : 0); 894 + if (ret) { 895 + deactivate_locked_super(s); 896 + return ERR_PTR(ret); 897 + } 898 + s->s_flags |= SB_ACTIVE; 899 + return dget(s->s_root); 877 900 } 878 901 879 902 /*
+101 -55
fs/namespace.c
··· 26 26 #include <linux/memblock.h> 27 27 #include <linux/task_work.h> 28 28 #include <linux/sched/task.h> 29 + #include <uapi/linux/mount.h> 29 30 30 31 #include "pnode.h" 31 32 #include "internal.h" ··· 246 245 * mnt_want/drop_write() will _keep_ the filesystem 247 246 * r/w. 248 247 */ 249 - int __mnt_is_readonly(struct vfsmount *mnt) 248 + bool __mnt_is_readonly(struct vfsmount *mnt) 250 249 { 251 - if (mnt->mnt_flags & MNT_READONLY) 252 - return 1; 253 - if (sb_rdonly(mnt->mnt_sb)) 254 - return 1; 255 - return 0; 250 + return (mnt->mnt_flags & MNT_READONLY) || sb_rdonly(mnt->mnt_sb); 256 251 } 257 252 EXPORT_SYMBOL_GPL(__mnt_is_readonly); 258 253 ··· 504 507 return ret; 505 508 } 506 509 507 - static void __mnt_unmake_readonly(struct mount *mnt) 510 + static int __mnt_unmake_readonly(struct mount *mnt) 508 511 { 509 512 lock_mount_hash(); 510 513 mnt->mnt.mnt_flags &= ~MNT_READONLY; 511 514 unlock_mount_hash(); 515 + return 0; 512 516 } 513 517 514 518 int sb_prepare_remount_readonly(struct super_block *sb) ··· 2213 2215 return err; 2214 2216 } 2215 2217 2216 - static int change_mount_flags(struct vfsmount *mnt, int ms_flags) 2218 + /* 2219 + * Don't allow locked mount flags to be cleared. 2220 + * 2221 + * No locks need to be held here while testing the various MNT_LOCK 2222 + * flags because those flags can never be cleared once they are set. 2223 + */ 2224 + static bool can_change_locked_flags(struct mount *mnt, unsigned int mnt_flags) 2217 2225 { 2218 - int error = 0; 2219 - int readonly_request = 0; 2226 + unsigned int fl = mnt->mnt.mnt_flags; 2220 2227 2221 - if (ms_flags & MS_RDONLY) 2222 - readonly_request = 1; 2223 - if (readonly_request == __mnt_is_readonly(mnt)) 2228 + if ((fl & MNT_LOCK_READONLY) && 2229 + !(mnt_flags & MNT_READONLY)) 2230 + return false; 2231 + 2232 + if ((fl & MNT_LOCK_NODEV) && 2233 + !(mnt_flags & MNT_NODEV)) 2234 + return false; 2235 + 2236 + if ((fl & MNT_LOCK_NOSUID) && 2237 + !(mnt_flags & MNT_NOSUID)) 2238 + return false; 2239 + 2240 + if ((fl & MNT_LOCK_NOEXEC) && 2241 + !(mnt_flags & MNT_NOEXEC)) 2242 + return false; 2243 + 2244 + if ((fl & MNT_LOCK_ATIME) && 2245 + ((fl & MNT_ATIME_MASK) != (mnt_flags & MNT_ATIME_MASK))) 2246 + return false; 2247 + 2248 + return true; 2249 + } 2250 + 2251 + static int change_mount_ro_state(struct mount *mnt, unsigned int mnt_flags) 2252 + { 2253 + bool readonly_request = (mnt_flags & MNT_READONLY); 2254 + 2255 + if (readonly_request == __mnt_is_readonly(&mnt->mnt)) 2224 2256 return 0; 2225 2257 2226 2258 if (readonly_request) 2227 - error = mnt_make_readonly(real_mount(mnt)); 2228 - else 2229 - __mnt_unmake_readonly(real_mount(mnt)); 2230 - return error; 2259 + return mnt_make_readonly(mnt); 2260 + 2261 + return __mnt_unmake_readonly(mnt); 2262 + } 2263 + 2264 + /* 2265 + * Update the user-settable attributes on a mount. The caller must hold 2266 + * sb->s_umount for writing. 2267 + */ 2268 + static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags) 2269 + { 2270 + lock_mount_hash(); 2271 + mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; 2272 + mnt->mnt.mnt_flags = mnt_flags; 2273 + touch_mnt_namespace(mnt->mnt_ns); 2274 + unlock_mount_hash(); 2275 + } 2276 + 2277 + /* 2278 + * Handle reconfiguration of the mountpoint only without alteration of the 2279 + * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND 2280 + * to mount(2). 2281 + */ 2282 + static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags) 2283 + { 2284 + struct super_block *sb = path->mnt->mnt_sb; 2285 + struct mount *mnt = real_mount(path->mnt); 2286 + int ret; 2287 + 2288 + if (!check_mnt(mnt)) 2289 + return -EINVAL; 2290 + 2291 + if (path->dentry != mnt->mnt.mnt_root) 2292 + return -EINVAL; 2293 + 2294 + if (!can_change_locked_flags(mnt, mnt_flags)) 2295 + return -EPERM; 2296 + 2297 + down_write(&sb->s_umount); 2298 + ret = change_mount_ro_state(mnt, mnt_flags); 2299 + if (ret == 0) 2300 + set_mount_attributes(mnt, mnt_flags); 2301 + up_write(&sb->s_umount); 2302 + return ret; 2231 2303 } 2232 2304 2233 2305 /* ··· 2311 2243 int err; 2312 2244 struct super_block *sb = path->mnt->mnt_sb; 2313 2245 struct mount *mnt = real_mount(path->mnt); 2246 + void *sec_opts = NULL; 2314 2247 2315 2248 if (!check_mnt(mnt)) 2316 2249 return -EINVAL; ··· 2319 2250 if (path->dentry != path->mnt->mnt_root) 2320 2251 return -EINVAL; 2321 2252 2322 - /* Don't allow changing of locked mnt flags. 2323 - * 2324 - * No locks need to be held here while testing the various 2325 - * MNT_LOCK flags because those flags can never be cleared 2326 - * once they are set. 2327 - */ 2328 - if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) && 2329 - !(mnt_flags & MNT_READONLY)) { 2253 + if (!can_change_locked_flags(mnt, mnt_flags)) 2330 2254 return -EPERM; 2331 - } 2332 - if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) && 2333 - !(mnt_flags & MNT_NODEV)) { 2334 - return -EPERM; 2335 - } 2336 - if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) && 2337 - !(mnt_flags & MNT_NOSUID)) { 2338 - return -EPERM; 2339 - } 2340 - if ((mnt->mnt.mnt_flags & MNT_LOCK_NOEXEC) && 2341 - !(mnt_flags & MNT_NOEXEC)) { 2342 - return -EPERM; 2343 - } 2344 - if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) && 2345 - ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (mnt_flags & MNT_ATIME_MASK))) { 2346 - return -EPERM; 2347 - } 2348 2255 2349 - err = security_sb_remount(sb, data); 2256 + if (data && !(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)) { 2257 + err = security_sb_eat_lsm_opts(data, &sec_opts); 2258 + if (err) 2259 + return err; 2260 + } 2261 + err = security_sb_remount(sb, sec_opts); 2262 + security_free_mnt_opts(&sec_opts); 2350 2263 if (err) 2351 2264 return err; 2352 2265 2353 2266 down_write(&sb->s_umount); 2354 - if (ms_flags & MS_BIND) 2355 - err = change_mount_flags(path->mnt, ms_flags); 2356 - else if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) 2357 - err = -EPERM; 2358 - else 2267 + err = -EPERM; 2268 + if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) { 2359 2269 err = do_remount_sb(sb, sb_flags, data, 0); 2360 - if (!err) { 2361 - lock_mount_hash(); 2362 - mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; 2363 - mnt->mnt.mnt_flags = mnt_flags; 2364 - touch_mnt_namespace(mnt->mnt_ns); 2365 - unlock_mount_hash(); 2270 + if (!err) 2271 + set_mount_attributes(mnt, mnt_flags); 2366 2272 } 2367 2273 up_write(&sb->s_umount); 2368 2274 return err; ··· 2832 2788 SB_LAZYTIME | 2833 2789 SB_I_VERSION); 2834 2790 2835 - if (flags & MS_REMOUNT) 2791 + if ((flags & (MS_REMOUNT | MS_BIND)) == (MS_REMOUNT | MS_BIND)) 2792 + retval = do_reconfigure_mnt(&path, mnt_flags); 2793 + else if (flags & MS_REMOUNT) 2836 2794 retval = do_remount(&path, flags, sb_flags, mnt_flags, 2837 2795 data_page); 2838 2796 else if (flags & MS_BIND)
+1 -1
fs/nfs/internal.h
··· 123 123 unsigned short protocol; 124 124 } nfs_server; 125 125 126 - struct security_mnt_opts lsm_opts; 126 + void *lsm_opts; 127 127 struct net *net; 128 128 }; 129 129
+10 -24
fs/nfs/super.c
··· 929 929 data->minorversion = 0; 930 930 data->need_mount = true; 931 931 data->net = current->nsproxy->net_ns; 932 - security_init_mnt_opts(&data->lsm_opts); 932 + data->lsm_opts = NULL; 933 933 } 934 934 return data; 935 935 } ··· 1206 1206 static int nfs_parse_mount_options(char *raw, 1207 1207 struct nfs_parsed_mount_data *mnt) 1208 1208 { 1209 - char *p, *string, *secdata; 1209 + char *p, *string; 1210 1210 int rc, sloppy = 0, invalid_option = 0; 1211 1211 unsigned short protofamily = AF_UNSPEC; 1212 1212 unsigned short mountfamily = AF_UNSPEC; ··· 1217 1217 } 1218 1218 dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); 1219 1219 1220 - secdata = alloc_secdata(); 1221 - if (!secdata) 1222 - goto out_nomem; 1223 - 1224 - rc = security_sb_copy_data(raw, secdata); 1220 + rc = security_sb_eat_lsm_opts(raw, &mnt->lsm_opts); 1225 1221 if (rc) 1226 1222 goto out_security_failure; 1227 - 1228 - rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts); 1229 - if (rc) 1230 - goto out_security_failure; 1231 - 1232 - free_secdata(secdata); 1233 1223 1234 1224 while ((p = strsep(&raw, ",")) != NULL) { 1235 1225 substring_t args[MAX_OPT_ARGS]; ··· 1672 1682 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1673 1683 return 0; 1674 1684 out_security_failure: 1675 - free_secdata(secdata); 1676 1685 printk(KERN_INFO "NFS: security options invalid: %d\n", rc); 1677 1686 return 0; 1678 1687 } ··· 2070 2081 if (data->context[0]){ 2071 2082 #ifdef CONFIG_SECURITY_SELINUX 2072 2083 int rc; 2073 - char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL); 2074 - if (!opts_str) 2075 - return -ENOMEM; 2076 - strcpy(opts_str, "context="); 2077 2084 data->context[NFS_MAX_CONTEXT_LEN] = '\0'; 2078 - strcat(opts_str, &data->context[0]); 2079 - rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts); 2080 - kfree(opts_str); 2085 + rc = security_add_mnt_opt("context", data->context, 2086 + strlen(data->context), &args->lsm_opts); 2081 2087 if (rc) 2082 2088 return rc; 2083 2089 #else ··· 2255 2271 options->version <= 6)))) 2256 2272 return 0; 2257 2273 2258 - data = kzalloc(sizeof(*data), GFP_KERNEL); 2274 + data = nfs_alloc_parsed_mount_data(); 2259 2275 if (data == NULL) 2260 2276 return -ENOMEM; 2261 2277 ··· 2294 2310 2295 2311 /* compare new mount options with old ones */ 2296 2312 error = nfs_compare_remount_data(nfss, data); 2313 + if (!error) 2314 + error = security_sb_remount(sb, data->lsm_opts); 2297 2315 out: 2298 - kfree(data); 2316 + nfs_free_parsed_mount_data(data); 2299 2317 return error; 2300 2318 } 2301 2319 EXPORT_SYMBOL_GPL(nfs_remount); ··· 2534 2548 if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) 2535 2549 kflags |= SECURITY_LSM_NATIVE_LABELS; 2536 2550 2537 - error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts, 2551 + error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts, 2538 2552 kflags, &kflags_out); 2539 2553 if (error) 2540 2554 goto err;
+1
fs/pnode.c
··· 10 10 #include <linux/mount.h> 11 11 #include <linux/fs.h> 12 12 #include <linux/nsproxy.h> 13 + #include <uapi/linux/mount.h> 13 14 #include "internal.h" 14 15 #include "pnode.h" 15 16
+13 -11
fs/super.c
··· 35 35 #include <linux/fsnotify.h> 36 36 #include <linux/lockdep.h> 37 37 #include <linux/user_namespace.h> 38 + #include <uapi/linux/mount.h> 38 39 #include "internal.h" 39 40 40 41 static int thaw_super_locked(struct super_block *sb); ··· 1246 1245 { 1247 1246 struct dentry *root; 1248 1247 struct super_block *sb; 1249 - char *secdata = NULL; 1250 1248 int error = -ENOMEM; 1249 + void *sec_opts = NULL; 1251 1250 1252 1251 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { 1253 - secdata = alloc_secdata(); 1254 - if (!secdata) 1255 - goto out; 1256 - 1257 - error = security_sb_copy_data(data, secdata); 1252 + error = security_sb_eat_lsm_opts(data, &sec_opts); 1258 1253 if (error) 1259 - goto out_free_secdata; 1254 + return ERR_PTR(error); 1260 1255 } 1261 1256 1262 1257 root = type->mount(type, flags, name, data); ··· 1273 1276 smp_wmb(); 1274 1277 sb->s_flags |= SB_BORN; 1275 1278 1276 - error = security_sb_kern_mount(sb, flags, secdata); 1279 + error = security_sb_set_mnt_opts(sb, sec_opts, 0, NULL); 1277 1280 if (error) 1278 1281 goto out_sb; 1282 + 1283 + if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT))) { 1284 + error = security_sb_kern_mount(sb); 1285 + if (error) 1286 + goto out_sb; 1287 + } 1279 1288 1280 1289 /* 1281 1290 * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE ··· 1293 1290 "negative value (%lld)\n", type->name, sb->s_maxbytes); 1294 1291 1295 1292 up_write(&sb->s_umount); 1296 - free_secdata(secdata); 1293 + security_free_mnt_opts(&sec_opts); 1297 1294 return root; 1298 1295 out_sb: 1299 1296 dput(root); 1300 1297 deactivate_locked_super(sb); 1301 1298 out_free_secdata: 1302 - free_secdata(secdata); 1303 - out: 1299 + security_free_mnt_opts(&sec_opts); 1304 1300 return ERR_PTR(error); 1305 1301 } 1306 1302
+10 -7
include/linux/lsm_hooks.h
··· 1461 1461 1462 1462 int (*sb_alloc_security)(struct super_block *sb); 1463 1463 void (*sb_free_security)(struct super_block *sb); 1464 - int (*sb_copy_data)(char *orig, char *copy); 1465 - int (*sb_remount)(struct super_block *sb, void *data); 1466 - int (*sb_kern_mount)(struct super_block *sb, int flags, void *data); 1464 + void (*sb_free_mnt_opts)(void *mnt_opts); 1465 + int (*sb_eat_lsm_opts)(char *orig, void **mnt_opts); 1466 + int (*sb_remount)(struct super_block *sb, void *mnt_opts); 1467 + int (*sb_kern_mount)(struct super_block *sb); 1467 1468 int (*sb_show_options)(struct seq_file *m, struct super_block *sb); 1468 1469 int (*sb_statfs)(struct dentry *dentry); 1469 1470 int (*sb_mount)(const char *dev_name, const struct path *path, ··· 1472 1471 int (*sb_umount)(struct vfsmount *mnt, int flags); 1473 1472 int (*sb_pivotroot)(const struct path *old_path, const struct path *new_path); 1474 1473 int (*sb_set_mnt_opts)(struct super_block *sb, 1475 - struct security_mnt_opts *opts, 1474 + void *mnt_opts, 1476 1475 unsigned long kern_flags, 1477 1476 unsigned long *set_kern_flags); 1478 1477 int (*sb_clone_mnt_opts)(const struct super_block *oldsb, 1479 1478 struct super_block *newsb, 1480 1479 unsigned long kern_flags, 1481 1480 unsigned long *set_kern_flags); 1482 - int (*sb_parse_opts_str)(char *options, struct security_mnt_opts *opts); 1481 + int (*sb_add_mnt_opt)(const char *option, const char *val, int len, 1482 + void **mnt_opts); 1483 1483 int (*dentry_init_security)(struct dentry *dentry, int mode, 1484 1484 const struct qstr *name, void **ctx, 1485 1485 u32 *ctxlen); ··· 1802 1800 struct hlist_head bprm_committed_creds; 1803 1801 struct hlist_head sb_alloc_security; 1804 1802 struct hlist_head sb_free_security; 1805 - struct hlist_head sb_copy_data; 1803 + struct hlist_head sb_free_mnt_opts; 1804 + struct hlist_head sb_eat_lsm_opts; 1806 1805 struct hlist_head sb_remount; 1807 1806 struct hlist_head sb_kern_mount; 1808 1807 struct hlist_head sb_show_options; ··· 1813 1810 struct hlist_head sb_pivotroot; 1814 1811 struct hlist_head sb_set_mnt_opts; 1815 1812 struct hlist_head sb_clone_mnt_opts; 1816 - struct hlist_head sb_parse_opts_str; 1813 + struct hlist_head sb_add_mnt_opt; 1817 1814 struct hlist_head dentry_init_security; 1818 1815 struct hlist_head dentry_create_files_as; 1819 1816 #ifdef CONFIG_SECURITY_PATH
+1 -1
include/linux/mount.h
··· 81 81 extern void mntput(struct vfsmount *mnt); 82 82 extern struct vfsmount *mntget(struct vfsmount *mnt); 83 83 extern struct vfsmount *mnt_clone_internal(const struct path *path); 84 - extern int __mnt_is_readonly(struct vfsmount *mnt); 84 + extern bool __mnt_is_readonly(struct vfsmount *mnt); 85 85 extern bool mnt_may_suid(struct vfsmount *mnt); 86 86 87 87 struct path;
+16 -66
include/linux/security.h
··· 182 182 183 183 #ifdef CONFIG_SECURITY 184 184 185 - struct security_mnt_opts { 186 - char **mnt_opts; 187 - int *mnt_opts_flags; 188 - int num_mnt_opts; 189 - }; 190 - 191 185 int call_lsm_notifier(enum lsm_event event, void *data); 192 186 int register_lsm_notifier(struct notifier_block *nb); 193 187 int unregister_lsm_notifier(struct notifier_block *nb); 194 - 195 - static inline void security_init_mnt_opts(struct security_mnt_opts *opts) 196 - { 197 - opts->mnt_opts = NULL; 198 - opts->mnt_opts_flags = NULL; 199 - opts->num_mnt_opts = 0; 200 - } 201 - 202 - static inline void security_free_mnt_opts(struct security_mnt_opts *opts) 203 - { 204 - int i; 205 - if (opts->mnt_opts) 206 - for (i = 0; i < opts->num_mnt_opts; i++) 207 - kfree(opts->mnt_opts[i]); 208 - kfree(opts->mnt_opts); 209 - opts->mnt_opts = NULL; 210 - kfree(opts->mnt_opts_flags); 211 - opts->mnt_opts_flags = NULL; 212 - opts->num_mnt_opts = 0; 213 - } 214 188 215 189 /* prototypes */ 216 190 extern int security_init(void); ··· 222 248 void security_bprm_committed_creds(struct linux_binprm *bprm); 223 249 int security_sb_alloc(struct super_block *sb); 224 250 void security_sb_free(struct super_block *sb); 225 - int security_sb_copy_data(char *orig, char *copy); 226 - int security_sb_remount(struct super_block *sb, void *data); 227 - int security_sb_kern_mount(struct super_block *sb, int flags, void *data); 251 + void security_free_mnt_opts(void **mnt_opts); 252 + int security_sb_eat_lsm_opts(char *options, void **mnt_opts); 253 + int security_sb_remount(struct super_block *sb, void *mnt_opts); 254 + int security_sb_kern_mount(struct super_block *sb); 228 255 int security_sb_show_options(struct seq_file *m, struct super_block *sb); 229 256 int security_sb_statfs(struct dentry *dentry); 230 257 int security_sb_mount(const char *dev_name, const struct path *path, ··· 233 258 int security_sb_umount(struct vfsmount *mnt, int flags); 234 259 int security_sb_pivotroot(const struct path *old_path, const struct path *new_path); 235 260 int security_sb_set_mnt_opts(struct super_block *sb, 236 - struct security_mnt_opts *opts, 261 + void *mnt_opts, 237 262 unsigned long kern_flags, 238 263 unsigned long *set_kern_flags); 239 264 int security_sb_clone_mnt_opts(const struct super_block *oldsb, 240 265 struct super_block *newsb, 241 266 unsigned long kern_flags, 242 267 unsigned long *set_kern_flags); 243 - int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); 268 + int security_add_mnt_opt(const char *option, const char *val, 269 + int len, void **mnt_opts); 244 270 int security_dentry_init_security(struct dentry *dentry, int mode, 245 271 const struct qstr *name, void **ctx, 246 272 u32 *ctxlen); ··· 379 403 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); 380 404 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); 381 405 #else /* CONFIG_SECURITY */ 382 - struct security_mnt_opts { 383 - }; 384 406 385 407 static inline int call_lsm_notifier(enum lsm_event event, void *data) 386 408 { ··· 395 421 return 0; 396 422 } 397 423 398 - static inline void security_init_mnt_opts(struct security_mnt_opts *opts) 399 - { 400 - } 401 - 402 - static inline void security_free_mnt_opts(struct security_mnt_opts *opts) 424 + static inline void security_free_mnt_opts(void **mnt_opts) 403 425 { 404 426 } 405 427 ··· 525 555 static inline void security_sb_free(struct super_block *sb) 526 556 { } 527 557 528 - static inline int security_sb_copy_data(char *orig, char *copy) 558 + static inline int security_sb_eat_lsm_opts(char *options, 559 + void **mnt_opts) 529 560 { 530 561 return 0; 531 562 } 532 563 533 - static inline int security_sb_remount(struct super_block *sb, void *data) 564 + static inline int security_sb_remount(struct super_block *sb, 565 + void *mnt_opts) 534 566 { 535 567 return 0; 536 568 } 537 569 538 - static inline int security_sb_kern_mount(struct super_block *sb, int flags, void *data) 570 + static inline int security_sb_kern_mount(struct super_block *sb) 539 571 { 540 572 return 0; 541 573 } ··· 572 600 } 573 601 574 602 static inline int security_sb_set_mnt_opts(struct super_block *sb, 575 - struct security_mnt_opts *opts, 603 + void *mnt_opts, 576 604 unsigned long kern_flags, 577 605 unsigned long *set_kern_flags) 578 606 { ··· 587 615 return 0; 588 616 } 589 617 590 - static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) 618 + static inline int security_add_mnt_opt(const char *option, const char *val, 619 + int len, void **mnt_opts) 591 620 { 592 621 return 0; 593 622 } ··· 1792 1819 { } 1793 1820 #endif /* CONFIG_SECURITY */ 1794 1821 #endif /* CONFIG_BPF_SYSCALL */ 1795 - 1796 - #ifdef CONFIG_SECURITY 1797 - 1798 - static inline char *alloc_secdata(void) 1799 - { 1800 - return (char *)get_zeroed_page(GFP_KERNEL); 1801 - } 1802 - 1803 - static inline void free_secdata(void *secdata) 1804 - { 1805 - free_page((unsigned long)secdata); 1806 - } 1807 - 1808 - #else 1809 - 1810 - static inline char *alloc_secdata(void) 1811 - { 1812 - return (char *)1; 1813 - } 1814 - 1815 - static inline void free_secdata(void *secdata) 1816 - { } 1817 - #endif /* CONFIG_SECURITY */ 1818 1822 1819 1823 #endif /* ! __LINUX_SECURITY_H */ 1820 1824
+5 -51
include/uapi/linux/fs.h
··· 14 14 #include <linux/ioctl.h> 15 15 #include <linux/types.h> 16 16 17 + /* Use of MS_* flags within the kernel is restricted to core mount(2) code. */ 18 + #if !defined(__KERNEL__) 19 + #include <linux/mount.h> 20 + #endif 21 + 17 22 /* 18 23 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change 19 24 * the file limit at runtime and only root can increase the per-process ··· 105 100 106 101 107 102 #define NR_FILE 8192 /* this can well be larger on a larger system */ 108 - 109 - 110 - /* 111 - * These are the fs-independent mount-flags: up to 32 flags are supported 112 - */ 113 - #define MS_RDONLY 1 /* Mount read-only */ 114 - #define MS_NOSUID 2 /* Ignore suid and sgid bits */ 115 - #define MS_NODEV 4 /* Disallow access to device special files */ 116 - #define MS_NOEXEC 8 /* Disallow program execution */ 117 - #define MS_SYNCHRONOUS 16 /* Writes are synced at once */ 118 - #define MS_REMOUNT 32 /* Alter flags of a mounted FS */ 119 - #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ 120 - #define MS_DIRSYNC 128 /* Directory modifications are synchronous */ 121 - #define MS_NOATIME 1024 /* Do not update access times. */ 122 - #define MS_NODIRATIME 2048 /* Do not update directory access times */ 123 - #define MS_BIND 4096 124 - #define MS_MOVE 8192 125 - #define MS_REC 16384 126 - #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. 127 - MS_VERBOSE is deprecated. */ 128 - #define MS_SILENT 32768 129 - #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ 130 - #define MS_UNBINDABLE (1<<17) /* change to unbindable */ 131 - #define MS_PRIVATE (1<<18) /* change to private */ 132 - #define MS_SLAVE (1<<19) /* change to slave */ 133 - #define MS_SHARED (1<<20) /* change to shared */ 134 - #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ 135 - #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ 136 - #define MS_I_VERSION (1<<23) /* Update inode I_version field */ 137 - #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ 138 - #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ 139 - 140 - /* These sb flags are internal to the kernel */ 141 - #define MS_SUBMOUNT (1<<26) 142 - #define MS_NOREMOTELOCK (1<<27) 143 - #define MS_NOSEC (1<<28) 144 - #define MS_BORN (1<<29) 145 - #define MS_ACTIVE (1<<30) 146 - #define MS_NOUSER (1<<31) 147 - 148 - /* 149 - * Superblock flags that can be altered by MS_REMOUNT 150 - */ 151 - #define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|\ 152 - MS_LAZYTIME) 153 - 154 - /* 155 - * Old magic mount flag and mask 156 - */ 157 - #define MS_MGC_VAL 0xC0ED0000 158 - #define MS_MGC_MSK 0xffff0000 159 103 160 104 /* 161 105 * Structure for FS_IOC_FSGETXATTR[A] and FS_IOC_FSSETXATTR.
+58
include/uapi/linux/mount.h
··· 1 + #ifndef _UAPI_LINUX_MOUNT_H 2 + #define _UAPI_LINUX_MOUNT_H 3 + 4 + /* 5 + * These are the fs-independent mount-flags: up to 32 flags are supported 6 + * 7 + * Usage of these is restricted within the kernel to core mount(2) code and 8 + * callers of sys_mount() only. Filesystems should be using the SB_* 9 + * equivalent instead. 10 + */ 11 + #define MS_RDONLY 1 /* Mount read-only */ 12 + #define MS_NOSUID 2 /* Ignore suid and sgid bits */ 13 + #define MS_NODEV 4 /* Disallow access to device special files */ 14 + #define MS_NOEXEC 8 /* Disallow program execution */ 15 + #define MS_SYNCHRONOUS 16 /* Writes are synced at once */ 16 + #define MS_REMOUNT 32 /* Alter flags of a mounted FS */ 17 + #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ 18 + #define MS_DIRSYNC 128 /* Directory modifications are synchronous */ 19 + #define MS_NOATIME 1024 /* Do not update access times. */ 20 + #define MS_NODIRATIME 2048 /* Do not update directory access times */ 21 + #define MS_BIND 4096 22 + #define MS_MOVE 8192 23 + #define MS_REC 16384 24 + #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. 25 + MS_VERBOSE is deprecated. */ 26 + #define MS_SILENT 32768 27 + #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ 28 + #define MS_UNBINDABLE (1<<17) /* change to unbindable */ 29 + #define MS_PRIVATE (1<<18) /* change to private */ 30 + #define MS_SLAVE (1<<19) /* change to slave */ 31 + #define MS_SHARED (1<<20) /* change to shared */ 32 + #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ 33 + #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ 34 + #define MS_I_VERSION (1<<23) /* Update inode I_version field */ 35 + #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ 36 + #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ 37 + 38 + /* These sb flags are internal to the kernel */ 39 + #define MS_SUBMOUNT (1<<26) 40 + #define MS_NOREMOTELOCK (1<<27) 41 + #define MS_NOSEC (1<<28) 42 + #define MS_BORN (1<<29) 43 + #define MS_ACTIVE (1<<30) 44 + #define MS_NOUSER (1<<31) 45 + 46 + /* 47 + * Superblock flags that can be altered by MS_REMOUNT 48 + */ 49 + #define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|\ 50 + MS_LAZYTIME) 51 + 52 + /* 53 + * Old magic mount flag and mask 54 + */ 55 + #define MS_MGC_VAL 0xC0ED0000 56 + #define MS_MGC_MSK 0xffff0000 57 + 58 + #endif /* _UAPI_LINUX_MOUNT_H */
+1
init/do_mounts.c
··· 22 22 #include <linux/nfs_fs.h> 23 23 #include <linux/nfs_fs_sb.h> 24 24 #include <linux/nfs_mount.h> 25 + #include <uapi/linux/mount.h> 25 26 26 27 #include "do_mounts.h" 27 28
+1
init/do_mounts_initrd.c
··· 8 8 #include <linux/sched.h> 9 9 #include <linux/freezer.h> 10 10 #include <linux/kmod.h> 11 + #include <uapi/linux/mount.h> 11 12 12 13 #include "do_mounts.h" 13 14
+1
security/apparmor/lsm.c
··· 26 26 #include <linux/netfilter_ipv4.h> 27 27 #include <linux/netfilter_ipv6.h> 28 28 #include <net/sock.h> 29 + #include <uapi/linux/mount.h> 29 30 30 31 #include "include/apparmor.h" 31 32 #include "include/apparmorfs.h"
+1
security/apparmor/mount.c
··· 15 15 #include <linux/fs.h> 16 16 #include <linux/mount.h> 17 17 #include <linux/namei.h> 18 + #include <uapi/linux/mount.h> 18 19 19 20 #include "include/apparmor.h" 20 21 #include "include/audit.h"
+26 -13
security/security.c
··· 384 384 call_void_hook(sb_free_security, sb); 385 385 } 386 386 387 - int security_sb_copy_data(char *orig, char *copy) 387 + void security_free_mnt_opts(void **mnt_opts) 388 388 { 389 - return call_int_hook(sb_copy_data, 0, orig, copy); 389 + if (!*mnt_opts) 390 + return; 391 + call_void_hook(sb_free_mnt_opts, *mnt_opts); 392 + *mnt_opts = NULL; 390 393 } 391 - EXPORT_SYMBOL(security_sb_copy_data); 394 + EXPORT_SYMBOL(security_free_mnt_opts); 392 395 393 - int security_sb_remount(struct super_block *sb, void *data) 396 + int security_sb_eat_lsm_opts(char *options, void **mnt_opts) 394 397 { 395 - return call_int_hook(sb_remount, 0, sb, data); 398 + return call_int_hook(sb_eat_lsm_opts, 0, options, mnt_opts); 396 399 } 400 + EXPORT_SYMBOL(security_sb_eat_lsm_opts); 397 401 398 - int security_sb_kern_mount(struct super_block *sb, int flags, void *data) 402 + int security_sb_remount(struct super_block *sb, 403 + void *mnt_opts) 399 404 { 400 - return call_int_hook(sb_kern_mount, 0, sb, flags, data); 405 + return call_int_hook(sb_remount, 0, sb, mnt_opts); 406 + } 407 + EXPORT_SYMBOL(security_sb_remount); 408 + 409 + int security_sb_kern_mount(struct super_block *sb) 410 + { 411 + return call_int_hook(sb_kern_mount, 0, sb); 401 412 } 402 413 403 414 int security_sb_show_options(struct seq_file *m, struct super_block *sb) ··· 438 427 } 439 428 440 429 int security_sb_set_mnt_opts(struct super_block *sb, 441 - struct security_mnt_opts *opts, 430 + void *mnt_opts, 442 431 unsigned long kern_flags, 443 432 unsigned long *set_kern_flags) 444 433 { 445 434 return call_int_hook(sb_set_mnt_opts, 446 - opts->num_mnt_opts ? -EOPNOTSUPP : 0, sb, 447 - opts, kern_flags, set_kern_flags); 435 + mnt_opts ? -EOPNOTSUPP : 0, sb, 436 + mnt_opts, kern_flags, set_kern_flags); 448 437 } 449 438 EXPORT_SYMBOL(security_sb_set_mnt_opts); 450 439 ··· 458 447 } 459 448 EXPORT_SYMBOL(security_sb_clone_mnt_opts); 460 449 461 - int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) 450 + int security_add_mnt_opt(const char *option, const char *val, int len, 451 + void **mnt_opts) 462 452 { 463 - return call_int_hook(sb_parse_opts_str, 0, options, opts); 453 + return call_int_hook(sb_add_mnt_opt, -EINVAL, 454 + option, val, len, mnt_opts); 464 455 } 465 - EXPORT_SYMBOL(security_sb_parse_opts_str); 456 + EXPORT_SYMBOL(security_add_mnt_opt); 466 457 467 458 int security_inode_alloc(struct inode *inode) 468 459 {
+309 -522
security/selinux/hooks.c
··· 88 88 #include <linux/msg.h> 89 89 #include <linux/shm.h> 90 90 #include <linux/bpf.h> 91 + #include <uapi/linux/mount.h> 91 92 92 93 #include "avc.h" 93 94 #include "objsec.h" ··· 433 432 kfree(sbsec); 434 433 } 435 434 435 + struct selinux_mnt_opts { 436 + const char *fscontext, *context, *rootcontext, *defcontext; 437 + }; 438 + 439 + static void selinux_free_mnt_opts(void *mnt_opts) 440 + { 441 + struct selinux_mnt_opts *opts = mnt_opts; 442 + kfree(opts->fscontext); 443 + kfree(opts->context); 444 + kfree(opts->rootcontext); 445 + kfree(opts->defcontext); 446 + kfree(opts); 447 + } 448 + 436 449 static inline int inode_doinit(struct inode *inode) 437 450 { 438 451 return inode_doinit_with_dentry(inode, NULL); ··· 458 443 Opt_fscontext = 2, 459 444 Opt_defcontext = 3, 460 445 Opt_rootcontext = 4, 461 - Opt_labelsupport = 5, 462 - Opt_nextmntopt = 6, 446 + Opt_seclabel = 5, 463 447 }; 464 448 465 - #define NUM_SEL_MNT_OPTS (Opt_nextmntopt - 1) 466 - 467 - static const match_table_t tokens = { 468 - {Opt_context, CONTEXT_STR "%s"}, 469 - {Opt_fscontext, FSCONTEXT_STR "%s"}, 470 - {Opt_defcontext, DEFCONTEXT_STR "%s"}, 471 - {Opt_rootcontext, ROOTCONTEXT_STR "%s"}, 472 - {Opt_labelsupport, LABELSUPP_STR}, 473 - {Opt_error, NULL}, 449 + #define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg} 450 + static struct { 451 + const char *name; 452 + int len; 453 + int opt; 454 + bool has_arg; 455 + } tokens[] = { 456 + A(context, true), 457 + A(fscontext, true), 458 + A(defcontext, true), 459 + A(rootcontext, true), 460 + A(seclabel, false), 474 461 }; 462 + #undef A 463 + 464 + static int match_opt_prefix(char *s, int l, char **arg) 465 + { 466 + int i; 467 + 468 + for (i = 0; i < ARRAY_SIZE(tokens); i++) { 469 + size_t len = tokens[i].len; 470 + if (len > l || memcmp(s, tokens[i].name, len)) 471 + continue; 472 + if (tokens[i].has_arg) { 473 + if (len == l || s[len] != '=') 474 + continue; 475 + *arg = s + len + 1; 476 + } else if (len != l) 477 + continue; 478 + return tokens[i].opt; 479 + } 480 + return Opt_error; 481 + } 475 482 476 483 #define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" 477 484 ··· 607 570 during get_sb by a pseudo filesystem that directly 608 571 populates itself. */ 609 572 spin_lock(&sbsec->isec_lock); 610 - next_inode: 611 - if (!list_empty(&sbsec->isec_head)) { 573 + while (!list_empty(&sbsec->isec_head)) { 612 574 struct inode_security_struct *isec = 613 - list_entry(sbsec->isec_head.next, 575 + list_first_entry(&sbsec->isec_head, 614 576 struct inode_security_struct, list); 615 577 struct inode *inode = isec->inode; 616 578 list_del_init(&isec->list); ··· 621 585 iput(inode); 622 586 } 623 587 spin_lock(&sbsec->isec_lock); 624 - goto next_inode; 625 588 } 626 589 spin_unlock(&sbsec->isec_lock); 627 590 out: 628 - return rc; 629 - } 630 - 631 - /* 632 - * This function should allow an FS to ask what it's mount security 633 - * options were so it can use those later for submounts, displaying 634 - * mount options, or whatever. 635 - */ 636 - static int selinux_get_mnt_opts(const struct super_block *sb, 637 - struct security_mnt_opts *opts) 638 - { 639 - int rc = 0, i; 640 - struct superblock_security_struct *sbsec = sb->s_security; 641 - char *context = NULL; 642 - u32 len; 643 - char tmp; 644 - 645 - security_init_mnt_opts(opts); 646 - 647 - if (!(sbsec->flags & SE_SBINITIALIZED)) 648 - return -EINVAL; 649 - 650 - if (!selinux_state.initialized) 651 - return -EINVAL; 652 - 653 - /* make sure we always check enough bits to cover the mask */ 654 - BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS)); 655 - 656 - tmp = sbsec->flags & SE_MNTMASK; 657 - /* count the number of mount options for this sb */ 658 - for (i = 0; i < NUM_SEL_MNT_OPTS; i++) { 659 - if (tmp & 0x01) 660 - opts->num_mnt_opts++; 661 - tmp >>= 1; 662 - } 663 - /* Check if the Label support flag is set */ 664 - if (sbsec->flags & SBLABEL_MNT) 665 - opts->num_mnt_opts++; 666 - 667 - opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 668 - if (!opts->mnt_opts) { 669 - rc = -ENOMEM; 670 - goto out_free; 671 - } 672 - 673 - opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC); 674 - if (!opts->mnt_opts_flags) { 675 - rc = -ENOMEM; 676 - goto out_free; 677 - } 678 - 679 - i = 0; 680 - if (sbsec->flags & FSCONTEXT_MNT) { 681 - rc = security_sid_to_context(&selinux_state, sbsec->sid, 682 - &context, &len); 683 - if (rc) 684 - goto out_free; 685 - opts->mnt_opts[i] = context; 686 - opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; 687 - } 688 - if (sbsec->flags & CONTEXT_MNT) { 689 - rc = security_sid_to_context(&selinux_state, 690 - sbsec->mntpoint_sid, 691 - &context, &len); 692 - if (rc) 693 - goto out_free; 694 - opts->mnt_opts[i] = context; 695 - opts->mnt_opts_flags[i++] = CONTEXT_MNT; 696 - } 697 - if (sbsec->flags & DEFCONTEXT_MNT) { 698 - rc = security_sid_to_context(&selinux_state, sbsec->def_sid, 699 - &context, &len); 700 - if (rc) 701 - goto out_free; 702 - opts->mnt_opts[i] = context; 703 - opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; 704 - } 705 - if (sbsec->flags & ROOTCONTEXT_MNT) { 706 - struct dentry *root = sbsec->sb->s_root; 707 - struct inode_security_struct *isec = backing_inode_security(root); 708 - 709 - rc = security_sid_to_context(&selinux_state, isec->sid, 710 - &context, &len); 711 - if (rc) 712 - goto out_free; 713 - opts->mnt_opts[i] = context; 714 - opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 715 - } 716 - if (sbsec->flags & SBLABEL_MNT) { 717 - opts->mnt_opts[i] = NULL; 718 - opts->mnt_opts_flags[i++] = SBLABEL_MNT; 719 - } 720 - 721 - BUG_ON(i != opts->num_mnt_opts); 722 - 723 - return 0; 724 - 725 - out_free: 726 - security_free_mnt_opts(opts); 727 591 return rc; 728 592 } 729 593 ··· 647 711 return 0; 648 712 } 649 713 714 + static int parse_sid(struct super_block *sb, const char *s, u32 *sid) 715 + { 716 + int rc = security_context_str_to_sid(&selinux_state, s, 717 + sid, GFP_KERNEL); 718 + if (rc) 719 + pr_warn("SELinux: security_context_str_to_sid" 720 + "(%s) failed for (dev %s, type %s) errno=%d\n", 721 + s, sb->s_id, sb->s_type->name, rc); 722 + return rc; 723 + } 724 + 650 725 /* 651 726 * Allow filesystems with binary mount data to explicitly set mount point 652 727 * labeling information. 653 728 */ 654 729 static int selinux_set_mnt_opts(struct super_block *sb, 655 - struct security_mnt_opts *opts, 730 + void *mnt_opts, 656 731 unsigned long kern_flags, 657 732 unsigned long *set_kern_flags) 658 733 { 659 734 const struct cred *cred = current_cred(); 660 - int rc = 0, i; 661 735 struct superblock_security_struct *sbsec = sb->s_security; 662 - const char *name = sb->s_type->name; 663 736 struct dentry *root = sbsec->sb->s_root; 737 + struct selinux_mnt_opts *opts = mnt_opts; 664 738 struct inode_security_struct *root_isec; 665 739 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 666 740 u32 defcontext_sid = 0; 667 - char **mount_options = opts->mnt_opts; 668 - int *flags = opts->mnt_opts_flags; 669 - int num_opts = opts->num_mnt_opts; 741 + int rc = 0; 670 742 671 743 mutex_lock(&sbsec->lock); 672 744 673 745 if (!selinux_state.initialized) { 674 - if (!num_opts) { 746 + if (!opts) { 675 747 /* Defer initialization until selinux_complete_init, 676 748 after the initial policy is loaded and the security 677 749 server is ready to handle calls. */ ··· 709 765 * will be used for both mounts) 710 766 */ 711 767 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) 712 - && (num_opts == 0)) 768 + && !opts) 713 769 goto out; 714 770 715 771 root_isec = backing_inode_security_novalidate(root); ··· 719 775 * also check if someone is trying to mount the same sb more 720 776 * than once with different security options. 721 777 */ 722 - for (i = 0; i < num_opts; i++) { 723 - u32 sid; 724 - 725 - if (flags[i] == SBLABEL_MNT) 726 - continue; 727 - rc = security_context_str_to_sid(&selinux_state, 728 - mount_options[i], &sid, 729 - GFP_KERNEL); 730 - if (rc) { 731 - pr_warn("SELinux: security_context_str_to_sid" 732 - "(%s) failed for (dev %s, type %s) errno=%d\n", 733 - mount_options[i], sb->s_id, name, rc); 734 - goto out; 735 - } 736 - switch (flags[i]) { 737 - case FSCONTEXT_MNT: 738 - fscontext_sid = sid; 739 - 778 + if (opts) { 779 + if (opts->fscontext) { 780 + rc = parse_sid(sb, opts->fscontext, &fscontext_sid); 781 + if (rc) 782 + goto out; 740 783 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, 741 784 fscontext_sid)) 742 785 goto out_double_mount; 743 - 744 786 sbsec->flags |= FSCONTEXT_MNT; 745 - break; 746 - case CONTEXT_MNT: 747 - context_sid = sid; 748 - 787 + } 788 + if (opts->context) { 789 + rc = parse_sid(sb, opts->context, &context_sid); 790 + if (rc) 791 + goto out; 749 792 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, 750 793 context_sid)) 751 794 goto out_double_mount; 752 - 753 795 sbsec->flags |= CONTEXT_MNT; 754 - break; 755 - case ROOTCONTEXT_MNT: 756 - rootcontext_sid = sid; 757 - 796 + } 797 + if (opts->rootcontext) { 798 + rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid); 799 + if (rc) 800 + goto out; 758 801 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, 759 802 rootcontext_sid)) 760 803 goto out_double_mount; 761 - 762 804 sbsec->flags |= ROOTCONTEXT_MNT; 763 - 764 - break; 765 - case DEFCONTEXT_MNT: 766 - defcontext_sid = sid; 767 - 805 + } 806 + if (opts->defcontext) { 807 + rc = parse_sid(sb, opts->defcontext, &defcontext_sid); 808 + if (rc) 809 + goto out; 768 810 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, 769 811 defcontext_sid)) 770 812 goto out_double_mount; 771 - 772 813 sbsec->flags |= DEFCONTEXT_MNT; 773 - 774 - break; 775 - default: 776 - rc = -EINVAL; 777 - goto out; 778 814 } 779 815 } 780 816 781 817 if (sbsec->flags & SE_SBINITIALIZED) { 782 818 /* previously mounted with options, but not on this attempt? */ 783 - if ((sbsec->flags & SE_MNTMASK) && !num_opts) 819 + if ((sbsec->flags & SE_MNTMASK) && !opts) 784 820 goto out_double_mount; 785 821 rc = 0; 786 822 goto out; ··· 893 969 out_double_mount: 894 970 rc = -EINVAL; 895 971 pr_warn("SELinux: mount invalid. Same superblock, different " 896 - "security settings for (dev %s, type %s)\n", sb->s_id, name); 972 + "security settings for (dev %s, type %s)\n", sb->s_id, 973 + sb->s_type->name); 897 974 goto out; 898 975 } 899 976 ··· 1006 1081 return rc; 1007 1082 } 1008 1083 1009 - static int selinux_parse_opts_str(char *options, 1010 - struct security_mnt_opts *opts) 1084 + static int selinux_add_opt(int token, const char *s, void **mnt_opts) 1011 1085 { 1012 - char *p; 1013 - char *context = NULL, *defcontext = NULL; 1014 - char *fscontext = NULL, *rootcontext = NULL; 1015 - int rc, num_mnt_opts = 0; 1086 + struct selinux_mnt_opts *opts = *mnt_opts; 1016 1087 1017 - opts->num_mnt_opts = 0; 1088 + if (token == Opt_seclabel) /* eaten and completely ignored */ 1089 + return 0; 1018 1090 1019 - /* Standard string-based options. */ 1020 - while ((p = strsep(&options, "|")) != NULL) { 1021 - int token; 1022 - substring_t args[MAX_OPT_ARGS]; 1091 + if (!opts) { 1092 + opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); 1093 + if (!opts) 1094 + return -ENOMEM; 1095 + *mnt_opts = opts; 1096 + } 1097 + if (!s) 1098 + return -ENOMEM; 1099 + switch (token) { 1100 + case Opt_context: 1101 + if (opts->context || opts->defcontext) 1102 + goto Einval; 1103 + opts->context = s; 1104 + break; 1105 + case Opt_fscontext: 1106 + if (opts->fscontext) 1107 + goto Einval; 1108 + opts->fscontext = s; 1109 + break; 1110 + case Opt_rootcontext: 1111 + if (opts->rootcontext) 1112 + goto Einval; 1113 + opts->rootcontext = s; 1114 + break; 1115 + case Opt_defcontext: 1116 + if (opts->context || opts->defcontext) 1117 + goto Einval; 1118 + opts->defcontext = s; 1119 + break; 1120 + } 1121 + return 0; 1122 + Einval: 1123 + pr_warn(SEL_MOUNT_FAIL_MSG); 1124 + return -EINVAL; 1125 + } 1023 1126 1024 - if (!*p) 1025 - continue; 1127 + static int selinux_add_mnt_opt(const char *option, const char *val, int len, 1128 + void **mnt_opts) 1129 + { 1130 + int token = Opt_error; 1131 + int rc, i; 1026 1132 1027 - token = match_token(p, tokens, args); 1028 - 1029 - switch (token) { 1030 - case Opt_context: 1031 - if (context || defcontext) { 1032 - rc = -EINVAL; 1033 - pr_warn(SEL_MOUNT_FAIL_MSG); 1034 - goto out_err; 1035 - } 1036 - context = match_strdup(&args[0]); 1037 - if (!context) { 1038 - rc = -ENOMEM; 1039 - goto out_err; 1040 - } 1133 + for (i = 0; i < ARRAY_SIZE(tokens); i++) { 1134 + if (strcmp(option, tokens[i].name) == 0) { 1135 + token = tokens[i].opt; 1041 1136 break; 1042 - 1043 - case Opt_fscontext: 1044 - if (fscontext) { 1045 - rc = -EINVAL; 1046 - pr_warn(SEL_MOUNT_FAIL_MSG); 1047 - goto out_err; 1048 - } 1049 - fscontext = match_strdup(&args[0]); 1050 - if (!fscontext) { 1051 - rc = -ENOMEM; 1052 - goto out_err; 1053 - } 1054 - break; 1055 - 1056 - case Opt_rootcontext: 1057 - if (rootcontext) { 1058 - rc = -EINVAL; 1059 - pr_warn(SEL_MOUNT_FAIL_MSG); 1060 - goto out_err; 1061 - } 1062 - rootcontext = match_strdup(&args[0]); 1063 - if (!rootcontext) { 1064 - rc = -ENOMEM; 1065 - goto out_err; 1066 - } 1067 - break; 1068 - 1069 - case Opt_defcontext: 1070 - if (context || defcontext) { 1071 - rc = -EINVAL; 1072 - pr_warn(SEL_MOUNT_FAIL_MSG); 1073 - goto out_err; 1074 - } 1075 - defcontext = match_strdup(&args[0]); 1076 - if (!defcontext) { 1077 - rc = -ENOMEM; 1078 - goto out_err; 1079 - } 1080 - break; 1081 - case Opt_labelsupport: 1082 - break; 1083 - default: 1084 - rc = -EINVAL; 1085 - pr_warn("SELinux: unknown mount option\n"); 1086 - goto out_err; 1087 - 1088 1137 } 1089 1138 } 1090 1139 1091 - rc = -ENOMEM; 1092 - opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_KERNEL); 1093 - if (!opts->mnt_opts) 1094 - goto out_err; 1140 + if (token == Opt_error) 1141 + return -EINVAL; 1095 1142 1096 - opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), 1097 - GFP_KERNEL); 1098 - if (!opts->mnt_opts_flags) 1099 - goto out_err; 1143 + if (token != Opt_seclabel) 1144 + val = kmemdup_nul(val, len, GFP_KERNEL); 1145 + rc = selinux_add_opt(token, val, mnt_opts); 1146 + if (unlikely(rc)) { 1147 + kfree(val); 1148 + if (*mnt_opts) { 1149 + selinux_free_mnt_opts(*mnt_opts); 1150 + *mnt_opts = NULL; 1151 + } 1152 + } 1153 + return rc; 1154 + } 1100 1155 1101 - if (fscontext) { 1102 - opts->mnt_opts[num_mnt_opts] = fscontext; 1103 - opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; 1104 - } 1105 - if (context) { 1106 - opts->mnt_opts[num_mnt_opts] = context; 1107 - opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; 1108 - } 1109 - if (rootcontext) { 1110 - opts->mnt_opts[num_mnt_opts] = rootcontext; 1111 - opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; 1112 - } 1113 - if (defcontext) { 1114 - opts->mnt_opts[num_mnt_opts] = defcontext; 1115 - opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; 1116 - } 1156 + static int show_sid(struct seq_file *m, u32 sid) 1157 + { 1158 + char *context = NULL; 1159 + u32 len; 1160 + int rc; 1117 1161 1118 - opts->num_mnt_opts = num_mnt_opts; 1119 - return 0; 1162 + rc = security_sid_to_context(&selinux_state, sid, 1163 + &context, &len); 1164 + if (!rc) { 1165 + bool has_comma = context && strchr(context, ','); 1120 1166 1121 - out_err: 1122 - security_free_mnt_opts(opts); 1167 + if (has_comma) 1168 + seq_putc(m, '\"'); 1169 + seq_escape(m, context, "\"\n\\"); 1170 + if (has_comma) 1171 + seq_putc(m, '\"'); 1172 + } 1123 1173 kfree(context); 1124 - kfree(defcontext); 1125 - kfree(fscontext); 1126 - kfree(rootcontext); 1127 1174 return rc; 1128 - } 1129 - /* 1130 - * string mount options parsing and call set the sbsec 1131 - */ 1132 - static int superblock_doinit(struct super_block *sb, void *data) 1133 - { 1134 - int rc = 0; 1135 - char *options = data; 1136 - struct security_mnt_opts opts; 1137 - 1138 - security_init_mnt_opts(&opts); 1139 - 1140 - if (!data) 1141 - goto out; 1142 - 1143 - BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA); 1144 - 1145 - rc = selinux_parse_opts_str(options, &opts); 1146 - if (rc) 1147 - goto out_err; 1148 - 1149 - out: 1150 - rc = selinux_set_mnt_opts(sb, &opts, 0, NULL); 1151 - 1152 - out_err: 1153 - security_free_mnt_opts(&opts); 1154 - return rc; 1155 - } 1156 - 1157 - static void selinux_write_opts(struct seq_file *m, 1158 - struct security_mnt_opts *opts) 1159 - { 1160 - int i; 1161 - char *prefix; 1162 - 1163 - for (i = 0; i < opts->num_mnt_opts; i++) { 1164 - char *has_comma; 1165 - 1166 - if (opts->mnt_opts[i]) 1167 - has_comma = strchr(opts->mnt_opts[i], ','); 1168 - else 1169 - has_comma = NULL; 1170 - 1171 - switch (opts->mnt_opts_flags[i]) { 1172 - case CONTEXT_MNT: 1173 - prefix = CONTEXT_STR; 1174 - break; 1175 - case FSCONTEXT_MNT: 1176 - prefix = FSCONTEXT_STR; 1177 - break; 1178 - case ROOTCONTEXT_MNT: 1179 - prefix = ROOTCONTEXT_STR; 1180 - break; 1181 - case DEFCONTEXT_MNT: 1182 - prefix = DEFCONTEXT_STR; 1183 - break; 1184 - case SBLABEL_MNT: 1185 - seq_putc(m, ','); 1186 - seq_puts(m, LABELSUPP_STR); 1187 - continue; 1188 - default: 1189 - BUG(); 1190 - return; 1191 - }; 1192 - /* we need a comma before each option */ 1193 - seq_putc(m, ','); 1194 - seq_puts(m, prefix); 1195 - if (has_comma) 1196 - seq_putc(m, '\"'); 1197 - seq_escape(m, opts->mnt_opts[i], "\"\n\\"); 1198 - if (has_comma) 1199 - seq_putc(m, '\"'); 1200 - } 1201 1175 } 1202 1176 1203 1177 static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) 1204 1178 { 1205 - struct security_mnt_opts opts; 1179 + struct superblock_security_struct *sbsec = sb->s_security; 1206 1180 int rc; 1207 1181 1208 - rc = selinux_get_mnt_opts(sb, &opts); 1209 - if (rc) { 1210 - /* before policy load we may get EINVAL, don't show anything */ 1211 - if (rc == -EINVAL) 1212 - rc = 0; 1213 - return rc; 1182 + if (!(sbsec->flags & SE_SBINITIALIZED)) 1183 + return 0; 1184 + 1185 + if (!selinux_state.initialized) 1186 + return 0; 1187 + 1188 + if (sbsec->flags & FSCONTEXT_MNT) { 1189 + seq_putc(m, ','); 1190 + seq_puts(m, FSCONTEXT_STR); 1191 + rc = show_sid(m, sbsec->sid); 1192 + if (rc) 1193 + return rc; 1214 1194 } 1215 - 1216 - selinux_write_opts(m, &opts); 1217 - 1218 - security_free_mnt_opts(&opts); 1219 - 1220 - return rc; 1195 + if (sbsec->flags & CONTEXT_MNT) { 1196 + seq_putc(m, ','); 1197 + seq_puts(m, CONTEXT_STR); 1198 + rc = show_sid(m, sbsec->mntpoint_sid); 1199 + if (rc) 1200 + return rc; 1201 + } 1202 + if (sbsec->flags & DEFCONTEXT_MNT) { 1203 + seq_putc(m, ','); 1204 + seq_puts(m, DEFCONTEXT_STR); 1205 + rc = show_sid(m, sbsec->def_sid); 1206 + if (rc) 1207 + return rc; 1208 + } 1209 + if (sbsec->flags & ROOTCONTEXT_MNT) { 1210 + struct dentry *root = sbsec->sb->s_root; 1211 + struct inode_security_struct *isec = backing_inode_security(root); 1212 + seq_putc(m, ','); 1213 + seq_puts(m, ROOTCONTEXT_STR); 1214 + rc = show_sid(m, isec->sid); 1215 + if (rc) 1216 + return rc; 1217 + } 1218 + if (sbsec->flags & SBLABEL_MNT) { 1219 + seq_putc(m, ','); 1220 + seq_puts(m, LABELSUPP_STR); 1221 + } 1222 + return 0; 1221 1223 } 1222 1224 1223 1225 static inline u16 inode_mode_to_security_class(umode_t mode) ··· 2599 2747 superblock_free_security(sb); 2600 2748 } 2601 2749 2602 - static inline int match_prefix(char *prefix, int plen, char *option, int olen) 2750 + static inline int opt_len(const char *s) 2603 2751 { 2604 - if (plen > olen) 2605 - return 0; 2752 + bool open_quote = false; 2753 + int len; 2754 + char c; 2606 2755 2607 - return !memcmp(prefix, option, plen); 2608 - } 2609 - 2610 - static inline int selinux_option(char *option, int len) 2611 - { 2612 - return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || 2613 - match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || 2614 - match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || 2615 - match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) || 2616 - match_prefix(LABELSUPP_STR, sizeof(LABELSUPP_STR)-1, option, len)); 2617 - } 2618 - 2619 - static inline void take_option(char **to, char *from, int *first, int len) 2620 - { 2621 - if (!*first) { 2622 - **to = ','; 2623 - *to += 1; 2624 - } else 2625 - *first = 0; 2626 - memcpy(*to, from, len); 2627 - *to += len; 2628 - } 2629 - 2630 - static inline void take_selinux_option(char **to, char *from, int *first, 2631 - int len) 2632 - { 2633 - int current_size = 0; 2634 - 2635 - if (!*first) { 2636 - **to = '|'; 2637 - *to += 1; 2638 - } else 2639 - *first = 0; 2640 - 2641 - while (current_size < len) { 2642 - if (*from != '"') { 2643 - **to = *from; 2644 - *to += 1; 2645 - } 2646 - from += 1; 2647 - current_size += 1; 2648 - } 2649 - } 2650 - 2651 - static int selinux_sb_copy_data(char *orig, char *copy) 2652 - { 2653 - int fnosec, fsec, rc = 0; 2654 - char *in_save, *in_curr, *in_end; 2655 - char *sec_curr, *nosec_save, *nosec; 2656 - int open_quote = 0; 2657 - 2658 - in_curr = orig; 2659 - sec_curr = copy; 2660 - 2661 - nosec = (char *)get_zeroed_page(GFP_KERNEL); 2662 - if (!nosec) { 2663 - rc = -ENOMEM; 2664 - goto out; 2665 - } 2666 - 2667 - nosec_save = nosec; 2668 - fnosec = fsec = 1; 2669 - in_save = in_end = orig; 2670 - 2671 - do { 2672 - if (*in_end == '"') 2756 + for (len = 0; (c = s[len]) != '\0'; len++) { 2757 + if (c == '"') 2673 2758 open_quote = !open_quote; 2674 - if ((*in_end == ',' && open_quote == 0) || 2675 - *in_end == '\0') { 2676 - int len = in_end - in_curr; 2677 - 2678 - if (selinux_option(in_curr, len)) 2679 - take_selinux_option(&sec_curr, in_curr, &fsec, len); 2680 - else 2681 - take_option(&nosec, in_curr, &fnosec, len); 2682 - 2683 - in_curr = in_end + 1; 2684 - } 2685 - } while (*in_end++); 2686 - 2687 - strcpy(in_save, nosec_save); 2688 - free_page((unsigned long)nosec_save); 2689 - out: 2690 - return rc; 2759 + if (c == ',' && !open_quote) 2760 + break; 2761 + } 2762 + return len; 2691 2763 } 2692 2764 2693 - static int selinux_sb_remount(struct super_block *sb, void *data) 2765 + static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts) 2694 2766 { 2695 - int rc, i, *flags; 2696 - struct security_mnt_opts opts; 2697 - char *secdata, **mount_options; 2767 + char *from = options; 2768 + char *to = options; 2769 + bool first = true; 2770 + 2771 + while (1) { 2772 + int len = opt_len(from); 2773 + int token, rc; 2774 + char *arg = NULL; 2775 + 2776 + token = match_opt_prefix(from, len, &arg); 2777 + 2778 + if (token != Opt_error) { 2779 + char *p, *q; 2780 + 2781 + /* strip quotes */ 2782 + if (arg) { 2783 + for (p = q = arg; p < from + len; p++) { 2784 + char c = *p; 2785 + if (c != '"') 2786 + *q++ = c; 2787 + } 2788 + arg = kmemdup_nul(arg, q - arg, GFP_KERNEL); 2789 + } 2790 + rc = selinux_add_opt(token, arg, mnt_opts); 2791 + if (unlikely(rc)) { 2792 + kfree(arg); 2793 + if (*mnt_opts) { 2794 + selinux_free_mnt_opts(*mnt_opts); 2795 + *mnt_opts = NULL; 2796 + } 2797 + return rc; 2798 + } 2799 + } else { 2800 + if (!first) { // copy with preceding comma 2801 + from--; 2802 + len++; 2803 + } 2804 + if (to != from) 2805 + memmove(to, from, len); 2806 + to += len; 2807 + first = false; 2808 + } 2809 + if (!from[len]) 2810 + break; 2811 + from += len + 1; 2812 + } 2813 + *to = '\0'; 2814 + return 0; 2815 + } 2816 + 2817 + static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) 2818 + { 2819 + struct selinux_mnt_opts *opts = mnt_opts; 2698 2820 struct superblock_security_struct *sbsec = sb->s_security; 2821 + u32 sid; 2822 + int rc; 2699 2823 2700 2824 if (!(sbsec->flags & SE_SBINITIALIZED)) 2701 2825 return 0; 2702 2826 2703 - if (!data) 2827 + if (!opts) 2704 2828 return 0; 2705 2829 2706 - if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) 2707 - return 0; 2708 - 2709 - security_init_mnt_opts(&opts); 2710 - secdata = alloc_secdata(); 2711 - if (!secdata) 2712 - return -ENOMEM; 2713 - rc = selinux_sb_copy_data(data, secdata); 2714 - if (rc) 2715 - goto out_free_secdata; 2716 - 2717 - rc = selinux_parse_opts_str(secdata, &opts); 2718 - if (rc) 2719 - goto out_free_secdata; 2720 - 2721 - mount_options = opts.mnt_opts; 2722 - flags = opts.mnt_opts_flags; 2723 - 2724 - for (i = 0; i < opts.num_mnt_opts; i++) { 2725 - u32 sid; 2726 - 2727 - if (flags[i] == SBLABEL_MNT) 2728 - continue; 2729 - rc = security_context_str_to_sid(&selinux_state, 2730 - mount_options[i], &sid, 2731 - GFP_KERNEL); 2732 - if (rc) { 2733 - pr_warn("SELinux: security_context_str_to_sid" 2734 - "(%s) failed for (dev %s, type %s) errno=%d\n", 2735 - mount_options[i], sb->s_id, sb->s_type->name, rc); 2736 - goto out_free_opts; 2737 - } 2738 - rc = -EINVAL; 2739 - switch (flags[i]) { 2740 - case FSCONTEXT_MNT: 2741 - if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) 2742 - goto out_bad_option; 2743 - break; 2744 - case CONTEXT_MNT: 2745 - if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) 2746 - goto out_bad_option; 2747 - break; 2748 - case ROOTCONTEXT_MNT: { 2749 - struct inode_security_struct *root_isec; 2750 - root_isec = backing_inode_security(sb->s_root); 2751 - 2752 - if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) 2753 - goto out_bad_option; 2754 - break; 2755 - } 2756 - case DEFCONTEXT_MNT: 2757 - if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) 2758 - goto out_bad_option; 2759 - break; 2760 - default: 2761 - goto out_free_opts; 2762 - } 2830 + if (opts->fscontext) { 2831 + rc = parse_sid(sb, opts->fscontext, &sid); 2832 + if (rc) 2833 + return rc; 2834 + if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) 2835 + goto out_bad_option; 2763 2836 } 2837 + if (opts->context) { 2838 + rc = parse_sid(sb, opts->context, &sid); 2839 + if (rc) 2840 + return rc; 2841 + if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) 2842 + goto out_bad_option; 2843 + } 2844 + if (opts->rootcontext) { 2845 + struct inode_security_struct *root_isec; 2846 + root_isec = backing_inode_security(sb->s_root); 2847 + rc = parse_sid(sb, opts->rootcontext, &sid); 2848 + if (rc) 2849 + return rc; 2850 + if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) 2851 + goto out_bad_option; 2852 + } 2853 + if (opts->defcontext) { 2854 + rc = parse_sid(sb, opts->defcontext, &sid); 2855 + if (rc) 2856 + return rc; 2857 + if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) 2858 + goto out_bad_option; 2859 + } 2860 + return 0; 2764 2861 2765 - rc = 0; 2766 - out_free_opts: 2767 - security_free_mnt_opts(&opts); 2768 - out_free_secdata: 2769 - free_secdata(secdata); 2770 - return rc; 2771 2862 out_bad_option: 2772 2863 pr_warn("SELinux: unable to change security options " 2773 2864 "during remount (dev %s, type=%s)\n", sb->s_id, 2774 2865 sb->s_type->name); 2775 - goto out_free_opts; 2866 + return -EINVAL; 2776 2867 } 2777 2868 2778 - static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) 2869 + static int selinux_sb_kern_mount(struct super_block *sb) 2779 2870 { 2780 2871 const struct cred *cred = current_cred(); 2781 2872 struct common_audit_data ad; 2782 - int rc; 2783 - 2784 - rc = superblock_doinit(sb, data); 2785 - if (rc) 2786 - return rc; 2787 - 2788 - /* Allow all mounts performed by the kernel */ 2789 - if (flags & (MS_KERNMOUNT | MS_SUBMOUNT)) 2790 - return 0; 2791 2873 2792 2874 ad.type = LSM_AUDIT_DATA_DENTRY; 2793 2875 ad.u.dentry = sb->s_root; ··· 6712 6926 6713 6927 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), 6714 6928 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), 6715 - LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data), 6929 + LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), 6930 + LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts), 6716 6931 LSM_HOOK_INIT(sb_remount, selinux_sb_remount), 6717 6932 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), 6718 6933 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options), ··· 6722 6935 LSM_HOOK_INIT(sb_umount, selinux_umount), 6723 6936 LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts), 6724 6937 LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts), 6725 - LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str), 6938 + LSM_HOOK_INIT(sb_add_mnt_opt, selinux_add_mnt_opt), 6726 6939 6727 6940 LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security), 6728 6941 LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as), ··· 6983 7196 6984 7197 static void delayed_superblock_init(struct super_block *sb, void *unused) 6985 7198 { 6986 - superblock_doinit(sb, NULL); 7199 + selinux_set_mnt_opts(sb, NULL, 0, NULL); 6987 7200 } 6988 7201 6989 7202 void selinux_complete_init(void)
+138 -223
security/smack/smack_lsm.c
··· 59 59 static struct kmem_cache *smack_inode_cache; 60 60 int smack_enabled; 61 61 62 - static const match_table_t smk_mount_tokens = { 63 - {Opt_fsdefault, SMK_FSDEFAULT "%s"}, 64 - {Opt_fsfloor, SMK_FSFLOOR "%s"}, 65 - {Opt_fshat, SMK_FSHAT "%s"}, 66 - {Opt_fsroot, SMK_FSROOT "%s"}, 67 - {Opt_fstransmute, SMK_FSTRANS "%s"}, 68 - {Opt_error, NULL}, 62 + #define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s} 63 + static struct { 64 + const char *name; 65 + int len; 66 + int opt; 67 + } smk_mount_opts[] = { 68 + A(fsdefault), A(fsfloor), A(fshat), A(fsroot), A(fstransmute) 69 69 }; 70 + #undef A 71 + 72 + static int match_opt_prefix(char *s, int l, char **arg) 73 + { 74 + int i; 75 + 76 + for (i = 0; i < ARRAY_SIZE(smk_mount_opts); i++) { 77 + size_t len = smk_mount_opts[i].len; 78 + if (len > l || memcmp(s, smk_mount_opts[i].name, len)) 79 + continue; 80 + if (len == l || s[len] != '=') 81 + continue; 82 + *arg = s + len + 1; 83 + return smk_mount_opts[i].opt; 84 + } 85 + return Opt_error; 86 + } 70 87 71 88 #ifdef CONFIG_SECURITY_SMACK_BRINGUP 72 89 static char *smk_bu_mess[] = { ··· 584 567 sb->s_security = NULL; 585 568 } 586 569 587 - /** 588 - * smack_sb_copy_data - copy mount options data for processing 589 - * @orig: where to start 590 - * @smackopts: mount options string 591 - * 592 - * Returns 0 on success or -ENOMEM on error. 593 - * 594 - * Copy the Smack specific mount options out of the mount 595 - * options list. 596 - */ 597 - static int smack_sb_copy_data(char *orig, char *smackopts) 570 + struct smack_mnt_opts { 571 + const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute; 572 + }; 573 + 574 + static void smack_free_mnt_opts(void *mnt_opts) 598 575 { 599 - char *cp, *commap, *otheropts, *dp; 600 - 601 - otheropts = (char *)get_zeroed_page(GFP_KERNEL); 602 - if (otheropts == NULL) 603 - return -ENOMEM; 604 - 605 - for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) { 606 - if (strstr(cp, SMK_FSDEFAULT) == cp) 607 - dp = smackopts; 608 - else if (strstr(cp, SMK_FSFLOOR) == cp) 609 - dp = smackopts; 610 - else if (strstr(cp, SMK_FSHAT) == cp) 611 - dp = smackopts; 612 - else if (strstr(cp, SMK_FSROOT) == cp) 613 - dp = smackopts; 614 - else if (strstr(cp, SMK_FSTRANS) == cp) 615 - dp = smackopts; 616 - else 617 - dp = otheropts; 618 - 619 - commap = strchr(cp, ','); 620 - if (commap != NULL) 621 - *commap = '\0'; 622 - 623 - if (*dp != '\0') 624 - strcat(dp, ","); 625 - strcat(dp, cp); 626 - } 627 - 628 - strcpy(orig, otheropts); 629 - free_page((unsigned long)otheropts); 630 - 631 - return 0; 576 + struct smack_mnt_opts *opts = mnt_opts; 577 + kfree(opts->fsdefault); 578 + kfree(opts->fsfloor); 579 + kfree(opts->fshat); 580 + kfree(opts->fsroot); 581 + kfree(opts->fstransmute); 582 + kfree(opts); 632 583 } 633 584 634 - /** 635 - * smack_parse_opts_str - parse Smack specific mount options 636 - * @options: mount options string 637 - * @opts: where to store converted mount opts 638 - * 639 - * Returns 0 on success or -ENOMEM on error. 640 - * 641 - * converts Smack specific mount options to generic security option format 642 - */ 643 - static int smack_parse_opts_str(char *options, 644 - struct security_mnt_opts *opts) 585 + static int smack_add_opt(int token, const char *s, void **mnt_opts) 645 586 { 646 - char *p; 647 - char *fsdefault = NULL; 648 - char *fsfloor = NULL; 649 - char *fshat = NULL; 650 - char *fsroot = NULL; 651 - char *fstransmute = NULL; 652 - int rc = -ENOMEM; 653 - int num_mnt_opts = 0; 654 - int token; 587 + struct smack_mnt_opts *opts = *mnt_opts; 655 588 656 - opts->num_mnt_opts = 0; 657 - 658 - if (!options) 659 - return 0; 660 - 661 - while ((p = strsep(&options, ",")) != NULL) { 662 - substring_t args[MAX_OPT_ARGS]; 663 - 664 - if (!*p) 665 - continue; 666 - 667 - token = match_token(p, smk_mount_tokens, args); 668 - 669 - switch (token) { 670 - case Opt_fsdefault: 671 - if (fsdefault) 672 - goto out_opt_err; 673 - fsdefault = match_strdup(&args[0]); 674 - if (!fsdefault) 675 - goto out_err; 676 - break; 677 - case Opt_fsfloor: 678 - if (fsfloor) 679 - goto out_opt_err; 680 - fsfloor = match_strdup(&args[0]); 681 - if (!fsfloor) 682 - goto out_err; 683 - break; 684 - case Opt_fshat: 685 - if (fshat) 686 - goto out_opt_err; 687 - fshat = match_strdup(&args[0]); 688 - if (!fshat) 689 - goto out_err; 690 - break; 691 - case Opt_fsroot: 692 - if (fsroot) 693 - goto out_opt_err; 694 - fsroot = match_strdup(&args[0]); 695 - if (!fsroot) 696 - goto out_err; 697 - break; 698 - case Opt_fstransmute: 699 - if (fstransmute) 700 - goto out_opt_err; 701 - fstransmute = match_strdup(&args[0]); 702 - if (!fstransmute) 703 - goto out_err; 704 - break; 705 - default: 706 - rc = -EINVAL; 707 - pr_warn("Smack: unknown mount option\n"); 708 - goto out_err; 709 - } 589 + if (!opts) { 590 + opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); 591 + if (!opts) 592 + return -ENOMEM; 593 + *mnt_opts = opts; 710 594 } 595 + if (!s) 596 + return -ENOMEM; 711 597 712 - opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_KERNEL); 713 - if (!opts->mnt_opts) 714 - goto out_err; 715 - 716 - opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int), 717 - GFP_KERNEL); 718 - if (!opts->mnt_opts_flags) 719 - goto out_err; 720 - 721 - if (fsdefault) { 722 - opts->mnt_opts[num_mnt_opts] = fsdefault; 723 - opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT; 598 + switch (token) { 599 + case Opt_fsdefault: 600 + if (opts->fsdefault) 601 + goto out_opt_err; 602 + opts->fsdefault = s; 603 + break; 604 + case Opt_fsfloor: 605 + if (opts->fsfloor) 606 + goto out_opt_err; 607 + opts->fsfloor = s; 608 + break; 609 + case Opt_fshat: 610 + if (opts->fshat) 611 + goto out_opt_err; 612 + opts->fshat = s; 613 + break; 614 + case Opt_fsroot: 615 + if (opts->fsroot) 616 + goto out_opt_err; 617 + opts->fsroot = s; 618 + break; 619 + case Opt_fstransmute: 620 + if (opts->fstransmute) 621 + goto out_opt_err; 622 + opts->fstransmute = s; 623 + break; 724 624 } 725 - if (fsfloor) { 726 - opts->mnt_opts[num_mnt_opts] = fsfloor; 727 - opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT; 728 - } 729 - if (fshat) { 730 - opts->mnt_opts[num_mnt_opts] = fshat; 731 - opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT; 732 - } 733 - if (fsroot) { 734 - opts->mnt_opts[num_mnt_opts] = fsroot; 735 - opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT; 736 - } 737 - if (fstransmute) { 738 - opts->mnt_opts[num_mnt_opts] = fstransmute; 739 - opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT; 740 - } 741 - 742 - opts->num_mnt_opts = num_mnt_opts; 743 625 return 0; 744 626 745 627 out_opt_err: 746 - rc = -EINVAL; 747 628 pr_warn("Smack: duplicate mount options\n"); 629 + return -EINVAL; 630 + } 748 631 749 - out_err: 750 - kfree(fsdefault); 751 - kfree(fsfloor); 752 - kfree(fshat); 753 - kfree(fsroot); 754 - kfree(fstransmute); 755 - return rc; 632 + static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) 633 + { 634 + char *from = options, *to = options; 635 + bool first = true; 636 + 637 + while (1) { 638 + char *next = strchr(from, ','); 639 + int token, len, rc; 640 + char *arg = NULL; 641 + 642 + if (next) 643 + len = next - from; 644 + else 645 + len = strlen(from); 646 + 647 + token = match_opt_prefix(from, len, &arg); 648 + if (token != Opt_error) { 649 + arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL); 650 + rc = smack_add_opt(token, arg, mnt_opts); 651 + if (unlikely(rc)) { 652 + kfree(arg); 653 + if (*mnt_opts) 654 + smack_free_mnt_opts(*mnt_opts); 655 + *mnt_opts = NULL; 656 + return rc; 657 + } 658 + } else { 659 + if (!first) { // copy with preceding comma 660 + from--; 661 + len++; 662 + } 663 + if (to != from) 664 + memmove(to, from, len); 665 + to += len; 666 + first = false; 667 + } 668 + if (!from[len]) 669 + break; 670 + from += len + 1; 671 + } 672 + *to = '\0'; 673 + return 0; 756 674 } 757 675 758 676 /** ··· 703 751 * labels. 704 752 */ 705 753 static int smack_set_mnt_opts(struct super_block *sb, 706 - struct security_mnt_opts *opts, 754 + void *mnt_opts, 707 755 unsigned long kern_flags, 708 756 unsigned long *set_kern_flags) 709 757 { ··· 712 760 struct superblock_smack *sp = sb->s_security; 713 761 struct inode_smack *isp; 714 762 struct smack_known *skp; 715 - int i; 716 - int num_opts = opts->num_mnt_opts; 717 - int transmute = 0; 763 + struct smack_mnt_opts *opts = mnt_opts; 764 + bool transmute = false; 718 765 719 766 if (sp->smk_flags & SMK_SB_INITIALIZED) 720 767 return 0; ··· 722 771 /* 723 772 * Unprivileged mounts don't get to specify Smack values. 724 773 */ 725 - if (num_opts) 774 + if (opts) 726 775 return -EPERM; 727 776 /* 728 777 * Unprivileged mounts get root and default from the caller. ··· 738 787 if (sb->s_user_ns != &init_user_ns && 739 788 sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC && 740 789 sb->s_magic != RAMFS_MAGIC) { 741 - transmute = 1; 790 + transmute = true; 742 791 sp->smk_flags |= SMK_SB_UNTRUSTED; 743 792 } 744 793 } 745 794 746 795 sp->smk_flags |= SMK_SB_INITIALIZED; 747 796 748 - for (i = 0; i < num_opts; i++) { 749 - switch (opts->mnt_opts_flags[i]) { 750 - case FSDEFAULT_MNT: 751 - skp = smk_import_entry(opts->mnt_opts[i], 0); 797 + if (opts) { 798 + if (opts->fsdefault) { 799 + skp = smk_import_entry(opts->fsdefault, 0); 752 800 if (IS_ERR(skp)) 753 801 return PTR_ERR(skp); 754 802 sp->smk_default = skp; 755 - break; 756 - case FSFLOOR_MNT: 757 - skp = smk_import_entry(opts->mnt_opts[i], 0); 803 + } 804 + if (opts->fsfloor) { 805 + skp = smk_import_entry(opts->fsfloor, 0); 758 806 if (IS_ERR(skp)) 759 807 return PTR_ERR(skp); 760 808 sp->smk_floor = skp; 761 - break; 762 - case FSHAT_MNT: 763 - skp = smk_import_entry(opts->mnt_opts[i], 0); 809 + } 810 + if (opts->fshat) { 811 + skp = smk_import_entry(opts->fshat, 0); 764 812 if (IS_ERR(skp)) 765 813 return PTR_ERR(skp); 766 814 sp->smk_hat = skp; 767 - break; 768 - case FSROOT_MNT: 769 - skp = smk_import_entry(opts->mnt_opts[i], 0); 815 + } 816 + if (opts->fsroot) { 817 + skp = smk_import_entry(opts->fsroot, 0); 770 818 if (IS_ERR(skp)) 771 819 return PTR_ERR(skp); 772 820 sp->smk_root = skp; 773 - break; 774 - case FSTRANS_MNT: 775 - skp = smk_import_entry(opts->mnt_opts[i], 0); 821 + } 822 + if (opts->fstransmute) { 823 + skp = smk_import_entry(opts->fstransmute, 0); 776 824 if (IS_ERR(skp)) 777 825 return PTR_ERR(skp); 778 826 sp->smk_root = skp; 779 - transmute = 1; 780 - break; 781 - default: 782 - break; 827 + transmute = true; 783 828 } 784 829 } 785 830 ··· 795 848 isp->smk_flags |= SMK_INODE_TRANSMUTE; 796 849 797 850 return 0; 798 - } 799 - 800 - /** 801 - * smack_sb_kern_mount - Smack specific mount processing 802 - * @sb: the file system superblock 803 - * @flags: the mount flags 804 - * @data: the smack mount options 805 - * 806 - * Returns 0 on success, an error code on failure 807 - */ 808 - static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) 809 - { 810 - int rc = 0; 811 - char *options = data; 812 - struct security_mnt_opts opts; 813 - 814 - security_init_mnt_opts(&opts); 815 - 816 - if (!options) 817 - goto out; 818 - 819 - rc = smack_parse_opts_str(options, &opts); 820 - if (rc) 821 - goto out_err; 822 - 823 - out: 824 - rc = smack_set_mnt_opts(sb, &opts, 0, NULL); 825 - 826 - out_err: 827 - security_free_mnt_opts(&opts); 828 - return rc; 829 851 } 830 852 831 853 /** ··· 4589 4673 4590 4674 LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security), 4591 4675 LSM_HOOK_INIT(sb_free_security, smack_sb_free_security), 4592 - LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data), 4593 - LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount), 4676 + LSM_HOOK_INIT(sb_free_mnt_opts, smack_free_mnt_opts), 4677 + LSM_HOOK_INIT(sb_eat_lsm_opts, smack_sb_eat_lsm_opts), 4594 4678 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs), 4595 4679 LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts), 4596 - LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str), 4597 4680 4598 4681 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), 4599 4682
+1
security/tomoyo/mount.c
··· 6 6 */ 7 7 8 8 #include <linux/slab.h> 9 + #include <uapi/linux/mount.h> 9 10 #include "common.h" 10 11 11 12 /* String table for special mount operations. */