diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-11 11:43:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-11 11:43:17 -0700 |
commit | 05ff0e291af086f4325bac76abad250690bbbd63 (patch) | |
tree | 3ea47e8ef5bebc1261302e3d0775414fb78037c4 /kernel/auditsc.c | |
parent | 5eea7ee2075b245d505285bb422e2fa8d686e5c8 (diff) | |
parent | 55669bfa141b488be865341ed12e188967d11308 (diff) |
Merge branch 'audit.b28' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b28' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
[PATCH] audit: AUDIT_PERM support
[PATCH] audit: more syscall classes added
[PATCH] syscall classes hookup for ppc and s390
[PATCH] update audit rule change messages
[PATCH] sanity check audit_buffer
[PATCH] fix ppid bug in 2.6.18 kernel
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index efc1b74bebf3..1bd8827a0102 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -209,6 +209,54 @@ struct audit_context { #endif }; +#define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE]) +static inline int open_arg(int flags, int mask) +{ + int n = ACC_MODE(flags); + if (flags & (O_TRUNC | O_CREAT)) + n |= AUDIT_PERM_WRITE; + return n & mask; +} + +static int audit_match_perm(struct audit_context *ctx, int mask) +{ + unsigned n = ctx->major; + switch (audit_classify_syscall(ctx->arch, n)) { + case 0: /* native */ + if ((mask & AUDIT_PERM_WRITE) && + audit_match_class(AUDIT_CLASS_WRITE, n)) + return 1; + if ((mask & AUDIT_PERM_READ) && + audit_match_class(AUDIT_CLASS_READ, n)) + return 1; + if ((mask & AUDIT_PERM_ATTR) && + audit_match_class(AUDIT_CLASS_CHATTR, n)) + return 1; + return 0; + case 1: /* 32bit on biarch */ + if ((mask & AUDIT_PERM_WRITE) && + audit_match_class(AUDIT_CLASS_WRITE_32, n)) + return 1; + if ((mask & AUDIT_PERM_READ) && + audit_match_class(AUDIT_CLASS_READ_32, n)) + return 1; + if ((mask & AUDIT_PERM_ATTR) && + audit_match_class(AUDIT_CLASS_CHATTR_32, n)) + return 1; + return 0; + case 2: /* open */ + return mask & ACC_MODE(ctx->argv[1]); + case 3: /* openat */ + return mask & ACC_MODE(ctx->argv[2]); + case 4: /* socketcall */ + return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND); + case 5: /* execve */ + return mask & AUDIT_PERM_EXEC; + default: + return 0; + } +} + /* Determine if any context name data matches a rule's watch data */ /* Compare a task_struct with an audit_rule. Return 1 on match, 0 * otherwise. */ @@ -397,6 +445,9 @@ static int audit_filter_rules(struct task_struct *tsk, /* ignore this field for filtering */ result = 1; break; + case AUDIT_PERM: + result = audit_match_perm(ctx, f->val); + break; } if (!result) |