aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c86
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
2366static 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;
2439out_free_opts:
2440 security_free_mnt_opts(&opts);
2441out_free_secdata:
2442 free_secdata(secdata);
2443 return rc;
2444out_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
2366static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) 2451static 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,