diff options
| author | James Morris <jmorris@namei.org> | 2011-05-19 04:51:57 -0400 |
|---|---|---|
| committer | James Morris <jmorris@namei.org> | 2011-05-19 04:51:57 -0400 |
| commit | 12a5a2621b1ee14d32beca35304d7c6076a58815 (patch) | |
| tree | 213e13f99de690b3c4a510f504393b63ada626bd /security | |
| parent | e77dc3460fa59be5759e9327ad882868eee9d61b (diff) | |
| parent | 61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf (diff) | |
Merge branch 'master' into next
Conflicts:
include/linux/capability.h
Manually resolve merge conflict w/ thanks to Stephen Rothwell.
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
| -rw-r--r-- | security/capability.c | 2 | ||||
| -rw-r--r-- | security/security.c | 6 | ||||
| -rw-r--r-- | security/selinux/avc.c | 36 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 27 | ||||
| -rw-r--r-- | security/selinux/include/avc.h | 18 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.c | 10 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 6 |
7 files changed, 69 insertions, 36 deletions
diff --git a/security/capability.c b/security/capability.c index 2984ea4f776f..bbb51156261b 100644 --- a/security/capability.c +++ b/security/capability.c | |||
| @@ -181,7 +181,7 @@ static int cap_inode_follow_link(struct dentry *dentry, | |||
| 181 | return 0; | 181 | return 0; |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | static int cap_inode_permission(struct inode *inode, int mask) | 184 | static int cap_inode_permission(struct inode *inode, int mask, unsigned flags) |
| 185 | { | 185 | { |
| 186 | return 0; | 186 | return 0; |
| 187 | } | 187 | } |
diff --git a/security/security.c b/security/security.c index 101142369db4..4ba6d4cc061f 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -518,16 +518,14 @@ int security_inode_permission(struct inode *inode, int mask) | |||
| 518 | { | 518 | { |
| 519 | if (unlikely(IS_PRIVATE(inode))) | 519 | if (unlikely(IS_PRIVATE(inode))) |
| 520 | return 0; | 520 | return 0; |
| 521 | return security_ops->inode_permission(inode, mask); | 521 | return security_ops->inode_permission(inode, mask, 0); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | int security_inode_exec_permission(struct inode *inode, unsigned int flags) | 524 | int security_inode_exec_permission(struct inode *inode, unsigned int flags) |
| 525 | { | 525 | { |
| 526 | if (unlikely(IS_PRIVATE(inode))) | 526 | if (unlikely(IS_PRIVATE(inode))) |
| 527 | return 0; | 527 | return 0; |
| 528 | if (flags) | 528 | return security_ops->inode_permission(inode, MAY_EXEC, flags); |
| 529 | return -ECHILD; | ||
| 530 | return security_ops->inode_permission(inode, MAY_EXEC); | ||
| 531 | } | 529 | } |
| 532 | 530 | ||
| 533 | int security_inode_setattr(struct dentry *dentry, struct iattr *attr) | 531 | int security_inode_setattr(struct dentry *dentry, struct iattr *attr) |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 9da6420e2056..1d027e29ce8d 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -471,6 +471,7 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) | |||
| 471 | * @avd: access vector decisions | 471 | * @avd: access vector decisions |
| 472 | * @result: result from avc_has_perm_noaudit | 472 | * @result: result from avc_has_perm_noaudit |
| 473 | * @a: auxiliary audit data | 473 | * @a: auxiliary audit data |
| 474 | * @flags: VFS walk flags | ||
| 474 | * | 475 | * |
| 475 | * Audit the granting or denial of permissions in accordance | 476 | * Audit the granting or denial of permissions in accordance |
| 476 | * with the policy. This function is typically called by | 477 | * with the policy. This function is typically called by |
| @@ -481,9 +482,10 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) | |||
| 481 | * be performed under a lock, to allow the lock to be released | 482 | * be performed under a lock, to allow the lock to be released |
| 482 | * before calling the auditing code. | 483 | * before calling the auditing code. |
| 483 | */ | 484 | */ |
| 484 | void avc_audit(u32 ssid, u32 tsid, | 485 | int avc_audit(u32 ssid, u32 tsid, |
| 485 | u16 tclass, u32 requested, | 486 | u16 tclass, u32 requested, |
| 486 | struct av_decision *avd, int result, struct common_audit_data *a) | 487 | struct av_decision *avd, int result, struct common_audit_data *a, |
| 488 | unsigned flags) | ||
| 487 | { | 489 | { |
| 488 | struct common_audit_data stack_data; | 490 | struct common_audit_data stack_data; |
| 489 | u32 denied, audited; | 491 | u32 denied, audited; |
| @@ -515,11 +517,24 @@ void avc_audit(u32 ssid, u32 tsid, | |||
| 515 | else | 517 | else |
| 516 | audited = requested & avd->auditallow; | 518 | audited = requested & avd->auditallow; |
| 517 | if (!audited) | 519 | if (!audited) |
| 518 | return; | 520 | return 0; |
| 521 | |||
| 519 | if (!a) { | 522 | if (!a) { |
| 520 | a = &stack_data; | 523 | a = &stack_data; |
| 521 | COMMON_AUDIT_DATA_INIT(a, NONE); | 524 | COMMON_AUDIT_DATA_INIT(a, NONE); |
| 522 | } | 525 | } |
| 526 | |||
| 527 | /* | ||
| 528 | * When in a RCU walk do the audit on the RCU retry. This is because | ||
| 529 | * the collection of the dname in an inode audit message is not RCU | ||
| 530 | * safe. Note this may drop some audits when the situation changes | ||
| 531 | * during retry. However this is logically just as if the operation | ||
| 532 | * happened a little later. | ||
| 533 | */ | ||
| 534 | if ((a->type == LSM_AUDIT_DATA_FS) && | ||
| 535 | (flags & IPERM_FLAG_RCU)) | ||
| 536 | return -ECHILD; | ||
| 537 | |||
| 523 | a->selinux_audit_data.tclass = tclass; | 538 | a->selinux_audit_data.tclass = tclass; |
| 524 | a->selinux_audit_data.requested = requested; | 539 | a->selinux_audit_data.requested = requested; |
| 525 | a->selinux_audit_data.ssid = ssid; | 540 | a->selinux_audit_data.ssid = ssid; |
| @@ -529,6 +544,7 @@ void avc_audit(u32 ssid, u32 tsid, | |||
| 529 | a->lsm_pre_audit = avc_audit_pre_callback; | 544 | a->lsm_pre_audit = avc_audit_pre_callback; |
| 530 | a->lsm_post_audit = avc_audit_post_callback; | 545 | a->lsm_post_audit = avc_audit_post_callback; |
| 531 | common_lsm_audit(a); | 546 | common_lsm_audit(a); |
| 547 | return 0; | ||
| 532 | } | 548 | } |
| 533 | 549 | ||
| 534 | /** | 550 | /** |
| @@ -793,6 +809,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 793 | * @tclass: target security class | 809 | * @tclass: target security class |
| 794 | * @requested: requested permissions, interpreted based on @tclass | 810 | * @requested: requested permissions, interpreted based on @tclass |
| 795 | * @auditdata: auxiliary audit data | 811 | * @auditdata: auxiliary audit data |
| 812 | * @flags: VFS walk flags | ||
| 796 | * | 813 | * |
| 797 | * Check the AVC to determine whether the @requested permissions are granted | 814 | * Check the AVC to determine whether the @requested permissions are granted |
| 798 | * for the SID pair (@ssid, @tsid), interpreting the permissions | 815 | * for the SID pair (@ssid, @tsid), interpreting the permissions |
| @@ -802,14 +819,19 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 802 | * permissions are granted, -%EACCES if any permissions are denied, or | 819 | * permissions are granted, -%EACCES if any permissions are denied, or |
| 803 | * another -errno upon other errors. | 820 | * another -errno upon other errors. |
| 804 | */ | 821 | */ |
| 805 | int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, | 822 | int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, |
| 806 | u32 requested, struct common_audit_data *auditdata) | 823 | u32 requested, struct common_audit_data *auditdata, |
| 824 | unsigned flags) | ||
| 807 | { | 825 | { |
| 808 | struct av_decision avd; | 826 | struct av_decision avd; |
| 809 | int rc; | 827 | int rc, rc2; |
| 810 | 828 | ||
| 811 | rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); | 829 | rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); |
| 812 | avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); | 830 | |
| 831 | rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata, | ||
| 832 | flags); | ||
| 833 | if (rc2) | ||
| 834 | return rc2; | ||
| 813 | return rc; | 835 | return rc; |
| 814 | } | 836 | } |
| 815 | 837 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f9c3764e4859..8fb248843009 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -1446,8 +1446,11 @@ static int task_has_capability(struct task_struct *tsk, | |||
| 1446 | } | 1446 | } |
| 1447 | 1447 | ||
| 1448 | rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); | 1448 | rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); |
| 1449 | if (audit == SECURITY_CAP_AUDIT) | 1449 | if (audit == SECURITY_CAP_AUDIT) { |
| 1450 | avc_audit(sid, sid, sclass, av, &avd, rc, &ad); | 1450 | int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0); |
| 1451 | if (rc2) | ||
| 1452 | return rc2; | ||
| 1453 | } | ||
| 1451 | return rc; | 1454 | return rc; |
| 1452 | } | 1455 | } |
| 1453 | 1456 | ||
| @@ -1467,7 +1470,8 @@ static int task_has_system(struct task_struct *tsk, | |||
| 1467 | static int inode_has_perm(const struct cred *cred, | 1470 | static int inode_has_perm(const struct cred *cred, |
| 1468 | struct inode *inode, | 1471 | struct inode *inode, |
| 1469 | u32 perms, | 1472 | u32 perms, |
| 1470 | struct common_audit_data *adp) | 1473 | struct common_audit_data *adp, |
| 1474 | unsigned flags) | ||
| 1471 | { | 1475 | { |
| 1472 | struct inode_security_struct *isec; | 1476 | struct inode_security_struct *isec; |
| 1473 | struct common_audit_data ad; | 1477 | struct common_audit_data ad; |
| @@ -1487,7 +1491,7 @@ static int inode_has_perm(const struct cred *cred, | |||
| 1487 | ad.u.fs.inode = inode; | 1491 | ad.u.fs.inode = inode; |
| 1488 | } | 1492 | } |
| 1489 | 1493 | ||
| 1490 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); | 1494 | return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); |
| 1491 | } | 1495 | } |
| 1492 | 1496 | ||
| 1493 | /* Same as inode_has_perm, but pass explicit audit data containing | 1497 | /* Same as inode_has_perm, but pass explicit audit data containing |
| @@ -1504,7 +1508,7 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
| 1504 | COMMON_AUDIT_DATA_INIT(&ad, FS); | 1508 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
| 1505 | ad.u.fs.path.mnt = mnt; | 1509 | ad.u.fs.path.mnt = mnt; |
| 1506 | ad.u.fs.path.dentry = dentry; | 1510 | ad.u.fs.path.dentry = dentry; |
| 1507 | return inode_has_perm(cred, inode, av, &ad); | 1511 | return inode_has_perm(cred, inode, av, &ad, 0); |
| 1508 | } | 1512 | } |
| 1509 | 1513 | ||
| 1510 | /* Check whether a task can use an open file descriptor to | 1514 | /* Check whether a task can use an open file descriptor to |
| @@ -1540,7 +1544,7 @@ static int file_has_perm(const struct cred *cred, | |||
| 1540 | /* av is zero if only checking access to the descriptor. */ | 1544 | /* av is zero if only checking access to the descriptor. */ |
| 1541 | rc = 0; | 1545 | rc = 0; |
| 1542 | if (av) | 1546 | if (av) |
| 1543 | rc = inode_has_perm(cred, inode, av, &ad); | 1547 | rc = inode_has_perm(cred, inode, av, &ad, 0); |
| 1544 | 1548 | ||
| 1545 | out: | 1549 | out: |
| 1546 | return rc; | 1550 | return rc; |
| @@ -1574,7 +1578,8 @@ static int may_create(struct inode *dir, | |||
| 1574 | return rc; | 1578 | return rc; |
| 1575 | 1579 | ||
| 1576 | if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { | 1580 | if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { |
| 1577 | rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid); | 1581 | rc = security_transition_sid(sid, dsec->sid, tclass, |
| 1582 | &dentry->d_name, &newsid); | ||
| 1578 | if (rc) | 1583 | if (rc) |
| 1579 | return rc; | 1584 | return rc; |
| 1580 | } | 1585 | } |
| @@ -2103,7 +2108,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
| 2103 | file = file_priv->file; | 2108 | file = file_priv->file; |
| 2104 | inode = file->f_path.dentry->d_inode; | 2109 | inode = file->f_path.dentry->d_inode; |
| 2105 | if (inode_has_perm(cred, inode, | 2110 | if (inode_has_perm(cred, inode, |
| 2106 | FILE__READ | FILE__WRITE, NULL)) { | 2111 | FILE__READ | FILE__WRITE, NULL, 0)) { |
| 2107 | drop_tty = 1; | 2112 | drop_tty = 1; |
| 2108 | } | 2113 | } |
| 2109 | } | 2114 | } |
| @@ -2635,7 +2640,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na | |||
| 2635 | return dentry_has_perm(cred, NULL, dentry, FILE__READ); | 2640 | return dentry_has_perm(cred, NULL, dentry, FILE__READ); |
| 2636 | } | 2641 | } |
| 2637 | 2642 | ||
| 2638 | static int selinux_inode_permission(struct inode *inode, int mask) | 2643 | static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) |
| 2639 | { | 2644 | { |
| 2640 | const struct cred *cred = current_cred(); | 2645 | const struct cred *cred = current_cred(); |
| 2641 | struct common_audit_data ad; | 2646 | struct common_audit_data ad; |
| @@ -2657,7 +2662,7 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
| 2657 | 2662 | ||
| 2658 | perms = file_mask_to_av(inode->i_mode, mask); | 2663 | perms = file_mask_to_av(inode->i_mode, mask); |
| 2659 | 2664 | ||
| 2660 | return inode_has_perm(cred, inode, perms, &ad); | 2665 | return inode_has_perm(cred, inode, perms, &ad, flags); |
| 2661 | } | 2666 | } |
| 2662 | 2667 | ||
| 2663 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2668 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
| @@ -3205,7 +3210,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred) | |||
| 3205 | * new inode label or new policy. | 3210 | * new inode label or new policy. |
| 3206 | * This check is not redundant - do not remove. | 3211 | * This check is not redundant - do not remove. |
| 3207 | */ | 3212 | */ |
| 3208 | return inode_has_perm(cred, inode, open_file_to_av(file), NULL); | 3213 | return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0); |
| 3209 | } | 3214 | } |
| 3210 | 3215 | ||
| 3211 | /* task security operations */ | 3216 | /* task security operations */ |
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 5615081b73ec..e77b2ac2908b 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h | |||
| @@ -54,11 +54,11 @@ struct avc_cache_stats { | |||
| 54 | 54 | ||
| 55 | void __init avc_init(void); | 55 | void __init avc_init(void); |
| 56 | 56 | ||
| 57 | void avc_audit(u32 ssid, u32 tsid, | 57 | int avc_audit(u32 ssid, u32 tsid, |
| 58 | u16 tclass, u32 requested, | 58 | u16 tclass, u32 requested, |
| 59 | struct av_decision *avd, | 59 | struct av_decision *avd, |
| 60 | int result, | 60 | int result, |
| 61 | struct common_audit_data *a); | 61 | struct common_audit_data *a, unsigned flags); |
| 62 | 62 | ||
| 63 | #define AVC_STRICT 1 /* Ignore permissive mode. */ | 63 | #define AVC_STRICT 1 /* Ignore permissive mode. */ |
| 64 | int avc_has_perm_noaudit(u32 ssid, u32 tsid, | 64 | int avc_has_perm_noaudit(u32 ssid, u32 tsid, |
| @@ -66,9 +66,17 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 66 | unsigned flags, | 66 | unsigned flags, |
| 67 | struct av_decision *avd); | 67 | struct av_decision *avd); |
| 68 | 68 | ||
| 69 | int avc_has_perm(u32 ssid, u32 tsid, | 69 | int avc_has_perm_flags(u32 ssid, u32 tsid, |
| 70 | u16 tclass, u32 requested, | 70 | u16 tclass, u32 requested, |
| 71 | struct common_audit_data *auditdata); | 71 | struct common_audit_data *auditdata, |
| 72 | unsigned); | ||
| 73 | |||
| 74 | static inline int avc_has_perm(u32 ssid, u32 tsid, | ||
| 75 | u16 tclass, u32 requested, | ||
| 76 | struct common_audit_data *auditdata) | ||
| 77 | { | ||
| 78 | return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0); | ||
| 79 | } | ||
| 72 | 80 | ||
| 73 | u32 avc_policy_seqno(void); | 81 | u32 avc_policy_seqno(void); |
| 74 | 82 | ||
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index e7b850ad57ee..7102457661d6 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
| @@ -502,7 +502,7 @@ static int policydb_index(struct policydb *p) | |||
| 502 | goto out; | 502 | goto out; |
| 503 | 503 | ||
| 504 | rc = flex_array_prealloc(p->type_val_to_struct_array, 0, | 504 | rc = flex_array_prealloc(p->type_val_to_struct_array, 0, |
| 505 | p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO); | 505 | p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); |
| 506 | if (rc) | 506 | if (rc) |
| 507 | goto out; | 507 | goto out; |
| 508 | 508 | ||
| @@ -519,7 +519,7 @@ static int policydb_index(struct policydb *p) | |||
| 519 | goto out; | 519 | goto out; |
| 520 | 520 | ||
| 521 | rc = flex_array_prealloc(p->sym_val_to_name[i], | 521 | rc = flex_array_prealloc(p->sym_val_to_name[i], |
| 522 | 0, p->symtab[i].nprim - 1, | 522 | 0, p->symtab[i].nprim, |
| 523 | GFP_KERNEL | __GFP_ZERO); | 523 | GFP_KERNEL | __GFP_ZERO); |
| 524 | if (rc) | 524 | if (rc) |
| 525 | goto out; | 525 | goto out; |
| @@ -1819,8 +1819,6 @@ static int filename_trans_read(struct policydb *p, void *fp) | |||
| 1819 | goto out; | 1819 | goto out; |
| 1820 | nel = le32_to_cpu(buf[0]); | 1820 | nel = le32_to_cpu(buf[0]); |
| 1821 | 1821 | ||
| 1822 | printk(KERN_ERR "%s: nel=%d\n", __func__, nel); | ||
| 1823 | |||
| 1824 | last = p->filename_trans; | 1822 | last = p->filename_trans; |
| 1825 | while (last && last->next) | 1823 | while (last && last->next) |
| 1826 | last = last->next; | 1824 | last = last->next; |
| @@ -1857,8 +1855,6 @@ static int filename_trans_read(struct policydb *p, void *fp) | |||
| 1857 | goto out; | 1855 | goto out; |
| 1858 | name[len] = 0; | 1856 | name[len] = 0; |
| 1859 | 1857 | ||
| 1860 | printk(KERN_ERR "%s: ft=%p ft->name=%p ft->name=%s\n", __func__, ft, ft->name, ft->name); | ||
| 1861 | |||
| 1862 | rc = next_entry(buf, fp, sizeof(u32) * 4); | 1858 | rc = next_entry(buf, fp, sizeof(u32) * 4); |
| 1863 | if (rc) | 1859 | if (rc) |
| 1864 | goto out; | 1860 | goto out; |
| @@ -2375,7 +2371,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
| 2375 | goto bad; | 2371 | goto bad; |
| 2376 | 2372 | ||
| 2377 | /* preallocate so we don't have to worry about the put ever failing */ | 2373 | /* preallocate so we don't have to worry about the put ever failing */ |
| 2378 | rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, | 2374 | rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim, |
| 2379 | GFP_KERNEL | __GFP_ZERO); | 2375 | GFP_KERNEL | __GFP_ZERO); |
| 2380 | if (rc) | 2376 | if (rc) |
| 2381 | goto bad; | 2377 | goto bad; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index c6f8fcadae07..400a5d5cde61 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -686,7 +686,7 @@ static int smack_inode_rename(struct inode *old_inode, | |||
| 686 | * | 686 | * |
| 687 | * Returns 0 if access is permitted, -EACCES otherwise | 687 | * Returns 0 if access is permitted, -EACCES otherwise |
| 688 | */ | 688 | */ |
| 689 | static int smack_inode_permission(struct inode *inode, int mask) | 689 | static int smack_inode_permission(struct inode *inode, int mask, unsigned flags) |
| 690 | { | 690 | { |
| 691 | struct smk_audit_info ad; | 691 | struct smk_audit_info ad; |
| 692 | 692 | ||
| @@ -696,6 +696,10 @@ static int smack_inode_permission(struct inode *inode, int mask) | |||
| 696 | */ | 696 | */ |
| 697 | if (mask == 0) | 697 | if (mask == 0) |
| 698 | return 0; | 698 | return 0; |
| 699 | |||
| 700 | /* May be droppable after audit */ | ||
| 701 | if (flags & IPERM_FLAG_RCU) | ||
| 702 | return -ECHILD; | ||
| 699 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); | 703 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); |
| 700 | smk_ad_setfield_u_fs_inode(&ad, inode); | 704 | smk_ad_setfield_u_fs_inode(&ad, inode); |
| 701 | return smk_curacc(smk_of_inode(inode), mask, &ad); | 705 | return smk_curacc(smk_of_inode(inode), mask, &ad); |
