diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 421 |
1 files changed, 44 insertions, 377 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index a371f857a0a9..3c8a601324a2 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -76,11 +76,6 @@ | |||
76 | #define AUDITSC_SUCCESS 1 | 76 | #define AUDITSC_SUCCESS 1 |
77 | #define AUDITSC_FAILURE 2 | 77 | #define AUDITSC_FAILURE 2 |
78 | 78 | ||
79 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context | ||
80 | * for saving names from getname(). If we get more names we will allocate | ||
81 | * a name dynamically and also add those to the list anchored by names_list. */ | ||
82 | #define AUDIT_NAMES 5 | ||
83 | |||
84 | /* no execve audit message should be longer than this (userspace limits) */ | 79 | /* no execve audit message should be longer than this (userspace limits) */ |
85 | #define MAX_EXECVE_AUDIT_LEN 7500 | 80 | #define MAX_EXECVE_AUDIT_LEN 7500 |
86 | 81 | ||
@@ -90,44 +85,6 @@ int audit_n_rules; | |||
90 | /* determines whether we collect data for signals sent */ | 85 | /* determines whether we collect data for signals sent */ |
91 | int audit_signals; | 86 | int audit_signals; |
92 | 87 | ||
93 | struct audit_cap_data { | ||
94 | kernel_cap_t permitted; | ||
95 | kernel_cap_t inheritable; | ||
96 | union { | ||
97 | unsigned int fE; /* effective bit of a file capability */ | ||
98 | kernel_cap_t effective; /* effective set of a process */ | ||
99 | }; | ||
100 | }; | ||
101 | |||
102 | /* When fs/namei.c:getname() is called, we store the pointer in name and | ||
103 | * we don't let putname() free it (instead we free all of the saved | ||
104 | * pointers at syscall exit time). | ||
105 | * | ||
106 | * Further, in fs/namei.c:path_lookup() we store the inode and device. | ||
107 | */ | ||
108 | struct audit_names { | ||
109 | struct list_head list; /* audit_context->names_list */ | ||
110 | struct filename *name; | ||
111 | unsigned long ino; | ||
112 | dev_t dev; | ||
113 | umode_t mode; | ||
114 | kuid_t uid; | ||
115 | kgid_t gid; | ||
116 | dev_t rdev; | ||
117 | u32 osid; | ||
118 | struct audit_cap_data fcap; | ||
119 | unsigned int fcap_ver; | ||
120 | int name_len; /* number of name's characters to log */ | ||
121 | unsigned char type; /* record type */ | ||
122 | bool name_put; /* call __putname() for this name */ | ||
123 | /* | ||
124 | * This was an allocated audit_names and not from the array of | ||
125 | * names allocated in the task audit context. Thus this name | ||
126 | * should be freed on syscall exit | ||
127 | */ | ||
128 | bool should_free; | ||
129 | }; | ||
130 | |||
131 | struct audit_aux_data { | 88 | struct audit_aux_data { |
132 | struct audit_aux_data *next; | 89 | struct audit_aux_data *next; |
133 | int type; | 90 | int type; |
@@ -175,106 +132,6 @@ struct audit_tree_refs { | |||
175 | struct audit_chunk *c[31]; | 132 | struct audit_chunk *c[31]; |
176 | }; | 133 | }; |
177 | 134 | ||
178 | /* The per-task audit context. */ | ||
179 | struct audit_context { | ||
180 | int dummy; /* must be the first element */ | ||
181 | int in_syscall; /* 1 if task is in a syscall */ | ||
182 | enum audit_state state, current_state; | ||
183 | unsigned int serial; /* serial number for record */ | ||
184 | int major; /* syscall number */ | ||
185 | struct timespec ctime; /* time of syscall entry */ | ||
186 | unsigned long argv[4]; /* syscall arguments */ | ||
187 | long return_code;/* syscall return code */ | ||
188 | u64 prio; | ||
189 | int return_valid; /* return code is valid */ | ||
190 | /* | ||
191 | * The names_list is the list of all audit_names collected during this | ||
192 | * syscall. The first AUDIT_NAMES entries in the names_list will | ||
193 | * actually be from the preallocated_names array for performance | ||
194 | * reasons. Except during allocation they should never be referenced | ||
195 | * through the preallocated_names array and should only be found/used | ||
196 | * by running the names_list. | ||
197 | */ | ||
198 | struct audit_names preallocated_names[AUDIT_NAMES]; | ||
199 | int name_count; /* total records in names_list */ | ||
200 | struct list_head names_list; /* anchor for struct audit_names->list */ | ||
201 | char * filterkey; /* key for rule that triggered record */ | ||
202 | struct path pwd; | ||
203 | struct audit_aux_data *aux; | ||
204 | struct audit_aux_data *aux_pids; | ||
205 | struct sockaddr_storage *sockaddr; | ||
206 | size_t sockaddr_len; | ||
207 | /* Save things to print about task_struct */ | ||
208 | pid_t pid, ppid; | ||
209 | kuid_t uid, euid, suid, fsuid; | ||
210 | kgid_t gid, egid, sgid, fsgid; | ||
211 | unsigned long personality; | ||
212 | int arch; | ||
213 | |||
214 | pid_t target_pid; | ||
215 | kuid_t target_auid; | ||
216 | kuid_t target_uid; | ||
217 | unsigned int target_sessionid; | ||
218 | u32 target_sid; | ||
219 | char target_comm[TASK_COMM_LEN]; | ||
220 | |||
221 | struct audit_tree_refs *trees, *first_trees; | ||
222 | struct list_head killed_trees; | ||
223 | int tree_count; | ||
224 | |||
225 | int type; | ||
226 | union { | ||
227 | struct { | ||
228 | int nargs; | ||
229 | long args[6]; | ||
230 | } socketcall; | ||
231 | struct { | ||
232 | kuid_t uid; | ||
233 | kgid_t gid; | ||
234 | umode_t mode; | ||
235 | u32 osid; | ||
236 | int has_perm; | ||
237 | uid_t perm_uid; | ||
238 | gid_t perm_gid; | ||
239 | umode_t perm_mode; | ||
240 | unsigned long qbytes; | ||
241 | } ipc; | ||
242 | struct { | ||
243 | mqd_t mqdes; | ||
244 | struct mq_attr mqstat; | ||
245 | } mq_getsetattr; | ||
246 | struct { | ||
247 | mqd_t mqdes; | ||
248 | int sigev_signo; | ||
249 | } mq_notify; | ||
250 | struct { | ||
251 | mqd_t mqdes; | ||
252 | size_t msg_len; | ||
253 | unsigned int msg_prio; | ||
254 | struct timespec abs_timeout; | ||
255 | } mq_sendrecv; | ||
256 | struct { | ||
257 | int oflag; | ||
258 | umode_t mode; | ||
259 | struct mq_attr attr; | ||
260 | } mq_open; | ||
261 | struct { | ||
262 | pid_t pid; | ||
263 | struct audit_cap_data cap; | ||
264 | } capset; | ||
265 | struct { | ||
266 | int fd; | ||
267 | int flags; | ||
268 | } mmap; | ||
269 | }; | ||
270 | int fds[2]; | ||
271 | |||
272 | #if AUDIT_DEBUG | ||
273 | int put_count; | ||
274 | int ino_count; | ||
275 | #endif | ||
276 | }; | ||
277 | |||
278 | static inline int open_arg(int flags, int mask) | 135 | static inline int open_arg(int flags, int mask) |
279 | { | 136 | { |
280 | int n = ACC_MODE(flags); | 137 | int n = ACC_MODE(flags); |
@@ -633,9 +490,23 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
633 | break; | 490 | break; |
634 | case AUDIT_GID: | 491 | case AUDIT_GID: |
635 | result = audit_gid_comparator(cred->gid, f->op, f->gid); | 492 | result = audit_gid_comparator(cred->gid, f->op, f->gid); |
493 | if (f->op == Audit_equal) { | ||
494 | if (!result) | ||
495 | result = in_group_p(f->gid); | ||
496 | } else if (f->op == Audit_not_equal) { | ||
497 | if (result) | ||
498 | result = !in_group_p(f->gid); | ||
499 | } | ||
636 | break; | 500 | break; |
637 | case AUDIT_EGID: | 501 | case AUDIT_EGID: |
638 | result = audit_gid_comparator(cred->egid, f->op, f->gid); | 502 | result = audit_gid_comparator(cred->egid, f->op, f->gid); |
503 | if (f->op == Audit_equal) { | ||
504 | if (!result) | ||
505 | result = in_egroup_p(f->gid); | ||
506 | } else if (f->op == Audit_not_equal) { | ||
507 | if (result) | ||
508 | result = !in_egroup_p(f->gid); | ||
509 | } | ||
639 | break; | 510 | break; |
640 | case AUDIT_SGID: | 511 | case AUDIT_SGID: |
641 | result = audit_gid_comparator(cred->sgid, f->op, f->gid); | 512 | result = audit_gid_comparator(cred->sgid, f->op, f->gid); |
@@ -742,6 +613,9 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
742 | if (ctx) | 613 | if (ctx) |
743 | result = audit_uid_comparator(tsk->loginuid, f->op, f->uid); | 614 | result = audit_uid_comparator(tsk->loginuid, f->op, f->uid); |
744 | break; | 615 | break; |
616 | case AUDIT_LOGINUID_SET: | ||
617 | result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val); | ||
618 | break; | ||
745 | case AUDIT_SUBJ_USER: | 619 | case AUDIT_SUBJ_USER: |
746 | case AUDIT_SUBJ_ROLE: | 620 | case AUDIT_SUBJ_ROLE: |
747 | case AUDIT_SUBJ_TYPE: | 621 | case AUDIT_SUBJ_TYPE: |
@@ -987,6 +861,8 @@ static inline void audit_free_names(struct audit_context *context) | |||
987 | 861 | ||
988 | #if AUDIT_DEBUG == 2 | 862 | #if AUDIT_DEBUG == 2 |
989 | if (context->put_count + context->ino_count != context->name_count) { | 863 | if (context->put_count + context->ino_count != context->name_count) { |
864 | int i = 0; | ||
865 | |||
990 | printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d" | 866 | printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d" |
991 | " name_count=%d put_count=%d" | 867 | " name_count=%d put_count=%d" |
992 | " ino_count=%d [NOT freeing]\n", | 868 | " ino_count=%d [NOT freeing]\n", |
@@ -995,7 +871,7 @@ static inline void audit_free_names(struct audit_context *context) | |||
995 | context->name_count, context->put_count, | 871 | context->name_count, context->put_count, |
996 | context->ino_count); | 872 | context->ino_count); |
997 | list_for_each_entry(n, &context->names_list, list) { | 873 | list_for_each_entry(n, &context->names_list, list) { |
998 | printk(KERN_ERR "names[%d] = %p = %s\n", i, | 874 | printk(KERN_ERR "names[%d] = %p = %s\n", i++, |
999 | n->name, n->name->name ?: "(null)"); | 875 | n->name, n->name->name ?: "(null)"); |
1000 | } | 876 | } |
1001 | dump_stack(); | 877 | dump_stack(); |
@@ -1010,7 +886,7 @@ static inline void audit_free_names(struct audit_context *context) | |||
1010 | list_for_each_entry_safe(n, next, &context->names_list, list) { | 886 | list_for_each_entry_safe(n, next, &context->names_list, list) { |
1011 | list_del(&n->list); | 887 | list_del(&n->list); |
1012 | if (n->name && n->name_put) | 888 | if (n->name && n->name_put) |
1013 | __putname(n->name); | 889 | final_putname(n->name); |
1014 | if (n->should_free) | 890 | if (n->should_free) |
1015 | kfree(n); | 891 | kfree(n); |
1016 | } | 892 | } |
@@ -1034,21 +910,15 @@ static inline void audit_free_aux(struct audit_context *context) | |||
1034 | } | 910 | } |
1035 | } | 911 | } |
1036 | 912 | ||
1037 | static inline void audit_zero_context(struct audit_context *context, | ||
1038 | enum audit_state state) | ||
1039 | { | ||
1040 | memset(context, 0, sizeof(*context)); | ||
1041 | context->state = state; | ||
1042 | context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0; | ||
1043 | } | ||
1044 | |||
1045 | static inline struct audit_context *audit_alloc_context(enum audit_state state) | 913 | static inline struct audit_context *audit_alloc_context(enum audit_state state) |
1046 | { | 914 | { |
1047 | struct audit_context *context; | 915 | struct audit_context *context; |
1048 | 916 | ||
1049 | if (!(context = kmalloc(sizeof(*context), GFP_KERNEL))) | 917 | context = kzalloc(sizeof(*context), GFP_KERNEL); |
918 | if (!context) | ||
1050 | return NULL; | 919 | return NULL; |
1051 | audit_zero_context(context, state); | 920 | context->state = state; |
921 | context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0; | ||
1052 | INIT_LIST_HEAD(&context->killed_trees); | 922 | INIT_LIST_HEAD(&context->killed_trees); |
1053 | INIT_LIST_HEAD(&context->names_list); | 923 | INIT_LIST_HEAD(&context->names_list); |
1054 | return context; | 924 | return context; |
@@ -1099,88 +969,6 @@ static inline void audit_free_context(struct audit_context *context) | |||
1099 | kfree(context); | 969 | kfree(context); |
1100 | } | 970 | } |
1101 | 971 | ||
1102 | void audit_log_task_context(struct audit_buffer *ab) | ||
1103 | { | ||
1104 | char *ctx = NULL; | ||
1105 | unsigned len; | ||
1106 | int error; | ||
1107 | u32 sid; | ||
1108 | |||
1109 | security_task_getsecid(current, &sid); | ||
1110 | if (!sid) | ||
1111 | return; | ||
1112 | |||
1113 | error = security_secid_to_secctx(sid, &ctx, &len); | ||
1114 | if (error) { | ||
1115 | if (error != -EINVAL) | ||
1116 | goto error_path; | ||
1117 | return; | ||
1118 | } | ||
1119 | |||
1120 | audit_log_format(ab, " subj=%s", ctx); | ||
1121 | security_release_secctx(ctx, len); | ||
1122 | return; | ||
1123 | |||
1124 | error_path: | ||
1125 | audit_panic("error in audit_log_task_context"); | ||
1126 | return; | ||
1127 | } | ||
1128 | |||
1129 | EXPORT_SYMBOL(audit_log_task_context); | ||
1130 | |||
1131 | void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | ||
1132 | { | ||
1133 | const struct cred *cred; | ||
1134 | char name[sizeof(tsk->comm)]; | ||
1135 | struct mm_struct *mm = tsk->mm; | ||
1136 | char *tty; | ||
1137 | |||
1138 | if (!ab) | ||
1139 | return; | ||
1140 | |||
1141 | /* tsk == current */ | ||
1142 | cred = current_cred(); | ||
1143 | |||
1144 | spin_lock_irq(&tsk->sighand->siglock); | ||
1145 | if (tsk->signal && tsk->signal->tty) | ||
1146 | tty = tsk->signal->tty->name; | ||
1147 | else | ||
1148 | tty = "(none)"; | ||
1149 | spin_unlock_irq(&tsk->sighand->siglock); | ||
1150 | |||
1151 | |||
1152 | audit_log_format(ab, | ||
1153 | " ppid=%ld pid=%d auid=%u uid=%u gid=%u" | ||
1154 | " euid=%u suid=%u fsuid=%u" | ||
1155 | " egid=%u sgid=%u fsgid=%u ses=%u tty=%s", | ||
1156 | sys_getppid(), | ||
1157 | tsk->pid, | ||
1158 | from_kuid(&init_user_ns, tsk->loginuid), | ||
1159 | from_kuid(&init_user_ns, cred->uid), | ||
1160 | from_kgid(&init_user_ns, cred->gid), | ||
1161 | from_kuid(&init_user_ns, cred->euid), | ||
1162 | from_kuid(&init_user_ns, cred->suid), | ||
1163 | from_kuid(&init_user_ns, cred->fsuid), | ||
1164 | from_kgid(&init_user_ns, cred->egid), | ||
1165 | from_kgid(&init_user_ns, cred->sgid), | ||
1166 | from_kgid(&init_user_ns, cred->fsgid), | ||
1167 | tsk->sessionid, tty); | ||
1168 | |||
1169 | get_task_comm(name, tsk); | ||
1170 | audit_log_format(ab, " comm="); | ||
1171 | audit_log_untrustedstring(ab, name); | ||
1172 | |||
1173 | if (mm) { | ||
1174 | down_read(&mm->mmap_sem); | ||
1175 | if (mm->exe_file) | ||
1176 | audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); | ||
1177 | up_read(&mm->mmap_sem); | ||
1178 | } | ||
1179 | audit_log_task_context(ab); | ||
1180 | } | ||
1181 | |||
1182 | EXPORT_SYMBOL(audit_log_task_info); | ||
1183 | |||
1184 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, | 972 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, |
1185 | kuid_t auid, kuid_t uid, unsigned int sessionid, | 973 | kuid_t auid, kuid_t uid, unsigned int sessionid, |
1186 | u32 sid, char *comm) | 974 | u32 sid, char *comm) |
@@ -1197,12 +985,14 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, | |||
1197 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, | 985 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, |
1198 | from_kuid(&init_user_ns, auid), | 986 | from_kuid(&init_user_ns, auid), |
1199 | from_kuid(&init_user_ns, uid), sessionid); | 987 | from_kuid(&init_user_ns, uid), sessionid); |
1200 | if (security_secid_to_secctx(sid, &ctx, &len)) { | 988 | if (sid) { |
1201 | audit_log_format(ab, " obj=(none)"); | 989 | if (security_secid_to_secctx(sid, &ctx, &len)) { |
1202 | rc = 1; | 990 | audit_log_format(ab, " obj=(none)"); |
1203 | } else { | 991 | rc = 1; |
1204 | audit_log_format(ab, " obj=%s", ctx); | 992 | } else { |
1205 | security_release_secctx(ctx, len); | 993 | audit_log_format(ab, " obj=%s", ctx); |
994 | security_release_secctx(ctx, len); | ||
995 | } | ||
1206 | } | 996 | } |
1207 | audit_log_format(ab, " ocomm="); | 997 | audit_log_format(ab, " ocomm="); |
1208 | audit_log_untrustedstring(ab, comm); | 998 | audit_log_untrustedstring(ab, comm); |
@@ -1396,35 +1186,6 @@ static void audit_log_execve_info(struct audit_context *context, | |||
1396 | kfree(buf); | 1186 | kfree(buf); |
1397 | } | 1187 | } |
1398 | 1188 | ||
1399 | static void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) | ||
1400 | { | ||
1401 | int i; | ||
1402 | |||
1403 | audit_log_format(ab, " %s=", prefix); | ||
1404 | CAP_FOR_EACH_U32(i) { | ||
1405 | audit_log_format(ab, "%08x", cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]); | ||
1406 | } | ||
1407 | } | ||
1408 | |||
1409 | static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) | ||
1410 | { | ||
1411 | kernel_cap_t *perm = &name->fcap.permitted; | ||
1412 | kernel_cap_t *inh = &name->fcap.inheritable; | ||
1413 | int log = 0; | ||
1414 | |||
1415 | if (!cap_isclear(*perm)) { | ||
1416 | audit_log_cap(ab, "cap_fp", perm); | ||
1417 | log = 1; | ||
1418 | } | ||
1419 | if (!cap_isclear(*inh)) { | ||
1420 | audit_log_cap(ab, "cap_fi", inh); | ||
1421 | log = 1; | ||
1422 | } | ||
1423 | |||
1424 | if (log) | ||
1425 | audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); | ||
1426 | } | ||
1427 | |||
1428 | static void show_special(struct audit_context *context, int *call_panic) | 1189 | static void show_special(struct audit_context *context, int *call_panic) |
1429 | { | 1190 | { |
1430 | struct audit_buffer *ab; | 1191 | struct audit_buffer *ab; |
@@ -1522,68 +1283,6 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1522 | audit_log_end(ab); | 1283 | audit_log_end(ab); |
1523 | } | 1284 | } |
1524 | 1285 | ||
1525 | static void audit_log_name(struct audit_context *context, struct audit_names *n, | ||
1526 | int record_num, int *call_panic) | ||
1527 | { | ||
1528 | struct audit_buffer *ab; | ||
1529 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); | ||
1530 | if (!ab) | ||
1531 | return; /* audit_panic has been called */ | ||
1532 | |||
1533 | audit_log_format(ab, "item=%d", record_num); | ||
1534 | |||
1535 | if (n->name) { | ||
1536 | switch (n->name_len) { | ||
1537 | case AUDIT_NAME_FULL: | ||
1538 | /* log the full path */ | ||
1539 | audit_log_format(ab, " name="); | ||
1540 | audit_log_untrustedstring(ab, n->name->name); | ||
1541 | break; | ||
1542 | case 0: | ||
1543 | /* name was specified as a relative path and the | ||
1544 | * directory component is the cwd */ | ||
1545 | audit_log_d_path(ab, " name=", &context->pwd); | ||
1546 | break; | ||
1547 | default: | ||
1548 | /* log the name's directory component */ | ||
1549 | audit_log_format(ab, " name="); | ||
1550 | audit_log_n_untrustedstring(ab, n->name->name, | ||
1551 | n->name_len); | ||
1552 | } | ||
1553 | } else | ||
1554 | audit_log_format(ab, " name=(null)"); | ||
1555 | |||
1556 | if (n->ino != (unsigned long)-1) { | ||
1557 | audit_log_format(ab, " inode=%lu" | ||
1558 | " dev=%02x:%02x mode=%#ho" | ||
1559 | " ouid=%u ogid=%u rdev=%02x:%02x", | ||
1560 | n->ino, | ||
1561 | MAJOR(n->dev), | ||
1562 | MINOR(n->dev), | ||
1563 | n->mode, | ||
1564 | from_kuid(&init_user_ns, n->uid), | ||
1565 | from_kgid(&init_user_ns, n->gid), | ||
1566 | MAJOR(n->rdev), | ||
1567 | MINOR(n->rdev)); | ||
1568 | } | ||
1569 | if (n->osid != 0) { | ||
1570 | char *ctx = NULL; | ||
1571 | u32 len; | ||
1572 | if (security_secid_to_secctx( | ||
1573 | n->osid, &ctx, &len)) { | ||
1574 | audit_log_format(ab, " osid=%u", n->osid); | ||
1575 | *call_panic = 2; | ||
1576 | } else { | ||
1577 | audit_log_format(ab, " obj=%s", ctx); | ||
1578 | security_release_secctx(ctx, len); | ||
1579 | } | ||
1580 | } | ||
1581 | |||
1582 | audit_log_fcaps(ab, n); | ||
1583 | |||
1584 | audit_log_end(ab); | ||
1585 | } | ||
1586 | |||
1587 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1286 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
1588 | { | 1287 | { |
1589 | int i, call_panic = 0; | 1288 | int i, call_panic = 0; |
@@ -1701,7 +1400,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1701 | 1400 | ||
1702 | i = 0; | 1401 | i = 0; |
1703 | list_for_each_entry(n, &context->names_list, list) | 1402 | list_for_each_entry(n, &context->names_list, list) |
1704 | audit_log_name(context, n, i++, &call_panic); | 1403 | audit_log_name(context, n, NULL, i++, &call_panic); |
1705 | 1404 | ||
1706 | /* Send end of event record to help user space know we are finished */ | 1405 | /* Send end of event record to help user space know we are finished */ |
1707 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); | 1406 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); |
@@ -2036,18 +1735,18 @@ void audit_putname(struct filename *name) | |||
2036 | BUG_ON(!context); | 1735 | BUG_ON(!context); |
2037 | if (!context->in_syscall) { | 1736 | if (!context->in_syscall) { |
2038 | #if AUDIT_DEBUG == 2 | 1737 | #if AUDIT_DEBUG == 2 |
2039 | printk(KERN_ERR "%s:%d(:%d): __putname(%p)\n", | 1738 | printk(KERN_ERR "%s:%d(:%d): final_putname(%p)\n", |
2040 | __FILE__, __LINE__, context->serial, name); | 1739 | __FILE__, __LINE__, context->serial, name); |
2041 | if (context->name_count) { | 1740 | if (context->name_count) { |
2042 | struct audit_names *n; | 1741 | struct audit_names *n; |
2043 | int i; | 1742 | int i = 0; |
2044 | 1743 | ||
2045 | list_for_each_entry(n, &context->names_list, list) | 1744 | list_for_each_entry(n, &context->names_list, list) |
2046 | printk(KERN_ERR "name[%d] = %p = %s\n", i, | 1745 | printk(KERN_ERR "name[%d] = %p = %s\n", i++, |
2047 | n->name, n->name->name ?: "(null)"); | 1746 | n->name, n->name->name ?: "(null)"); |
2048 | } | 1747 | } |
2049 | #endif | 1748 | #endif |
2050 | __putname(name); | 1749 | final_putname(name); |
2051 | } | 1750 | } |
2052 | #if AUDIT_DEBUG | 1751 | #if AUDIT_DEBUG |
2053 | else { | 1752 | else { |
@@ -2066,41 +1765,6 @@ void audit_putname(struct filename *name) | |||
2066 | #endif | 1765 | #endif |
2067 | } | 1766 | } |
2068 | 1767 | ||
2069 | static inline int audit_copy_fcaps(struct audit_names *name, const struct dentry *dentry) | ||
2070 | { | ||
2071 | struct cpu_vfs_cap_data caps; | ||
2072 | int rc; | ||
2073 | |||
2074 | if (!dentry) | ||
2075 | return 0; | ||
2076 | |||
2077 | rc = get_vfs_caps_from_disk(dentry, &caps); | ||
2078 | if (rc) | ||
2079 | return rc; | ||
2080 | |||
2081 | name->fcap.permitted = caps.permitted; | ||
2082 | name->fcap.inheritable = caps.inheritable; | ||
2083 | name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); | ||
2084 | name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT; | ||
2085 | |||
2086 | return 0; | ||
2087 | } | ||
2088 | |||
2089 | |||
2090 | /* Copy inode data into an audit_names. */ | ||
2091 | static void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, | ||
2092 | const struct inode *inode) | ||
2093 | { | ||
2094 | name->ino = inode->i_ino; | ||
2095 | name->dev = inode->i_sb->s_dev; | ||
2096 | name->mode = inode->i_mode; | ||
2097 | name->uid = inode->i_uid; | ||
2098 | name->gid = inode->i_gid; | ||
2099 | name->rdev = inode->i_rdev; | ||
2100 | security_inode_getsecid(inode, &name->osid); | ||
2101 | audit_copy_fcaps(name, dentry); | ||
2102 | } | ||
2103 | |||
2104 | /** | 1768 | /** |
2105 | * __audit_inode - store the inode and device from a lookup | 1769 | * __audit_inode - store the inode and device from a lookup |
2106 | * @name: name being audited | 1770 | * @name: name being audited |
@@ -2309,7 +1973,7 @@ int audit_set_loginuid(kuid_t loginuid) | |||
2309 | unsigned int sessionid; | 1973 | unsigned int sessionid; |
2310 | 1974 | ||
2311 | #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE | 1975 | #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE |
2312 | if (uid_valid(task->loginuid)) | 1976 | if (audit_loginuid_set(task)) |
2313 | return -EPERM; | 1977 | return -EPERM; |
2314 | #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */ | 1978 | #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */ |
2315 | if (!capable(CAP_AUDIT_CONTROL)) | 1979 | if (!capable(CAP_AUDIT_CONTROL)) |
@@ -2477,17 +2141,20 @@ int __audit_bprm(struct linux_binprm *bprm) | |||
2477 | 2141 | ||
2478 | /** | 2142 | /** |
2479 | * audit_socketcall - record audit data for sys_socketcall | 2143 | * audit_socketcall - record audit data for sys_socketcall |
2480 | * @nargs: number of args | 2144 | * @nargs: number of args, which should not be more than AUDITSC_ARGS. |
2481 | * @args: args array | 2145 | * @args: args array |
2482 | * | 2146 | * |
2483 | */ | 2147 | */ |
2484 | void __audit_socketcall(int nargs, unsigned long *args) | 2148 | int __audit_socketcall(int nargs, unsigned long *args) |
2485 | { | 2149 | { |
2486 | struct audit_context *context = current->audit_context; | 2150 | struct audit_context *context = current->audit_context; |
2487 | 2151 | ||
2152 | if (nargs <= 0 || nargs > AUDITSC_ARGS || !args) | ||
2153 | return -EINVAL; | ||
2488 | context->type = AUDIT_SOCKETCALL; | 2154 | context->type = AUDIT_SOCKETCALL; |
2489 | context->socketcall.nargs = nargs; | 2155 | context->socketcall.nargs = nargs; |
2490 | memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long)); | 2156 | memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long)); |
2157 | return 0; | ||
2491 | } | 2158 | } |
2492 | 2159 | ||
2493 | /** | 2160 | /** |