diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-13 12:47:30 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-13 12:47:30 -0400 |
| commit | 5d54e69c68c05b162a56f9914cae72afd7e6f40a (patch) | |
| tree | c5933858c4861bc3e358559f64ef459a1f56ab75 /kernel | |
| parent | 63f3d1df1ad276a30b75339dd682a6e1f9d0c181 (diff) | |
| parent | b6ddc518520887a62728b0414efbf802a9dfdd55 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/audit.c | 128 | ||||
| -rw-r--r-- | kernel/auditsc.c | 327 |
2 files changed, 308 insertions, 147 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 7f0699790d46..83096b67510a 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -79,6 +79,8 @@ static int audit_rate_limit; | |||
| 79 | 79 | ||
| 80 | /* Number of outstanding audit_buffers allowed. */ | 80 | /* Number of outstanding audit_buffers allowed. */ |
| 81 | static int audit_backlog_limit = 64; | 81 | static int audit_backlog_limit = 64; |
| 82 | static int audit_backlog_wait_time = 60 * HZ; | ||
| 83 | static int audit_backlog_wait_overflow = 0; | ||
| 82 | 84 | ||
| 83 | /* The identity of the user shutting down the audit system. */ | 85 | /* The identity of the user shutting down the audit system. */ |
| 84 | uid_t audit_sig_uid = -1; | 86 | uid_t audit_sig_uid = -1; |
| @@ -106,18 +108,12 @@ static LIST_HEAD(audit_freelist); | |||
| 106 | static struct sk_buff_head audit_skb_queue; | 108 | static struct sk_buff_head audit_skb_queue; |
| 107 | static struct task_struct *kauditd_task; | 109 | static struct task_struct *kauditd_task; |
| 108 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 110 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
| 109 | 111 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | |
| 110 | /* There are three lists of rules -- one to search at task creation | ||
| 111 | * time, one to search at syscall entry time, and another to search at | ||
| 112 | * syscall exit time. */ | ||
| 113 | static LIST_HEAD(audit_tsklist); | ||
| 114 | static LIST_HEAD(audit_entlist); | ||
| 115 | static LIST_HEAD(audit_extlist); | ||
| 116 | 112 | ||
| 117 | /* The netlink socket is only to be read by 1 CPU, which lets us assume | 113 | /* The netlink socket is only to be read by 1 CPU, which lets us assume |
| 118 | * that list additions and deletions never happen simultaneously in | 114 | * that list additions and deletions never happen simultaneously in |
| 119 | * auditsc.c */ | 115 | * auditsc.c */ |
| 120 | static DECLARE_MUTEX(audit_netlink_sem); | 116 | DECLARE_MUTEX(audit_netlink_sem); |
| 121 | 117 | ||
| 122 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting | 118 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting |
| 123 | * audit records. Since printk uses a 1024 byte buffer, this buffer | 119 | * audit records. Since printk uses a 1024 byte buffer, this buffer |
| @@ -137,6 +133,7 @@ struct audit_buffer { | |||
| 137 | struct list_head list; | 133 | struct list_head list; |
| 138 | struct sk_buff *skb; /* formatted skb ready to send */ | 134 | struct sk_buff *skb; /* formatted skb ready to send */ |
| 139 | struct audit_context *ctx; /* NULL or associated context */ | 135 | struct audit_context *ctx; /* NULL or associated context */ |
| 136 | int gfp_mask; | ||
| 140 | }; | 137 | }; |
| 141 | 138 | ||
| 142 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | 139 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) |
| @@ -145,11 +142,6 @@ static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | |||
| 145 | nlh->nlmsg_pid = pid; | 142 | nlh->nlmsg_pid = pid; |
| 146 | } | 143 | } |
| 147 | 144 | ||
| 148 | struct audit_entry { | ||
| 149 | struct list_head list; | ||
| 150 | struct audit_rule rule; | ||
| 151 | }; | ||
| 152 | |||
| 153 | static void audit_panic(const char *message) | 145 | static void audit_panic(const char *message) |
| 154 | { | 146 | { |
| 155 | switch (audit_failure) | 147 | switch (audit_failure) |
| @@ -233,7 +225,7 @@ static int audit_set_rate_limit(int limit, uid_t loginuid) | |||
| 233 | { | 225 | { |
| 234 | int old = audit_rate_limit; | 226 | int old = audit_rate_limit; |
| 235 | audit_rate_limit = limit; | 227 | audit_rate_limit = limit; |
| 236 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 228 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 237 | "audit_rate_limit=%d old=%d by auid=%u", | 229 | "audit_rate_limit=%d old=%d by auid=%u", |
| 238 | audit_rate_limit, old, loginuid); | 230 | audit_rate_limit, old, loginuid); |
| 239 | return old; | 231 | return old; |
| @@ -243,7 +235,7 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid) | |||
| 243 | { | 235 | { |
| 244 | int old = audit_backlog_limit; | 236 | int old = audit_backlog_limit; |
| 245 | audit_backlog_limit = limit; | 237 | audit_backlog_limit = limit; |
| 246 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 238 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 247 | "audit_backlog_limit=%d old=%d by auid=%u", | 239 | "audit_backlog_limit=%d old=%d by auid=%u", |
| 248 | audit_backlog_limit, old, loginuid); | 240 | audit_backlog_limit, old, loginuid); |
| 249 | return old; | 241 | return old; |
| @@ -255,7 +247,7 @@ static int audit_set_enabled(int state, uid_t loginuid) | |||
| 255 | if (state != 0 && state != 1) | 247 | if (state != 0 && state != 1) |
| 256 | return -EINVAL; | 248 | return -EINVAL; |
| 257 | audit_enabled = state; | 249 | audit_enabled = state; |
| 258 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 250 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 259 | "audit_enabled=%d old=%d by auid=%u", | 251 | "audit_enabled=%d old=%d by auid=%u", |
| 260 | audit_enabled, old, loginuid); | 252 | audit_enabled, old, loginuid); |
| 261 | return old; | 253 | return old; |
| @@ -269,7 +261,7 @@ static int audit_set_failure(int state, uid_t loginuid) | |||
| 269 | && state != AUDIT_FAIL_PANIC) | 261 | && state != AUDIT_FAIL_PANIC) |
| 270 | return -EINVAL; | 262 | return -EINVAL; |
| 271 | audit_failure = state; | 263 | audit_failure = state; |
| 272 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 264 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 273 | "audit_failure=%d old=%d by auid=%u", | 265 | "audit_failure=%d old=%d by auid=%u", |
| 274 | audit_failure, old, loginuid); | 266 | audit_failure, old, loginuid); |
| 275 | return old; | 267 | return old; |
| @@ -281,6 +273,7 @@ int kauditd_thread(void *dummy) | |||
| 281 | 273 | ||
| 282 | while (1) { | 274 | while (1) { |
| 283 | skb = skb_dequeue(&audit_skb_queue); | 275 | skb = skb_dequeue(&audit_skb_queue); |
| 276 | wake_up(&audit_backlog_wait); | ||
| 284 | if (skb) { | 277 | if (skb) { |
| 285 | if (audit_pid) { | 278 | if (audit_pid) { |
| 286 | int err = netlink_unicast(audit_sock, skb, audit_pid, 0); | 279 | int err = netlink_unicast(audit_sock, skb, audit_pid, 0); |
| @@ -290,7 +283,7 @@ int kauditd_thread(void *dummy) | |||
| 290 | audit_pid = 0; | 283 | audit_pid = 0; |
| 291 | } | 284 | } |
| 292 | } else { | 285 | } else { |
| 293 | printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0)); | 286 | printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0)); |
| 294 | kfree_skb(skb); | 287 | kfree_skb(skb); |
| 295 | } | 288 | } |
| 296 | } else { | 289 | } else { |
| @@ -423,7 +416,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 423 | if (status_get->mask & AUDIT_STATUS_PID) { | 416 | if (status_get->mask & AUDIT_STATUS_PID) { |
| 424 | int old = audit_pid; | 417 | int old = audit_pid; |
| 425 | audit_pid = status_get->pid; | 418 | audit_pid = status_get->pid; |
| 426 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 419 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 427 | "audit_pid=%d old=%d by auid=%u", | 420 | "audit_pid=%d old=%d by auid=%u", |
| 428 | audit_pid, old, loginuid); | 421 | audit_pid, old, loginuid); |
| 429 | } | 422 | } |
| @@ -435,15 +428,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 435 | break; | 428 | break; |
| 436 | case AUDIT_USER: | 429 | case AUDIT_USER: |
| 437 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 430 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
| 438 | ab = audit_log_start(NULL, msg_type); | 431 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) |
| 439 | if (!ab) | 432 | return 0; |
| 440 | break; /* audit_panic has been called */ | 433 | |
| 441 | audit_log_format(ab, | 434 | err = audit_filter_user(&NETLINK_CB(skb), msg_type); |
| 442 | "user pid=%d uid=%u auid=%u" | 435 | if (err == 1) { |
| 443 | " msg='%.1024s'", | 436 | err = 0; |
| 444 | pid, uid, loginuid, (char *)data); | 437 | ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
| 445 | audit_set_pid(ab, pid); | 438 | if (ab) { |
| 446 | audit_log_end(ab); | 439 | audit_log_format(ab, |
| 440 | "user pid=%d uid=%u auid=%u msg='%.1024s'", | ||
| 441 | pid, uid, loginuid, (char *)data); | ||
| 442 | audit_set_pid(ab, pid); | ||
| 443 | audit_log_end(ab); | ||
| 444 | } | ||
| 445 | } | ||
| 447 | break; | 446 | break; |
| 448 | case AUDIT_ADD: | 447 | case AUDIT_ADD: |
| 449 | case AUDIT_DEL: | 448 | case AUDIT_DEL: |
| @@ -523,7 +522,7 @@ static int __init audit_init(void) | |||
| 523 | skb_queue_head_init(&audit_skb_queue); | 522 | skb_queue_head_init(&audit_skb_queue); |
| 524 | audit_initialized = 1; | 523 | audit_initialized = 1; |
| 525 | audit_enabled = audit_default; | 524 | audit_enabled = audit_default; |
| 526 | audit_log(NULL, AUDIT_KERNEL, "initialized"); | 525 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); |
| 527 | return 0; | 526 | return 0; |
| 528 | } | 527 | } |
| 529 | __initcall(audit_init); | 528 | __initcall(audit_init); |
| @@ -561,7 +560,7 @@ static void audit_buffer_free(struct audit_buffer *ab) | |||
| 561 | } | 560 | } |
| 562 | 561 | ||
| 563 | static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, | 562 | static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, |
| 564 | int gfp_mask, int type) | 563 | unsigned int __nocast gfp_mask, int type) |
| 565 | { | 564 | { |
| 566 | unsigned long flags; | 565 | unsigned long flags; |
| 567 | struct audit_buffer *ab = NULL; | 566 | struct audit_buffer *ab = NULL; |
| @@ -587,6 +586,7 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, | |||
| 587 | goto err; | 586 | |
