diff options
-rw-r--r-- | include/linux/audit.h | 2 | ||||
-rw-r--r-- | include/linux/netlink.h | 1 | ||||
-rw-r--r-- | kernel/audit.c | 46 | ||||
-rw-r--r-- | kernel/auditsc.c | 5 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 1 |
5 files changed, 32 insertions, 23 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 5fabe8481011..19f214230fec 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -184,7 +184,7 @@ extern void audit_inode(const char *name, const struct inode *inode); | |||
184 | 184 | ||
185 | /* Private API (for audit.c only) */ | 185 | /* Private API (for audit.c only) */ |
186 | extern int audit_receive_filter(int type, int pid, int uid, int seq, | 186 | extern int audit_receive_filter(int type, int pid, int uid, int seq, |
187 | void *data); | 187 | void *data, uid_t loginuid); |
188 | extern void audit_get_stamp(struct audit_context *ctx, | 188 | extern void audit_get_stamp(struct audit_context *ctx, |
189 | struct timespec *t, unsigned int *serial); | 189 | struct timespec *t, unsigned int *serial); |
190 | extern int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid); | 190 | extern int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid); |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index f731abdc1a29..b2738ac8bc99 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -110,6 +110,7 @@ struct netlink_skb_parms | |||
110 | __u32 dst_pid; | 110 | __u32 dst_pid; |
111 | __u32 dst_groups; | 111 | __u32 dst_groups; |
112 | kernel_cap_t eff_cap; | 112 | kernel_cap_t eff_cap; |
113 | __u32 loginuid; /* Login (audit) uid */ | ||
113 | }; | 114 | }; |
114 | 115 | ||
115 | #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) | 116 | #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) |
diff --git a/kernel/audit.c b/kernel/audit.c index 58c7d7e47299..587d3b2eba7f 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -239,36 +239,36 @@ void audit_log_lost(const char *message) | |||
239 | 239 | ||
240 | } | 240 | } |
241 | 241 | ||
242 | static int audit_set_rate_limit(int limit) | 242 | static int audit_set_rate_limit(int limit, uid_t loginuid) |
243 | { | 243 | { |
244 | int old = audit_rate_limit; | 244 | int old = audit_rate_limit; |
245 | audit_rate_limit = limit; | 245 | audit_rate_limit = limit; |
246 | audit_log(current->audit_context, "audit_rate_limit=%d old=%d", | 246 | audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u", |
247 | audit_rate_limit, old); | 247 | audit_rate_limit, old, loginuid); |
248 | return old; | 248 | return old; |
249 | } | 249 | } |
250 | 250 | ||
251 | static int audit_set_backlog_limit(int limit) | 251 | static int audit_set_backlog_limit(int limit, uid_t loginuid) |
252 | { | 252 | { |
253 | int old = audit_backlog_limit; | 253 | int old = audit_backlog_limit; |
254 | audit_backlog_limit = limit; | 254 | audit_backlog_limit = limit; |
255 | audit_log(current->audit_context, "audit_backlog_limit=%d old=%d", | 255 | audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u", |
256 | audit_backlog_limit, old); | 256 | audit_backlog_limit, old, loginuid); |
257 | return old; | 257 | return old; |
258 | } | 258 | } |
259 | 259 | ||
260 | static int audit_set_enabled(int state) | 260 | static int audit_set_enabled(int state, uid_t loginuid) |
261 | { | 261 | { |
262 | int old = audit_enabled; | 262 | int old = audit_enabled; |
263 | if (state != 0 && state != 1) | 263 | if (state != 0 && state != 1) |
264 | return -EINVAL; | 264 | return -EINVAL; |
265 | audit_enabled = state; | 265 | audit_enabled = state; |
266 | audit_log(current->audit_context, "audit_enabled=%d old=%d", | 266 | audit_log(NULL, "audit_enabled=%d old=%d by auid %u", |
267 | audit_enabled, old); | 267 | audit_enabled, old, loginuid); |
268 | return old; | 268 | return old; |
269 | } | 269 | } |
270 | 270 | ||
271 | static int audit_set_failure(int state) | 271 | static int audit_set_failure(int state, uid_t loginuid) |
272 | { | 272 | { |
273 | int old = audit_failure; | 273 | int old = audit_failure; |
274 | if (state != AUDIT_FAIL_SILENT | 274 | if (state != AUDIT_FAIL_SILENT |
@@ -276,8 +276,8 @@ static int audit_set_failure(int state) | |||
276 | && state != AUDIT_FAIL_PANIC) | 276 | && state != AUDIT_FAIL_PANIC) |
277 | return -EINVAL; | 277 | return -EINVAL; |
278 | audit_failure = state; | 278 | audit_failure = state; |
279 | audit_log(current->audit_context, "audit_failure=%d old=%d", | 279 | audit_log(NULL, "audit_failure=%d old=%d by auid %u", |
280 | audit_failure, old); | 280 | audit_failure, old, loginuid); |
281 | return old; | 281 | return old; |
282 | } | 282 | } |
283 | 283 | ||
@@ -344,6 +344,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
344 | int err; | 344 | int err; |
345 | struct audit_buffer *ab; | 345 | struct audit_buffer *ab; |
346 | u16 msg_type = nlh->nlmsg_type; | 346 | u16 msg_type = nlh->nlmsg_type; |
347 | uid_t loginuid; /* loginuid of sender */ | ||
347 | 348 | ||
348 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); | 349 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); |
349 | if (err) | 350 | if (err) |
@@ -351,6 +352,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
351 | 352 | ||
352 | pid = NETLINK_CREDS(skb)->pid; | 353 | pid = NETLINK_CREDS(skb)->pid; |
353 | uid = NETLINK_CREDS(skb)->uid; | 354 | uid = NETLINK_CREDS(skb)->uid; |
355 | loginuid = NETLINK_CB(skb).loginuid; | ||
354 | seq = nlh->nlmsg_seq; | 356 | seq = nlh->nlmsg_seq; |
355 | data = NLMSG_DATA(nlh); | 357 | data = NLMSG_DATA(nlh); |
356 | 358 | ||
@@ -371,34 +373,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
371 | return -EINVAL; | 373 | return -EINVAL; |
372 | status_get = (struct audit_status *)data; | 374 | status_get = (struct audit_status *)data; |
373 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 375 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
374 | err = audit_set_enabled(status_get->enabled); | 376 | err = audit_set_enabled(status_get->enabled, loginuid); |
375 | if (err < 0) return err; | 377 | if (err < 0) return err; |
376 | } | 378 | } |
377 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 379 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
378 | err = audit_set_failure(status_get->failure); | 380 | err = audit_set_failure(status_get->failure, loginuid); |
379 | if (err < 0) return err; | 381 | if (err < 0) return err; |
380 | } | 382 | } |
381 | if (status_get->mask & AUDIT_STATUS_PID) { | 383 | if (status_get->mask & AUDIT_STATUS_PID) { |
382 | int old = audit_pid; | 384 | int old = audit_pid; |
383 | audit_pid = status_get->pid; | 385 | audit_pid = status_get->pid; |
384 | audit_log(current->audit_context, | 386 | audit_log(NULL, "audit_pid=%d old=%d by auid %u", |
385 | "audit_pid=%d old=%d", audit_pid, old); | 387 | audit_pid, old, loginuid); |
386 | } | 388 | } |
387 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 389 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
388 | audit_set_rate_limit(status_get->rate_limit); | 390 | audit_set_rate_limit(status_get->rate_limit, loginuid); |
389 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 391 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
390 | audit_set_backlog_limit(status_get->backlog_limit); | 392 | audit_set_backlog_limit(status_get->backlog_limit, |
393 | loginuid); | ||
391 | break; | 394 | break; |
392 | case AUDIT_USER: | 395 | case AUDIT_USER: |
393 | ab = audit_log_start(NULL); | 396 | ab = audit_log_start(NULL); |
394 | if (!ab) | 397 | if (!ab) |
395 | break; /* audit_panic has been called */ | 398 | break; /* audit_panic has been called */ |
396 | audit_log_format(ab, | 399 | audit_log_format(ab, |
397 | "user pid=%d uid=%d length=%d msg='%.1024s'", | 400 | "user pid=%d uid=%d length=%d loginuid=%u" |
401 | " msg='%.1024s'", | ||
398 | pid, uid, | 402 | pid, uid, |
399 | (int)(nlh->nlmsg_len | 403 | (int)(nlh->nlmsg_len |
400 | - ((char *)data - (char *)nlh)), | 404 | - ((char *)data - (char *)nlh)), |
401 | (char *)data); | 405 | loginuid, (char *)data); |
402 | ab->type = AUDIT_USER; | 406 | ab->type = AUDIT_USER; |
403 | ab->pid = pid; | 407 | ab->pid = pid; |
404 | audit_log_end(ab); | 408 | audit_log_end(ab); |
@@ -411,7 +415,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
411 | case AUDIT_LIST: | 415 | case AUDIT_LIST: |
412 | #ifdef CONFIG_AUDITSYSCALL | 416 | #ifdef CONFIG_AUDITSYSCALL |
413 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 417 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
414 | uid, seq, data); | 418 | uid, seq, data, loginuid); |
415 | #else | 419 | #else |
416 | err = -EOPNOTSUPP; | 420 | err = -EOPNOTSUPP; |
417 | #endif | 421 | #endif |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 9ff2c1b1033e..66148f81d783 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -251,7 +251,8 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s) | |||
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
253 | 253 | ||
254 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data) | 254 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
255 | uid_t loginuid) | ||
255 | { | 256 | { |
256 | u32 flags; | 257 | u32 flags; |
257 | struct audit_entry *entry; | 258 | struct audit_entry *entry; |
@@ -286,6 +287,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data) | |||
286 | err = audit_add_rule(entry, &audit_entlist); | 287 | err = audit_add_rule(entry, &audit_entlist); |
287 | if (!err && (flags & AUDIT_AT_EXIT)) | 288 | if (!err && (flags & AUDIT_AT_EXIT)) |
288 | err = audit_add_rule(entry, &audit_extlist); | 289 | err = audit_add_rule(entry, &audit_extlist); |
290 | audit_log(NULL, "auid %u added an audit rule\n", loginuid); | ||
289 | break; | 291 | break; |
290 | case AUDIT_DEL: | 292 | case AUDIT_DEL: |
291 | flags =((struct audit_rule *)data)->flags; | 293 | flags =((struct audit_rule *)data)->flags; |
@@ -295,6 +297,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data) | |||
295 | err = audit_del_rule(data, &audit_entlist); | 297 | err = audit_del_rule(data, &audit_entlist); |
296 | if (!err && (flags & AUDIT_AT_EXIT)) | 298 | if (!err && (flags & AUDIT_AT_EXIT)) |
297 | err = audit_del_rule(data, &audit_extlist); | 299 | err = audit_del_rule(data, &audit_extlist); |
300 | audit_log(NULL, "auid %u removed an audit rule\n", loginuid); | ||
298 | break; | 301 | break; |
299 | default: | 302 | default: |
300 | return -EINVAL; | 303 | return -EINVAL; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 29a5fd231eac..cb64cff3e339 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -905,6 +905,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
905 | NETLINK_CB(skb).groups = nlk->groups; | 905 | NETLINK_CB(skb).groups = nlk->groups; |
906 | NETLINK_CB(skb).dst_pid = dst_pid; | 906 | NETLINK_CB(skb).dst_pid = dst_pid; |
907 | NETLINK_CB(skb).dst_groups = dst_groups; | 907 | NETLINK_CB(skb).dst_groups = dst_groups; |
908 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context); | ||
908 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 909 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
909 | 910 | ||
910 | /* What can I do? Netlink is asynchronous, so that | 911 | /* What can I do? Netlink is asynchronous, so that |