diff options
| -rw-r--r-- | security/selinux/hooks.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3decf07b8dc1..f2f3cf2e806d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -2363,6 +2363,91 @@ out: | |||
| 2363 | return rc; | 2363 | return rc; |
| 2364 | } | 2364 | } |
| 2365 | 2365 | ||
| 2366 | static int selinux_sb_remount(struct super_block *sb, void *data) | ||
| 2367 | { | ||
| 2368 | int rc, i, *flags; | ||
| 2369 | struct security_mnt_opts opts; | ||
| 2370 | char *secdata, **mount_options; | ||
| 2371 | struct superblock_security_struct *sbsec = sb->s_security; | ||
| 2372 | |||
| 2373 | if (!(sbsec->flags & SE_SBINITIALIZED)) | ||
| 2374 | return 0; | ||
| 2375 | |||
| 2376 | if (!data) | ||
| 2377 | return 0; | ||
| 2378 | |||
| 2379 | if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | ||
| 2380 | return 0; | ||
| 2381 | |||
| 2382 | security_init_mnt_opts(&opts); | ||
| 2383 | secdata = alloc_secdata(); | ||
| 2384 | if (!secdata) | ||
| 2385 | return -ENOMEM; | ||
| 2386 | rc = selinux_sb_copy_data(data, secdata); | ||
| 2387 | if (rc) | ||
| 2388 | goto out_free_secdata; | ||
| 2389 | |||
| 2390 | rc = selinux_parse_opts_str(secdata, &opts); | ||
| 2391 | if (rc) | ||
| 2392 | goto out_free_secdata; | ||
| 2393 | |||
| 2394 | mount_options = opts.mnt_opts; | ||
| 2395 | flags = opts.mnt_opts_flags; | ||
| 2396 | |||
| 2397 | for (i = 0; i < opts.num_mnt_opts; i++) { | ||
| 2398 | u32 sid; | ||
| 2399 | size_t len; | ||
| 2400 | |||
| 2401 | if (flags[i] == SE_SBLABELSUPP) | ||
| 2402 | continue; | ||
| 2403 | len = strlen(mount_options[i]); | ||
| 2404 | rc = security_context_to_sid(mount_options[i], len, &sid); | ||
| 2405 | if (rc) { | ||
| 2406 | printk(KERN_WARNING "SELinux: security_context_to_sid" | ||
| 2407 | "(%s) failed for (dev %s, type %s) errno=%d\n", | ||
| 2408 | mount_options[i], sb->s_id, sb->s_type->name, rc); | ||
| 2409 | goto out_free_opts; | ||
| 2410 | } | ||
| 2411 | rc = -EINVAL; | ||
| 2412 | switch (flags[i]) { | ||
| 2413 | case FSCONTEXT_MNT: | ||
| 2414 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) | ||
| 2415 | goto out_bad_option; | ||
| 2416 | break; | ||
| 2417 | case CONTEXT_MNT: | ||
| 2418 | if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) | ||
| 2419 | goto out_bad_option; | ||
| 2420 | break; | ||
| 2421 | case ROOTCONTEXT_MNT: { | ||
| 2422 | struct inode_security_struct *root_isec; | ||
| 2423 | root_isec = sb->s_root->d_inode->i_security; | ||
| 2424 | |||
| 2425 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) | ||
| 2426 | goto out_bad_option; | ||
| 2427 | break; | ||
| 2428 | } | ||
| 2429 | case DEFCONTEXT_MNT: | ||
| 2430 | if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) | ||
| 2431 | goto out_bad_option; | ||
| 2432 | break; | ||
| 2433 | default: | ||
| 2434 | goto out_free_opts; | ||
| 2435 | } | ||
| 2436 | } | ||
| 2437 | |||
| 2438 | rc = 0; | ||
| 2439 | out_free_opts: | ||
| 2440 | security_free_mnt_opts(&opts); | ||
| 2441 | out_free_secdata: | ||
| 2442 | free_secdata(secdata); | ||
| 2443 | return rc; | ||
| 2444 | out_bad_option: | ||
| 2445 | printk(KERN_WARNING "SELinux: unable to change security options " | ||
| 2446 | "during remount (dev %s, type=%s)\n", sb->s_id, | ||
| 2447 | sb->s_type->name); | ||
| 2448 | goto out_free_opts; | ||
| 2449 | } | ||
| 2450 | |||
| 2366 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | 2451 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 2367 | { | 2452 | { |
| 2368 | const struct cred *cred = current_cred(); | 2453 | const struct cred *cred = current_cred(); |
| @@ -5356,6 +5441,7 @@ static struct security_operations selinux_ops = { | |||
| 5356 | .sb_alloc_security = selinux_sb_alloc_security, | 5441 | .sb_alloc_security = selinux_sb_alloc_security, |
| 5357 | .sb_free_security = selinux_sb_free_security, | 5442 | .sb_free_security = selinux_sb_free_security, |
| 5358 | .sb_copy_data = selinux_sb_copy_data, | 5443 | .sb_copy_data = selinux_sb_copy_data, |
| 5444 | .sb_remount = selinux_sb_remount, | ||
| 5359 | .sb_kern_mount = selinux_sb_kern_mount, | 5445 | .sb_kern_mount = selinux_sb_kern_mount, |
| 5360 | .sb_show_options = selinux_sb_show_options, | 5446 | .sb_show_options = selinux_sb_show_options, |
| 5361 | .sb_statfs = selinux_sb_statfs, | 5447 | .sb_statfs = selinux_sb_statfs, |
