diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-09 11:28:13 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-09 11:28:13 -0500 |
| commit | b749e3f8d7879c9c87e237d75b2256b4d1d04df2 (patch) | |
| tree | 27589e391ecb12ad51243bf7e124c6dfcc7a5b66 | |
| parent | 6f8e5850df8eecee212c84831030b04f025c11ac (diff) | |
| parent | 48887e63d6e057543067327da6b091297f7fe645 (diff) | |
Merge branch 'audit.b59' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b59' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
[PATCH] fix broken timestamps in AVC generated by kernel threads
[patch 1/1] audit: remove excess kernel-doc
[PATCH] asm/generic: fix bug - kernel fails to build when enable some common audit code on Blackfin
[PATCH] return records for fork() both to child and parent
[PATCH] Audit: make audit=0 actually turn off audit
| -rw-r--r-- | include/asm-generic/audit_write.h | 2 | ||||
| -rw-r--r-- | include/linux/audit.h | 6 | ||||
| -rw-r--r-- | kernel/audit.c | 32 | ||||
| -rw-r--r-- | kernel/auditsc.c | 24 | ||||
| -rw-r--r-- | kernel/fork.c | 1 |
5 files changed, 50 insertions, 15 deletions
diff --git a/include/asm-generic/audit_write.h b/include/asm-generic/audit_write.h index f10d367fb2a5..c5f1c2c920e2 100644 --- a/include/asm-generic/audit_write.h +++ b/include/asm-generic/audit_write.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #include <asm-generic/audit_dir_write.h> | 1 | #include <asm-generic/audit_dir_write.h> |
| 2 | __NR_acct, | 2 | __NR_acct, |
| 3 | #ifdef __NR_swapon | ||
| 3 | __NR_swapon, | 4 | __NR_swapon, |
| 5 | #endif | ||
| 4 | __NR_quotactl, | 6 | __NR_quotactl, |
| 5 | __NR_truncate, | 7 | __NR_truncate, |
| 6 | #ifdef __NR_truncate64 | 8 | #ifdef __NR_truncate64 |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 6272a395d43c..8f0672d13eb1 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -391,6 +391,7 @@ extern int audit_classify_arch(int arch); | |||
| 391 | #ifdef CONFIG_AUDITSYSCALL | 391 | #ifdef CONFIG_AUDITSYSCALL |
| 392 | /* These are defined in auditsc.c */ | 392 | /* These are defined in auditsc.c */ |
| 393 | /* Public API */ | 393 | /* Public API */ |
| 394 | extern void audit_finish_fork(struct task_struct *child); | ||
| 394 | extern int audit_alloc(struct task_struct *task); | 395 | extern int audit_alloc(struct task_struct *task); |
| 395 | extern void audit_free(struct task_struct *task); | 396 | extern void audit_free(struct task_struct *task); |
| 396 | extern void audit_syscall_entry(int arch, | 397 | extern void audit_syscall_entry(int arch, |
| @@ -434,7 +435,7 @@ static inline void audit_ptrace(struct task_struct *t) | |||
| 434 | 435 | ||
| 435 | /* Private API (for audit.c only) */ | 436 | /* Private API (for audit.c only) */ |
| 436 | extern unsigned int audit_serial(void); | 437 | extern unsigned int audit_serial(void); |
| 437 | extern void auditsc_get_stamp(struct audit_context *ctx, | 438 | extern int auditsc_get_stamp(struct audit_context *ctx, |
| 438 | struct timespec *t, unsigned int *serial); | 439 | struct timespec *t, unsigned int *serial); |
| 439 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); | 440 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); |
| 440 | #define audit_get_loginuid(t) ((t)->loginuid) | 441 | #define audit_get_loginuid(t) ((t)->loginuid) |
| @@ -504,6 +505,7 @@ static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) | |||
| 504 | extern int audit_n_rules; | 505 | extern int audit_n_rules; |
| 505 | extern int audit_signals; | 506 | extern int audit_signals; |
| 506 | #else | 507 | #else |
| 508 | #define audit_finish_fork(t) | ||
| 507 | #define audit_alloc(t) ({ 0; }) | 509 | #define audit_alloc(t) ({ 0; }) |
| 508 | #define audit_free(t) do { ; } while (0) | 510 | #define audit_free(t) do { ; } while (0) |
| 509 | #define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0) | 511 | #define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0) |
| @@ -516,7 +518,7 @@ extern int audit_signals; | |||
| 516 | #define audit_inode(n,d) do { ; } while (0) | 518 | #define audit_inode(n,d) do { ; } while (0) |
| 517 | #define audit_inode_child(d,i,p) do { ; } while (0) | 519 | #define audit_inode_child(d,i,p) do { ; } while (0) |
| 518 | #define audit_core_dumps(i) do { ; } while (0) | 520 | #define audit_core_dumps(i) do { ; } while (0) |
| 519 | #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) | 521 | #define auditsc_get_stamp(c,t,s) (0) |
| 520 | #define audit_get_loginuid(t) (-1) | 522 | #define audit_get_loginuid(t) (-1) |
| 521 | #define audit_get_sessionid(t) (-1) | 523 | #define audit_get_sessionid(t) (-1) |
| 522 | #define audit_log_task_context(b) do { ; } while (0) | 524 | #define audit_log_task_context(b) do { ; } while (0) |
diff --git a/kernel/audit.c b/kernel/audit.c index 4414e93d8750..ce6d8ea3131e 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -61,8 +61,11 @@ | |||
| 61 | 61 | ||
| 62 | #include "audit.h" | 62 | #include "audit.h" |
| 63 | 63 | ||
| 64 | /* No auditing will take place until audit_initialized != 0. | 64 | /* No auditing will take place until audit_initialized == AUDIT_INITIALIZED. |
| 65 | * (Initialization happens after skb_init is called.) */ | 65 | * (Initialization happens after skb_init is called.) */ |
| 66 | #define AUDIT_DISABLED -1 | ||
| 67 | #define AUDIT_UNINITIALIZED 0 | ||
| 68 | #define AUDIT_INITIALIZED 1 | ||
| 66 | static int audit_initialized; | 69 | static int audit_initialized; |
| 67 | 70 | ||
| 68 | #define AUDIT_OFF 0 | 71 | #define AUDIT_OFF 0 |
| @@ -965,6 +968,9 @@ static int __init audit_init(void) | |||
| 965 | { | 968 | { |
| 966 | int i; | 969 | int i; |
| 967 | 970 | ||
| 971 | if (audit_initialized == AUDIT_DISABLED) | ||
| 972 | return 0; | ||
| 973 | |||
| 968 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", | 974 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", |
| 969 | audit_default ? "enabled" : "disabled"); | 975 | audit_default ? "enabled" : "disabled"); |
| 970 | audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, | 976 | audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, |
| @@ -976,7 +982,7 @@ static int __init audit_init(void) | |||
| 976 | 982 | ||
| 977 | skb_queue_head_init(&audit_skb_queue); | 983 | skb_queue_head_init(&audit_skb_queue); |
| 978 | skb_queue_head_init(&audit_skb_hold_queue); | 984 | skb_queue_head_init(&audit_skb_hold_queue); |
| 979 | audit_initialized = 1; | 985 | audit_initialized = AUDIT_INITIALIZED; |
| 980 | audit_enabled = audit_default; | 986 | audit_enabled = audit_default; |
| 981 | audit_ever_enabled |= !!audit_default; | 987 | audit_ever_enabled |= !!audit_default; |
| 982 | 988 | ||
| @@ -999,13 +1005,21 @@ __initcall(audit_init); | |||
| 999 | static int __init audit_enable(char *str) | 1005 | static int __init audit_enable(char *str) |
| 1000 | { | 1006 | { |
| 1001 | audit_default = !!simple_strtol(str, NULL, 0); | 1007 | audit_default = !!simple_strtol(str, NULL, 0); |
| 1002 | printk(KERN_INFO "audit: %s%s\n", | 1008 | if (!audit_default) |
| 1003 | audit_default ? "enabled" : "disabled", | 1009 | audit_initialized = AUDIT_DISABLED; |
| 1004 | audit_initialized ? "" : " (after initialization)"); | 1010 | |
| 1005 | if (audit_initialized) { | 1011 | printk(KERN_INFO "audit: %s", audit_default ? "enabled" : "disabled"); |
| 1012 | |||
| 1013 | if (audit_initialized == AUDIT_INITIALIZED) { | ||
| 1006 | audit_enabled = audit_default; | 1014 | audit_enabled = audit_default; |
| 1007 | audit_ever_enabled |= !!audit_default; | 1015 | audit_ever_enabled |= !!audit_default; |
| 1016 | } else if (audit_initialized == AUDIT_UNINITIALIZED) { | ||
| 1017 | printk(" (after initialization)"); | ||
| 1018 | } else { | ||
| 1019 | printk(" (until reboot)"); | ||
| 1008 | } | 1020 | } |
| 1021 | printk("\n"); | ||
| 1022 | |||
| 1009 | return 1; | 1023 | return 1; |
| 1010 | } | 1024 | } |
| 1011 | 1025 | ||
| @@ -1107,9 +1121,7 @@ unsigned int audit_serial(void) | |||
| 1107 | static inline void audit_get_stamp(struct audit_context *ctx, | 1121 | static inline void audit_get_stamp(struct audit_context *ctx, |
| 1108 | struct timespec *t, unsigned int *serial) | 1122 | struct timespec *t, unsigned int *serial) |
| 1109 | { | 1123 | { |
| 1110 | if (ctx) | 1124 | if (!ctx || !auditsc_get_stamp(ctx, t, serial)) { |
| 1111 | auditsc_get_stamp(ctx, t, serial); | ||
| 1112 | else { | ||
| 1113 | *t = CURRENT_TIME; | 1125 | *t = CURRENT_TIME; |
| 1114 | *serial = audit_serial(); | 1126 | *serial = audit_serial(); |
| 1115 | } | 1127 | } |
| @@ -1146,7 +1158,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
| 1146 | int reserve; | 1158 | int reserve; |
| 1147 | unsigned long timeout_start = jiffies; | 1159 | unsigned long timeout_start = jiffies; |
| 1148 | 1160 | ||
| 1149 | if (!audit_initialized) | 1161 | if (audit_initialized != AUDIT_INITIALIZED) |
| 1150 | return NULL; | 1162 | return NULL; |
| 1151 | 1163 | ||
| 1152 | if (unlikely(audit_filter_type(type))) | 1164 | if (unlikely(audit_filter_type(type))) |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index cf5bc2f5f9c3..2a3f0afc4d2a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -1459,7 +1459,6 @@ void audit_free(struct task_struct *tsk) | |||
| 1459 | 1459 | ||
| 1460 | /** | 1460 | /** |
| 1461 | * audit_syscall_entry - fill in an audit record at syscall entry | 1461 | * audit_syscall_entry - fill in an audit record at syscall entry |
| 1462 | * @tsk: task being audited | ||
| 1463 | * @arch: architecture type | 1462 | * @arch: architecture type |
| 1464 | * @major: major syscall type (function) | 1463 | * @major: major syscall type (function) |
| 1465 | * @a1: additional syscall register 1 | 1464 | * @a1: additional syscall register 1 |
| @@ -1548,9 +1547,25 @@ void audit_syscall_entry(int arch, int major, | |||
| 1548 | context->ppid = 0; | 1547 | context->ppid = 0; |
| 1549 | } | 1548 | } |
| 1550 | 1549 | ||
| 1550 | void audit_finish_fork(struct task_struct *child) | ||
| 1551 | { | ||
| 1552 | struct audit_context *ctx = current->audit_context; | ||
| 1553 | struct audit_context *p = child->audit_context; | ||
| 1554 | if (!p || !ctx || !ctx->auditable) | ||
| 1555 | return; | ||
| 1556 | p->arch = ctx->arch; | ||
| 1557 | p->major = ctx->major; | ||
| 1558 | memcpy(p->argv, ctx->argv, sizeof(ctx->argv)); | ||
| 1559 | p->ctime = ctx->ctime; | ||
| 1560 | p->dummy = ctx->dummy; | ||
| 1561 | p->auditable = ctx->auditable; | ||
| 1562 | p->in_syscall = ctx->in_syscall; | ||
| 1563 | p->filterkey = kstrdup(ctx->filterkey, GFP_KERNEL); | ||
| 1564 | p->ppid = current->pid; | ||
| 1565 | } | ||
| 1566 | |||
| 1551 | /** | 1567 | /** |
| 1552 | * audit_syscall_exit - deallocate audit context after a system call | 1568 | * audit_syscall_exit - deallocate audit context after a system call |
| 1553 | * @tsk: task being audited | ||
| 1554 | * @valid: success/failure flag | 1569 | * @valid: success/failure flag |
| 1555 | * @return_code: syscall return value | 1570 | * @return_code: syscall return value |
| 1556 | * | 1571 | * |
| @@ -1942,15 +1957,18 @@ EXPORT_SYMBOL_GPL(__audit_inode_child); | |||
| 1942 | * | 1957 | * |
| 1943 | * Also sets the context as auditable. | 1958 | * Also sets the context as auditable. |
| 1944 | */ | 1959 | */ |
| 1945 | void auditsc_get_stamp(struct audit_context *ctx, | 1960 | int auditsc_get_stamp(struct audit_context *ctx, |
| 1946 | struct timespec *t, unsigned int *serial) | 1961 | struct timespec *t, unsigned int *serial) |
| 1947 | { | 1962 | { |
| 1963 | if (!ctx->in_syscall) | ||
| 1964 | return 0; | ||
| 1948 | if (!ctx->serial) | 1965 | if (!ctx->serial) |
| 1949 | ctx->serial = audit_serial(); | 1966 | ctx->serial = audit_serial(); |
| 1950 | t->tv_sec = ctx->ctime.tv_sec; | 1967 | t->tv_sec = ctx->ctime.tv_sec; |
| 1951 | t->tv_nsec = ctx->ctime.tv_nsec; | 1968 | t->tv_nsec = ctx->ctime.tv_nsec; |
| 1952 | *serial = ctx->serial; | 1969 | *serial = ctx->serial; |
| 1953 | ctx->auditable = 1; | 1970 | ctx->auditable = 1; |
| 1971 | return 1; | ||
| 1954 | } | 1972 | } |
| 1955 | 1973 | ||
| 1956 | /* global counter which is incremented every time something logs in */ | 1974 | /* global counter which is incremented every time something logs in */ |
diff --git a/kernel/fork.c b/kernel/fork.c index 2a372a0e206f..8d6a7dd9282b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -1398,6 +1398,7 @@ long do_fork(unsigned long clone_flags, | |||
| 1398 | init_completion(&vfork); | 1398 | init_completion(&vfork); |
| 1399 | } | 1399 | } |
| 1400 | 1400 | ||
| 1401 | audit_finish_fork(p); | ||
| 1401 | tracehook_report_clone(trace, regs, clone_flags, nr, p); | 1402 | tracehook_report_clone(trace, regs, clone_flags, nr, p); |
| 1402 | 1403 | ||
| 1403 | /* | 1404 | /* |
