diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 45c32f074166..df45d3939188 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -556,6 +556,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, | |||
556 | void **value, size_t *len) | 556 | void **value, size_t *len) |
557 | { | 557 | { |
558 | struct smack_known *skp; | 558 | struct smack_known *skp; |
559 | struct inode_smack *issp = inode->i_security; | ||
559 | char *csp = smk_of_current(); | 560 | char *csp = smk_of_current(); |
560 | char *isp = smk_of_inode(inode); | 561 | char *isp = smk_of_inode(inode); |
561 | char *dsp = smk_of_inode(dir); | 562 | char *dsp = smk_of_inode(dir); |
@@ -577,10 +578,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, | |||
577 | * If the access rule allows transmutation and | 578 | * If the access rule allows transmutation and |
578 | * the directory requests transmutation then | 579 | * the directory requests transmutation then |
579 | * by all means transmute. | 580 | * by all means transmute. |
581 | * Mark the inode as changed. | ||
580 | */ | 582 | */ |
581 | if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && | 583 | if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && |
582 | smk_inode_transmutable(dir)) | 584 | smk_inode_transmutable(dir)) { |
583 | isp = dsp; | 585 | isp = dsp; |
586 | issp->smk_flags |= SMK_INODE_CHANGED; | ||
587 | } | ||
584 | 588 | ||
585 | *value = kstrdup(isp, GFP_KERNEL); | 589 | *value = kstrdup(isp, GFP_KERNEL); |
586 | if (*value == NULL) | 590 | if (*value == NULL) |
@@ -2552,6 +2556,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
2552 | char *final; | 2556 | char *final; |
2553 | char trattr[TRANS_TRUE_SIZE]; | 2557 | char trattr[TRANS_TRUE_SIZE]; |
2554 | int transflag = 0; | 2558 | int transflag = 0; |
2559 | int rc; | ||
2555 | struct dentry *dp; | 2560 | struct dentry *dp; |
2556 | 2561 | ||
2557 | if (inode == NULL) | 2562 | if (inode == NULL) |
@@ -2670,17 +2675,38 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
2670 | */ | 2675 | */ |
2671 | dp = dget(opt_dentry); | 2676 | dp = dget(opt_dentry); |
2672 | fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); | 2677 | fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); |
2673 | if (fetched != NULL) { | 2678 | if (fetched != NULL) |
2674 | final = fetched; | 2679 | final = fetched; |
2675 | if (S_ISDIR(inode->i_mode)) { | 2680 | |
2676 | trattr[0] = '\0'; | 2681 | /* |
2677 | inode->i_op->getxattr(dp, | 2682 | * Transmuting directory |
2683 | */ | ||
2684 | if (S_ISDIR(inode->i_mode)) { | ||
2685 | /* | ||
2686 | * If this is a new directory and the label was | ||
2687 | * transmuted when the inode was initialized | ||
2688 | * set the transmute attribute on the directory | ||
2689 | * and mark the inode. | ||
2690 | * | ||
2691 | * If there is a transmute attribute on the | ||
2692 | * directory mark the inode. | ||
2693 | */ | ||
2694 | if (isp->smk_flags & SMK_INODE_CHANGED) { | ||
2695 | isp->smk_flags &= ~SMK_INODE_CHANGED; | ||
2696 | rc = inode->i_op->setxattr(dp, | ||
2678 | XATTR_NAME_SMACKTRANSMUTE, | 2697 | XATTR_NAME_SMACKTRANSMUTE, |
2679 | trattr, TRANS_TRUE_SIZE); | 2698 | TRANS_TRUE, TRANS_TRUE_SIZE, |
2680 | if (strncmp(trattr, TRANS_TRUE, | 2699 | 0); |
2681 | TRANS_TRUE_SIZE) == 0) | 2700 | } else { |
2682 | transflag = SMK_INODE_TRANSMUTE; | 2701 | rc = inode->i_op->getxattr(dp, |
2702 | XATTR_NAME_SMACKTRANSMUTE, trattr, | ||
2703 | TRANS_TRUE_SIZE); | ||
2704 | if (rc >= 0 && strncmp(trattr, TRANS_TRUE, | ||
2705 | TRANS_TRUE_SIZE) != 0) | ||
2706 | rc = -EINVAL; | ||
2683 | } | 2707 | } |
2708 | if (rc >= 0) | ||
2709 | transflag = SMK_INODE_TRANSMUTE; | ||
2684 | } | 2710 | } |
2685 | isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); | 2711 | isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); |
2686 | isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); | 2712 | isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); |