diff options
Diffstat (limited to 'kernel/auditfilter.c')
| -rw-r--r-- | kernel/auditfilter.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 14a78cca384e..8e9bc9c3dbb7 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
| 23 | #include <linux/audit.h> | 25 | #include <linux/audit.h> |
| 24 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
| @@ -29,6 +31,8 @@ | |||
| 29 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
| 30 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 31 | #include <linux/security.h> | 33 | #include <linux/security.h> |
| 34 | #include <net/net_namespace.h> | ||
| 35 | #include <net/sock.h> | ||
| 32 | #include "audit.h" | 36 | #include "audit.h" |
| 33 | 37 | ||
| 34 | /* | 38 | /* |
| @@ -224,7 +228,7 @@ static int audit_match_signal(struct audit_entry *entry) | |||
| 224 | #endif | 228 | #endif |
| 225 | 229 | ||
| 226 | /* Common user-space to kernel rule translation. */ | 230 | /* Common user-space to kernel rule translation. */ |
| 227 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | 231 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule_data *rule) |
| 228 | { | 232 | { |
| 229 | unsigned listnr; | 233 | unsigned listnr; |
| 230 | struct audit_entry *entry; | 234 | struct audit_entry *entry; |
| @@ -247,7 +251,7 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | |||
| 247 | ; | 251 | ; |
| 248 | } | 252 | } |
| 249 | if (unlikely(rule->action == AUDIT_POSSIBLE)) { | 253 | if (unlikely(rule->action == AUDIT_POSSIBLE)) { |
| 250 | printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n"); | 254 | pr_err("AUDIT_POSSIBLE is deprecated\n"); |
| 251 | goto exit_err; | 255 | goto exit_err; |
| 252 | } | 256 | } |
| 253 | if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS) | 257 | if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS) |
| @@ -401,7 +405,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 401 | int i; | 405 | int i; |
| 402 | char *str; | 406 | char *str; |
| 403 | 407 | ||
| 404 | entry = audit_to_entry_common((struct audit_rule *)data); | 408 | entry = audit_to_entry_common(data); |
| 405 | if (IS_ERR(entry)) | 409 | if (IS_ERR(entry)) |
| 406 | goto exit_nofree; | 410 | goto exit_nofree; |
| 407 | 411 | ||
| @@ -429,6 +433,19 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 429 | f->val = 0; | 433 | f->val = 0; |
| 430 | } | 434 | } |
| 431 | 435 | ||
| 436 | if ((f->type == AUDIT_PID) || (f->type == AUDIT_PPID)) { | ||
| 437 | struct pid *pid; | ||
| 438 | rcu_read_lock(); | ||
| 439 | pid = find_vpid(f->val); | ||
| 440 | if (!pid) { | ||
| 441 | rcu_read_unlock(); | ||
| 442 | err = -ESRCH; | ||
| 443 | goto exit_free; | ||
| 444 | } | ||
| 445 | f->val = pid_nr(pid); | ||
| 446 | rcu_read_unlock(); | ||
| 447 | } | ||
| 448 | |||
| 432 | err = audit_field_valid(entry, f); | 449 | err = audit_field_valid(entry, f); |
| 433 | if (err) | 450 | if (err) |
| 434 | goto exit_free; | 451 | goto exit_free; |
| @@ -477,8 +494,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 477 | /* Keep currently invalid fields around in case they | 494 | /* Keep currently invalid fields around in case they |
| 478 | * become valid after a policy reload. */ | 495 | * become valid after a policy reload. */ |
| 479 | if (err == -EINVAL) { | 496 | if (err == -EINVAL) { |
| 480 | printk(KERN_WARNING "audit rule for LSM " | 497 | pr_warn("audit rule for LSM \'%s\' is invalid\n", |
| 481 | "\'%s\' is invalid\n", str); | 498 | str); |
| 482 | err = 0; | 499 | err = 0; |
| 483 | } | 500 | } |
| 484 | if (err) { | 501 | if (err) { |
| @@ -707,8 +724,8 @@ static inline int audit_dupe_lsm_field(struct audit_field *df, | |||
| 707 | /* Keep currently invalid fields around in case they | 724 | /* Keep currently invalid fields around in case they |
| 708 | * become valid after a policy reload. */ | 725 | * become valid after a policy reload. */ |
| 709 | if (ret == -EINVAL) { | 726 | if (ret == -EINVAL) { |
| 710 | printk(KERN_WARNING "audit rule for LSM \'%s\' is " | 727 | pr_warn("audit rule for LSM \'%s\' is invalid\n", |
| 711 | "invalid\n", df->lsm_str); | 728 | df->lsm_str); |
| 712 | ret = 0; | 729 | ret = 0; |
| 713 | } | 730 | } |
| 714 | 731 | ||
| @@ -1065,11 +1082,13 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data, | |||
| 1065 | 1082 | ||
| 1066 | /** | 1083 | /** |
| 1067 | * audit_list_rules_send - list the audit rules | 1084 | * audit_list_rules_send - list the audit rules |
| 1068 | * @portid: target portid for netlink audit messages | 1085 | * @request_skb: skb of request we are replying to (used to target the reply) |
| 1069 | * @seq: netlink audit message sequence (serial) number | 1086 | * @seq: netlink audit message sequence (serial) number |
| 1070 | */ | 1087 | */ |
| 1071 | int audit_list_rules_send(__u32 portid, int seq) | 1088 | int audit_list_rules_send(struct sk_buff *request_skb, int seq) |
| 1072 | { | 1089 | { |
| 1090 | u32 portid = NETLINK_CB(request_skb).portid; | ||
| 1091 | struct net *net = sock_net(NETLINK_CB(request_skb).sk); | ||
| 1073 | struct task_struct *tsk; | 1092 | struct task_struct *tsk; |
| 1074 | struct audit_netlink_list *dest; | 1093 | struct audit_netlink_list *dest; |
| 1075 | int err = 0; | 1094 | int err = 0; |
| @@ -1083,8 +1102,8 @@ int audit_list_rules_send(__u32 portid, int seq) | |||
| 1083 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | 1102 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); |
| 1084 | if (!dest) | 1103 | if (!dest) |
| 1085 | return -ENOMEM; | 1104 | return -ENOMEM; |
| 1105 | dest->net = get_net(net); | ||
| 1086 | dest->portid = portid; | 1106 | dest->portid = portid; |
| 1087 | dest->pid = task_pid_vnr(current); | ||
| 1088 | skb_queue_head_init(&dest->q); | 1107 | skb_queue_head_init(&dest->q); |
| 1089 | 1108 | ||
| 1090 | mutex_lock(&audit_filter_mutex); | 1109 | mutex_lock(&audit_filter_mutex); |
| @@ -1236,12 +1255,14 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type, | |||
| 1236 | 1255 | ||
| 1237 | for (i = 0; i < rule->field_count; i++) { | 1256 | for (i = 0; i < rule->field_count; i++) { |
| 1238 | struct audit_field *f = &rule->fields[i]; | 1257 | struct audit_field *f = &rule->fields[i]; |
| 1258 | pid_t pid; | ||
| 1239 | int result = 0; | 1259 | int result = 0; |
| 1240 | u32 sid; | 1260 | u32 sid; |
| 1241 | 1261 | ||
| 1242 | switch (f->type) { | 1262 | switch (f->type) { |
| 1243 | case AUDIT_PID: | 1263 | case AUDIT_PID: |
| 1244 | result = audit_comparator(task_pid_vnr(current), f->op, f->val); | 1264 | pid = task_pid_nr(current); |
| 1265 | result = audit_comparator(pid, f->op, f->val); | ||
| 1245 | break; | 1266 | break; |
| 1246 | case AUDIT_UID: | 1267 | case AUDIT_UID: |
| 1247 | result = audit_uid_comparator(current_uid(), f->op, f->uid); | 1268 | result = audit_uid_comparator(current_uid(), f->op, f->uid); |
