aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2013-12-30 12:38:00 -0500
committerCasey Schaufler <casey@schaufler-ca.com>2013-12-31 16:35:16 -0500
commit24ea1b6efcd8fc3b465fb74964e1a0cbe9979730 (patch)
treebb45d3814997cbfe99a72fa9c874b752fcd6b83a /security/smack
parent4afde48be8929b6da63a9e977aaff0894ba82984 (diff)
Smack: Rationalize mount restrictions
The mount restrictions imposed by Smack rely heavily on the use of the filesystem "floor", which is the label that all processes writing to the filesystem must have access to. It turns out that while the "floor" notion is sound, it has yet to be fully implemented and has never been used. The sb_mount and sb_umount hooks only make sense if the filesystem floor is used actively, and it isn't. They can be reintroduced if a rational restriction comes up. Until then, they get removed. The sb_kern_mount hook is required for the option processing. It is too permissive in the case of unprivileged mounts, effectively bypassing the CAP_MAC_ADMIN restrictions if any of the smack options are specified. Unprivileged mounts are no longer allowed to set Smack filesystem options. Additionally, the root and default values are set to the label of the caller, in keeping with the policy that objects get the label of their creator. Targeted for git://git.gitorious.org/smack-next/kernel.git Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack_lsm.c83
1 files changed, 29 insertions, 54 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 67b7381d0244..d5528324a637 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -229,7 +229,7 @@ static int smack_syslog(int typefrom_file)
229 if (smack_privileged(CAP_MAC_OVERRIDE)) 229 if (smack_privileged(CAP_MAC_OVERRIDE))
230 return 0; 230 return 0;
231 231
232 if (smack_syslog_label != NULL && smack_syslog_label != skp) 232 if (smack_syslog_label != NULL && smack_syslog_label != skp)
233 rc = -EACCES; 233 rc = -EACCES;
234 234
235 return rc; 235 return rc;
@@ -339,10 +339,12 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
339 struct inode *inode = root->d_inode; 339 struct inode *inode = root->d_inode;
340 struct superblock_smack *sp = sb->s_security; 340 struct superblock_smack *sp = sb->s_security;
341 struct inode_smack *isp; 341 struct inode_smack *isp;
342 struct smack_known *skp;
342 char *op; 343 char *op;
343 char *commap; 344 char *commap;
344 char *nsp; 345 char *nsp;
345 int transmute = 0; 346 int transmute = 0;
347 int specified = 0;
346 348
347 if (sp->smk_initialized) 349 if (sp->smk_initialized)
348 return 0; 350 return 0;
@@ -357,34 +359,56 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
357 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { 359 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
358 op += strlen(SMK_FSHAT); 360 op += strlen(SMK_FSHAT);
359 nsp = smk_import(op, 0); 361 nsp = smk_import(op, 0);
360 if (nsp != NULL) 362 if (nsp != NULL) {
361 sp->smk_hat = nsp; 363 sp->smk_hat = nsp;
364 specified = 1;
365 }
362 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { 366 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
363 op += strlen(SMK_FSFLOOR); 367 op += strlen(SMK_FSFLOOR);
364 nsp = smk_import(op, 0); 368 nsp = smk_import(op, 0);
365 if (nsp != NULL) 369 if (nsp != NULL) {
366 sp->smk_floor = nsp; 370 sp->smk_floor = nsp;
371 specified = 1;
372 }
367 } else if (strncmp(op, SMK_FSDEFAULT, 373 } else if (strncmp(op, SMK_FSDEFAULT,
368 strlen(SMK_FSDEFAULT)) == 0) { 374 strlen(SMK_FSDEFAULT)) == 0) {
369 op += strlen(SMK_FSDEFAULT); 375 op += strlen(SMK_FSDEFAULT);
370 nsp = smk_import(op, 0); 376 nsp = smk_import(op, 0);
371 if (nsp != NULL) 377 if (nsp != NULL) {
372 sp->smk_default = nsp; 378 sp->smk_default = nsp;
379 specified = 1;
380 }
373 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { 381 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
374 op += strlen(SMK_FSROOT); 382 op += strlen(SMK_FSROOT);
375 nsp = smk_import(op, 0); 383 nsp = smk_import(op, 0);
376 if (nsp != NULL) 384 if (nsp != NULL) {
377 sp->smk_root = nsp; 385 sp->smk_root = nsp;
386 specified = 1;
387 }
378 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { 388 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
379 op += strlen(SMK_FSTRANS); 389 op += strlen(SMK_FSTRANS);
380 nsp = smk_import(op, 0); 390 nsp = smk_import(op, 0);
381 if (nsp != NULL) { 391 if (nsp != NULL) {
382 sp->smk_root = nsp; 392 sp->smk_root = nsp;
383 transmute = 1; 393 transmute = 1;
394 specified = 1;
384 } 395 }
385 } 396 }
386 } 397 }
387 398
399 if (!smack_privileged(CAP_MAC_ADMIN)) {
400 /*
401 * Unprivileged mounts don't get to specify Smack values.
402 */
403 if (specified)
404 return -EPERM;
405 /*
406 * Unprivileged mounts get root and default from the caller.
407 */
408 skp = smk_of_current();
409 sp->smk_root = skp->smk_known;
410 sp->smk_default = skp->smk_known;
411 }
388 /* 412 /*
389 * Initialize the root inode. 413 * Initialize the root inode.
390 */ 414 */
@@ -421,53 +445,6 @@ static int smack_sb_statfs(struct dentry *dentry)
421 return rc; 445 return rc;
422} 446}
423 447
424/**
425 * smack_sb_mount - Smack check for mounting
426 * @dev_name: unused
427 * @path: mount point
428 * @type: unused
429 * @flags: unused
430 * @data: unused
431 *
432 * Returns 0 if current can write the floor of the filesystem
433 * being mounted on, an error code otherwise.
434 */
435static int smack_sb_mount(const char *dev_name, struct path *path,
436 const char *type, unsigned long flags, void *data)
437{
438 struct superblock_smack *sbp = path->dentry->d_sb->s_security;
439 struct smk_audit_info ad;
440
441 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
442 smk_ad_setfield_u_fs_path(&ad, *path);
443
444 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
445}
446
447/**
448 * smack_sb_umount - Smack check for unmounting
449 * @mnt: file system to unmount
450 * @flags: unused
451 *
452 * Returns 0 if current can write the floor of the filesystem
453 * being unmounted, an error code otherwise.
454 */
455static int smack_sb_umount(struct vfsmount *mnt, int flags)
456{
457 struct superblock_smack *sbp;
458 struct smk_audit_info ad;
459 struct path path;
460
461 path.dentry = mnt->mnt_root;
462 path.mnt = mnt;
463
464 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
465 smk_ad_setfield_u_fs_path(&ad, path);
466
467 sbp = path.dentry->d_sb->s_security;
468 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
469}
470
471/* 448/*
472 * BPRM hooks 449 * BPRM hooks
473 */ 450 */
@@ -3762,8 +3739,6 @@ struct security_operations smack_ops = {
3762 .sb_copy_data = smack_sb_copy_data, 3739 .sb_copy_data = smack_sb_copy_data,
3763 .sb_kern_mount = smack_sb_kern_mount, 3740 .sb_kern_mount = smack_sb_kern_mount,
3764 .sb_statfs = smack_sb_statfs, 3741 .sb_statfs = smack_sb_statfs,
3765 .sb_mount = smack_sb_mount,
3766 .sb_umount = smack_sb_umount,
3767 3742
3768 .bprm_set_creds = smack_bprm_set_creds, 3743 .bprm_set_creds = smack_bprm_set_creds,
3769 .bprm_committing_creds = smack_bprm_committing_creds, 3744 .bprm_committing_creds = smack_bprm_committing_creds,