aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_lsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r--security/smack/smack_lsm.c145
1 files changed, 69 insertions, 76 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index b0be893ad44d..14f52be78c75 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
219 * smack_syslog - Smack approval on syslog 219 * smack_syslog - Smack approval on syslog
220 * @type: message type 220 * @type: message type
221 * 221 *
222 * Require that the task has the floor label
223 *
224 * Returns 0 on success, error code otherwise. 222 * Returns 0 on success, error code otherwise.
225 */ 223 */
226static int smack_syslog(int typefrom_file) 224static int smack_syslog(int typefrom_file)
@@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file)
231 if (smack_privileged(CAP_MAC_OVERRIDE)) 229 if (smack_privileged(CAP_MAC_OVERRIDE))
232 return 0; 230 return 0;
233 231
234 if (skp != &smack_known_floor) 232 if (smack_syslog_label != NULL && smack_syslog_label != skp)
235 rc = -EACCES; 233 rc = -EACCES;
236 234
237 return rc; 235 return rc;
@@ -341,10 +339,12 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
341 struct inode *inode = root->d_inode; 339 struct inode *inode = root->d_inode;
342 struct superblock_smack *sp = sb->s_security; 340 struct superblock_smack *sp = sb->s_security;
343 struct inode_smack *isp; 341 struct inode_smack *isp;
342 struct smack_known *skp;
344 char *op; 343 char *op;
345 char *commap; 344 char *commap;
346 char *nsp; 345 char *nsp;
347 int transmute = 0; 346 int transmute = 0;
347 int specified = 0;
348 348
349 if (sp->smk_initialized) 349 if (sp->smk_initialized)
350 return 0; 350 return 0;
@@ -359,34 +359,56 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
359 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { 359 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
360 op += strlen(SMK_FSHAT); 360 op += strlen(SMK_FSHAT);
361 nsp = smk_import(op, 0); 361 nsp = smk_import(op, 0);
362 if (nsp != NULL) 362 if (nsp != NULL) {
363 sp->smk_hat = nsp; 363 sp->smk_hat = nsp;
364 specified = 1;
365 }
364 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { 366 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
365 op += strlen(SMK_FSFLOOR); 367 op += strlen(SMK_FSFLOOR);
366 nsp = smk_import(op, 0); 368 nsp = smk_import(op, 0);
367 if (nsp != NULL) 369 if (nsp != NULL) {
368 sp->smk_floor = nsp; 370 sp->smk_floor = nsp;
371 specified = 1;
372 }
369 } else if (strncmp(op, SMK_FSDEFAULT, 373 } else if (strncmp(op, SMK_FSDEFAULT,
370 strlen(SMK_FSDEFAULT)) == 0) { 374 strlen(SMK_FSDEFAULT)) == 0) {
371 op += strlen(SMK_FSDEFAULT); 375 op += strlen(SMK_FSDEFAULT);
372 nsp = smk_import(op, 0); 376 nsp = smk_import(op, 0);
373 if (nsp != NULL) 377 if (nsp != NULL) {
374 sp->smk_default = nsp; 378 sp->smk_default = nsp;
379 specified = 1;
380 }
375 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { 381 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
376 op += strlen(SMK_FSROOT); 382 op += strlen(SMK_FSROOT);
377 nsp = smk_import(op, 0); 383 nsp = smk_import(op, 0);
378 if (nsp != NULL) 384 if (nsp != NULL) {
379 sp->smk_root = nsp; 385 sp->smk_root = nsp;
386 specified = 1;
387 }
380 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { 388 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
381 op += strlen(SMK_FSTRANS); 389 op += strlen(SMK_FSTRANS);
382 nsp = smk_import(op, 0); 390 nsp = smk_import(op, 0);
383 if (nsp != NULL) { 391 if (nsp != NULL) {
384 sp->smk_root = nsp; 392 sp->smk_root = nsp;
385 transmute = 1; 393 transmute = 1;
394 specified = 1;
386 } 395 }
387 } 396 }
388 } 397 }
389 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 }
390 /* 412 /*
391 * Initialize the root inode. 413 * Initialize the root inode.
392 */ 414 */
@@ -423,53 +445,6 @@ static int smack_sb_statfs(struct dentry *dentry)
423 return rc; 445 return rc;
424} 446}
425 447
426/**
427 * smack_sb_mount - Smack check for mounting
428 * @dev_name: unused
429 * @path: mount point
430 * @type: unused
431 * @flags: unused
432 * @data: unused
433 *
434 * Returns 0 if current can write the floor of the filesystem
435 * being mounted on, an error code otherwise.
436 */
437static int smack_sb_mount(const char *dev_name, struct path *path,
438 const char *type, unsigned long flags, void *data)
439{
440 struct superblock_smack *sbp = path->dentry->d_sb->s_security;
441 struct smk_audit_info ad;
442
443 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
444 smk_ad_setfield_u_fs_path(&ad, *path);
445
446 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
447}
448
449/**
450 * smack_sb_umount - Smack check for unmounting
451 * @mnt: file system to unmount
452 * @flags: unused
453 *
454 * Returns 0 if current can write the floor of the filesystem
455 * being unmounted, an error code otherwise.
456 */
457static int smack_sb_umount(struct vfsmount *mnt, int flags)
458{
459 struct superblock_smack *sbp;
460 struct smk_audit_info ad;
461 struct path path;
462
463 path.dentry = mnt->mnt_root;
464 path.mnt = mnt;
465
466 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
467 smk_ad_setfield_u_fs_path(&ad, path);
468
469 sbp = path.dentry->d_sb->s_security;
470 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
471}
472
473/* 448/*
474 * BPRM hooks 449 * BPRM hooks
475 */ 450 */
@@ -837,31 +812,43 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
837 const void *value, size_t size, int flags) 812 const void *value, size_t size, int flags)
838{ 813{
839 struct smk_audit_info ad; 814 struct smk_audit_info ad;
815 struct smack_known *skp;
816 int check_priv = 0;
817 int check_import = 0;
818 int check_star = 0;
840 int rc = 0; 819 int rc = 0;
841 820
821 /*
822 * Check label validity here so import won't fail in post_setxattr
823 */
842 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 824 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
843 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 825 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
844 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 826 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
845 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 827 check_priv = 1;
846 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 828 check_import = 1;
847 if (!smack_privileged(CAP_MAC_ADMIN)) 829 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
848 rc = -EPERM; 830 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
849 /* 831 check_priv = 1;
850 * check label validity here so import wont fail on 832 check_import = 1;
851 * post_setxattr 833 check_star = 1;
852 */
853 if (size == 0 || size >= SMK_LONGLABEL ||
854 smk_import(value, size) == NULL)
855 rc = -EINVAL;
856 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { 834 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
857 if (!smack_privileged(CAP_MAC_ADMIN)) 835 check_priv = 1;
858 rc = -EPERM;
859 if (size != TRANS_TRUE_SIZE || 836 if (size != TRANS_TRUE_SIZE ||
860 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) 837 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
861 rc = -EINVAL; 838 rc = -EINVAL;
862 } else 839 } else
863 rc = cap_inode_setxattr(dentry, name, value, size, flags); 840 rc = cap_inode_setxattr(dentry, name, value, size, flags);
864 841
842 if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
843 rc = -EPERM;
844
845 if (rc == 0 && check_import) {
846 skp = smk_import_entry(value, size);
847 if (skp == NULL || (check_star &&
848 (skp == &smack_known_star || skp == &smack_known_web)))
849 rc = -EINVAL;
850 }
851
865 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); 852 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
866 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 853 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
867 854
@@ -1364,7 +1351,7 @@ static int smack_file_receive(struct file *file)
1364 int may = 0; 1351 int may = 0;
1365 struct smk_audit_info ad; 1352 struct smk_audit_info ad;
1366 1353
1367 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1354 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1368 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1355 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1369 /* 1356 /*
1370 * This code relies on bitmasks. 1357 * This code relies on bitmasks.
@@ -2847,8 +2834,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2847 if (rc >= 0) 2834 if (rc >= 0)
2848 transflag = SMK_INODE_TRANSMUTE; 2835 transflag = SMK_INODE_TRANSMUTE;
2849 } 2836 }
2850 isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); 2837 /*
2851 isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); 2838 * Don't let the exec or mmap label be "*" or "@".
2839 */
2840 skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
2841 if (skp == &smack_known_star || skp == &smack_known_web)
2842 skp = NULL;
2843 isp->smk_task = skp;
2844 skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
2845 if (skp == &smack_known_star || skp == &smack_known_web)
2846 skp = NULL;
2847 isp->smk_mmap = skp;
2852 2848
2853 dput(dp); 2849 dput(dp);
2854 break; 2850 break;
@@ -3620,9 +3616,8 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3620 struct smack_known *skp; 3616 struct smack_known *skp;
3621 char *rule = vrule; 3617 char *rule = vrule;
3622 3618
3623 if (!rule) { 3619 if (unlikely(!rule)) {
3624 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 3620 WARN_ONCE(1, "Smack: missing rule\n");
3625 "Smack: missing rule\n");
3626 return -ENOENT; 3621 return -ENOENT;
3627 } 3622 }
3628 3623
@@ -3743,8 +3738,6 @@ struct security_operations smack_ops = {
3743 .sb_copy_data = smack_sb_copy_data, 3738 .sb_copy_data = smack_sb_copy_data,
3744 .sb_kern_mount = smack_sb_kern_mount, 3739 .sb_kern_mount = smack_sb_kern_mount,
3745 .sb_statfs = smack_sb_statfs, 3740 .sb_statfs = smack_sb_statfs,
3746 .sb_mount = smack_sb_mount,
3747 .sb_umount = smack_sb_umount,
3748 3741
3749 .bprm_set_creds = smack_bprm_set_creds, 3742 .bprm_set_creds = smack_bprm_set_creds,
3750 .bprm_committing_creds = smack_bprm_committing_creds, 3743 .bprm_committing_creds = smack_bprm_committing_creds,