Skip to content

Commit bce6a32

Browse files
stephensmalleygregkh
authored andcommitted
selinux: fix avdcache auditing
commit f92d542 upstream. The per-task avdcache was incorrectly saving and reusing the audited vector computed by avc_audit_required() rather than recomputing based on the currently requested permissions and distinguishing the denied versus allowed cases. As a result, some permission checks were not being audited, e.g. directory write checks after a previously cached directory search check. Cc: stable@vger.kernel.org Fixes: dde3a5d ("selinux: move avdcache to per-task security struct") Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> [PM: line wrap tweaks] Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 2ffaa7a commit bce6a32

2 files changed

Lines changed: 14 additions & 21 deletions

File tree

security/selinux/hooks.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,15 +3207,13 @@ static inline int task_avdcache_search(struct task_security_struct *tsec,
32073207
* @tsec: the task's security state
32083208
* @isec: the inode associated with the cache entry
32093209
* @avd: the AVD to cache
3210-
* @audited: the permission audit bitmask to cache
32113210
*
3212-
* Update the AVD cache in @tsec with the @avdc and @audited info associated
3211+
* Update the AVD cache in @tsec with the @avd info associated
32133212
* with @isec.
32143213
*/
32153214
static inline void task_avdcache_update(struct task_security_struct *tsec,
32163215
struct inode_security_struct *isec,
3217-
struct av_decision *avd,
3218-
u32 audited)
3216+
struct av_decision *avd)
32193217
{
32203218
int spot;
32213219

@@ -3227,9 +3225,7 @@ static inline void task_avdcache_update(struct task_security_struct *tsec,
32273225
spot = (tsec->avdcache.dir_spot + 1) & (TSEC_AVDC_DIR_SIZE - 1);
32283226
tsec->avdcache.dir_spot = spot;
32293227
tsec->avdcache.dir[spot].isid = isec->sid;
3230-
tsec->avdcache.dir[spot].audited = audited;
3231-
tsec->avdcache.dir[spot].allowed = avd->allowed;
3232-
tsec->avdcache.dir[spot].permissive = avd->flags & AVD_FLAGS_PERMISSIVE;
3228+
tsec->avdcache.dir[spot].avd = *avd;
32333229
tsec->avdcache.permissive_neveraudit =
32343230
(avd->flags == (AVD_FLAGS_PERMISSIVE|AVD_FLAGS_NEVERAUDIT));
32353231
}
@@ -3250,6 +3246,7 @@ static int selinux_inode_permission(struct inode *inode, int requested)
32503246
struct task_security_struct *tsec;
32513247
struct inode_security_struct *isec;
32523248
struct avdc_entry *avdc;
3249+
struct av_decision avd, *avdp = &avd;
32533250
int rc, rc2;
32543251
u32 audited, denied;
32553252

@@ -3271,23 +3268,21 @@ static int selinux_inode_permission(struct inode *inode, int requested)
32713268
rc = task_avdcache_search(tsec, isec, &avdc);
32723269
if (likely(!rc)) {
32733270
/* Cache hit. */
3274-
audited = perms & avdc->audited;
3275-
denied = perms & ~avdc->allowed;
3276-
if (unlikely(denied && enforcing_enabled() &&
3277-
!avdc->permissive))
3271+
avdp = &avdc->avd;
3272+
denied = perms & ~avdp->allowed;
3273+
if (unlikely(denied) && enforcing_enabled() &&
3274+
!(avdp->flags & AVD_FLAGS_PERMISSIVE))
32783275
rc = -EACCES;
32793276
} else {
3280-
struct av_decision avd;
3281-
32823277
/* Cache miss. */
32833278
rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass,
3284-
perms, 0, &avd);
3285-
audited = avc_audit_required(perms, &avd, rc,
3286-
(requested & MAY_ACCESS) ? FILE__AUDIT_ACCESS : 0,
3287-
&denied);
3288-
task_avdcache_update(tsec, isec, &avd, audited);
3279+
perms, 0, avdp);
3280+
task_avdcache_update(tsec, isec, avdp);
32893281
}
32903282

3283+
audited = avc_audit_required(perms, avdp, rc,
3284+
(requested & MAY_ACCESS) ?
3285+
FILE__AUDIT_ACCESS : 0, &denied);
32913286
if (likely(!audited))
32923287
return rc;
32933288

security/selinux/include/objsec.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232

3333
struct avdc_entry {
3434
u32 isid; /* inode SID */
35-
u32 allowed; /* allowed permission bitmask */
36-
u32 audited; /* audited permission bitmask */
37-
bool permissive; /* AVC permissive flag */
35+
struct av_decision avd; /* av decision */
3836
};
3937

4038
struct cred_security_struct {

0 commit comments

Comments
 (0)