]>
Commit | Line | Data |
---|---|---|
b0d623f7 | 1 | /*- |
39037602 | 2 | * Copyright (c) 1999-2016 Apple Inc. |
b0d623f7 A |
3 | * All rights reserved. |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. Neither the name of Apple Inc. ("Apple") nor the names of | |
14 | * its contributors may be used to endorse or promote products derived | |
15 | * from this software without specific prior written permission. | |
16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND | |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR | |
21 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
25 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 | * POSSIBILITY OF SUCH DAMAGE. | |
28 | * | |
29 | */ | |
30 | /* | |
31 | * NOTICE: This file was modified by McAfee Research in 2004 to introduce | |
32 | * support for mandatory and extensible security protections. This notice | |
33 | * is included in support of clause 2.2 (b) of the Apple Public License, | |
34 | * Version 2.0. | |
35 | */ | |
36 | ||
37 | #include <sys/param.h> | |
38 | #include <sys/fcntl.h> | |
39 | #include <sys/kernel.h> | |
40 | #include <sys/lock.h> | |
41 | #include <sys/namei.h> | |
42 | #include <sys/proc_internal.h> | |
43 | #include <sys/kauth.h> | |
44 | #include <sys/queue.h> | |
45 | #include <sys/systm.h> | |
46 | #include <sys/time.h> | |
47 | #include <sys/ucred.h> | |
48 | #include <sys/uio.h> | |
49 | #include <sys/unistd.h> | |
50 | #include <sys/file_internal.h> | |
51 | #include <sys/vnode_internal.h> | |
52 | #include <sys/user.h> | |
53 | #include <sys/syscall.h> | |
54 | #include <sys/malloc.h> | |
55 | #include <sys/un.h> | |
56 | #include <sys/sysent.h> | |
57 | #include <sys/sysproto.h> | |
58 | #include <sys/vfs_context.h> | |
59 | #include <sys/domain.h> | |
60 | #include <sys/protosw.h> | |
61 | #include <sys/socketvar.h> | |
d9a64523 A |
62 | #include <sys/codesign.h> |
63 | #include <sys/ubc.h> | |
b0d623f7 A |
64 | |
65 | #include <bsm/audit.h> | |
66 | #include <bsm/audit_internal.h> | |
67 | #include <bsm/audit_kevents.h> | |
68 | ||
69 | #include <security/audit/audit.h> | |
70 | #include <security/audit/audit_bsd.h> | |
71 | #include <security/audit/audit_private.h> | |
72 | ||
73 | #include <mach/host_priv.h> | |
74 | #include <mach/host_special_ports.h> | |
75 | #include <mach/audit_triggers_server.h> | |
76 | ||
77 | #include <kern/host.h> | |
b0d623f7 | 78 | #include <kern/zalloc.h> |
b0d623f7 A |
79 | #include <kern/sched_prim.h> |
80 | ||
81 | #if CONFIG_MACF | |
82 | #include <bsm/audit_record.h> | |
83 | #include <security/mac.h> | |
84 | #include <security/mac_framework.h> | |
85 | #include <security/mac_policy.h> | |
86 | extern zone_t audit_mac_label_zone; | |
87 | #endif | |
88 | ||
89 | #include <net/route.h> | |
90 | ||
91 | #include <netinet/in.h> | |
92 | #include <netinet/in_pcb.h> | |
93 | ||
94 | #if CONFIG_AUDIT | |
95 | /* | |
96 | * Calls to manipulate elements of the audit record structure from system | |
97 | * call code. Macro wrappers will prevent this functions from being entered | |
98 | * if auditing is disabled, avoiding the function call cost. We check the | |
99 | * thread audit record pointer anyway, as the audit condition could change, | |
100 | * and pre-selection may not have allocated an audit record for this event. | |
101 | * | |
102 | * XXXAUDIT: Should we assert, in each case, that this field of the record | |
103 | * hasn't already been filled in? | |
104 | */ | |
105 | void | |
106 | audit_arg_addr(struct kaudit_record *ar, user_addr_t addr) | |
107 | { | |
108 | struct proc *p = current_proc(); | |
109 | ||
110 | ar->k_ar.ar_arg_addr = addr; | |
111 | ||
112 | /* | |
113 | * If the process is 64-bit then flag the address as such. | |
114 | */ | |
0a7de745 | 115 | if (proc_is64bit(p)) { |
b0d623f7 | 116 | ARG_SET_VALID(ar, ARG_ADDR64); |
0a7de745 | 117 | } else { |
b0d623f7 | 118 | ARG_SET_VALID(ar, ARG_ADDR32); |
0a7de745 | 119 | } |
b0d623f7 A |
120 | } |
121 | ||
122 | void | |
123 | audit_arg_exit(struct kaudit_record *ar, int status, int retval) | |
124 | { | |
b0d623f7 A |
125 | ar->k_ar.ar_arg_exitstatus = status; |
126 | ar->k_ar.ar_arg_exitretval = retval; | |
127 | ARG_SET_VALID(ar, ARG_EXIT); | |
128 | } | |
129 | ||
130 | void | |
131 | audit_arg_len(struct kaudit_record *ar, user_size_t len) | |
132 | { | |
b0d623f7 A |
133 | ar->k_ar.ar_arg_len = len; |
134 | ARG_SET_VALID(ar, ARG_LEN); | |
135 | } | |
136 | ||
39037602 A |
137 | void |
138 | audit_arg_fd2(struct kaudit_record *ar, int fd) | |
139 | { | |
39037602 A |
140 | ar->k_ar.ar_arg_fd2 = fd; |
141 | ARG_SET_VALID(ar, ARG_FD2); | |
142 | } | |
143 | ||
b0d623f7 A |
144 | void |
145 | audit_arg_fd(struct kaudit_record *ar, int fd) | |
146 | { | |
b0d623f7 A |
147 | ar->k_ar.ar_arg_fd = fd; |
148 | ARG_SET_VALID(ar, ARG_FD); | |
149 | } | |
150 | ||
151 | void | |
152 | audit_arg_fflags(struct kaudit_record *ar, int fflags) | |
153 | { | |
b0d623f7 A |
154 | ar->k_ar.ar_arg_fflags = fflags; |
155 | ARG_SET_VALID(ar, ARG_FFLAGS); | |
156 | } | |
157 | ||
158 | void | |
159 | audit_arg_gid(struct kaudit_record *ar, gid_t gid) | |
160 | { | |
b0d623f7 A |
161 | ar->k_ar.ar_arg_gid = gid; |
162 | ARG_SET_VALID(ar, ARG_GID); | |
163 | } | |
164 | ||
165 | void | |
166 | audit_arg_uid(struct kaudit_record *ar, uid_t uid) | |
167 | { | |
b0d623f7 A |
168 | ar->k_ar.ar_arg_uid = uid; |
169 | ARG_SET_VALID(ar, ARG_UID); | |
170 | } | |
171 | ||
172 | void | |
173 | audit_arg_egid(struct kaudit_record *ar, gid_t egid) | |
174 | { | |
b0d623f7 A |
175 | ar->k_ar.ar_arg_egid = egid; |
176 | ARG_SET_VALID(ar, ARG_EGID); | |
177 | } | |
178 | ||
179 | void | |
180 | audit_arg_euid(struct kaudit_record *ar, uid_t euid) | |
181 | { | |
b0d623f7 A |
182 | ar->k_ar.ar_arg_euid = euid; |
183 | ARG_SET_VALID(ar, ARG_EUID); | |
184 | } | |
185 | ||
186 | void | |
187 | audit_arg_rgid(struct kaudit_record *ar, gid_t rgid) | |
188 | { | |
b0d623f7 A |
189 | ar->k_ar.ar_arg_rgid = rgid; |
190 | ARG_SET_VALID(ar, ARG_RGID); | |
191 | } | |
192 | ||
193 | void | |
194 | audit_arg_ruid(struct kaudit_record *ar, uid_t ruid) | |
195 | { | |
b0d623f7 A |
196 | ar->k_ar.ar_arg_ruid = ruid; |
197 | ARG_SET_VALID(ar, ARG_RUID); | |
198 | } | |
199 | ||
200 | void | |
201 | audit_arg_sgid(struct kaudit_record *ar, gid_t sgid) | |
202 | { | |
b0d623f7 A |
203 | ar->k_ar.ar_arg_sgid = sgid; |
204 | ARG_SET_VALID(ar, ARG_SGID); | |
205 | } | |
206 | ||
207 | void | |
208 | audit_arg_suid(struct kaudit_record *ar, uid_t suid) | |
209 | { | |
b0d623f7 A |
210 | ar->k_ar.ar_arg_suid = suid; |
211 | ARG_SET_VALID(ar, ARG_SUID); | |
212 | } | |
213 | ||
214 | void | |
215 | audit_arg_groupset(struct kaudit_record *ar, gid_t *gidset, u_int gidset_size) | |
216 | { | |
217 | u_int i; | |
218 | ||
0a7de745 | 219 | for (i = 0; i < gidset_size; i++) { |
b0d623f7 | 220 | ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; |
0a7de745 | 221 | } |
b0d623f7 A |
222 | ar->k_ar.ar_arg_groups.gidset_size = gidset_size; |
223 | ARG_SET_VALID(ar, ARG_GROUPSET); | |
224 | } | |
225 | ||
226 | void | |
227 | audit_arg_login(struct kaudit_record *ar, char *login) | |
228 | { | |
b0d623f7 A |
229 | strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); |
230 | ARG_SET_VALID(ar, ARG_LOGIN); | |
231 | } | |
232 | ||
233 | void | |
234 | audit_arg_ctlname(struct kaudit_record *ar, int *name, int namelen) | |
235 | { | |
b0d623f7 A |
236 | bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); |
237 | ar->k_ar.ar_arg_len = namelen; | |
238 | ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); | |
239 | } | |
240 | ||
241 | void | |
242 | audit_arg_mask(struct kaudit_record *ar, int mask) | |
243 | { | |
b0d623f7 A |
244 | ar->k_ar.ar_arg_mask = mask; |
245 | ARG_SET_VALID(ar, ARG_MASK); | |
246 | } | |
247 | ||
248 | void | |
249 | audit_arg_mode(struct kaudit_record *ar, mode_t mode) | |
250 | { | |
b0d623f7 A |
251 | ar->k_ar.ar_arg_mode = mode; |
252 | ARG_SET_VALID(ar, ARG_MODE); | |
253 | } | |
254 | ||
255 | void | |
256 | audit_arg_value32(struct kaudit_record *ar, uint32_t value32) | |
257 | { | |
b0d623f7 A |
258 | ar->k_ar.ar_arg_value32 = value32; |
259 | ARG_SET_VALID(ar, ARG_VALUE32); | |
260 | } | |
261 | ||
262 | void | |
263 | audit_arg_value64(struct kaudit_record *ar, uint64_t value64) | |
264 | { | |
b0d623f7 A |
265 | ar->k_ar.ar_arg_value64 = value64; |
266 | ARG_SET_VALID(ar, ARG_VALUE64); | |
267 | } | |
268 | ||
269 | void | |
270 | audit_arg_owner(struct kaudit_record *ar, uid_t uid, gid_t gid) | |
271 | { | |
b0d623f7 A |
272 | ar->k_ar.ar_arg_uid = uid; |
273 | ar->k_ar.ar_arg_gid = gid; | |
274 | ARG_SET_VALID(ar, ARG_UID | ARG_GID); | |
275 | } | |
276 | ||
277 | void | |
278 | audit_arg_pid(struct kaudit_record *ar, pid_t pid) | |
279 | { | |
b0d623f7 A |
280 | ar->k_ar.ar_arg_pid = pid; |
281 | ARG_SET_VALID(ar, ARG_PID); | |
282 | } | |
283 | ||
284 | void | |
285 | audit_arg_process(struct kaudit_record *ar, proc_t p) | |
286 | { | |
287 | kauth_cred_t my_cred; | |
288 | ||
289 | KASSERT(p != NULL, ("audit_arg_process: p == NULL")); | |
290 | ||
0a7de745 | 291 | if (p == NULL) { |
b0d623f7 | 292 | return; |
0a7de745 | 293 | } |
b0d623f7 A |
294 | |
295 | my_cred = kauth_cred_proc_ref(p); | |
296 | ar->k_ar.ar_arg_auid = my_cred->cr_audit.as_aia_p->ai_auid; | |
297 | ar->k_ar.ar_arg_asid = my_cred->cr_audit.as_aia_p->ai_asid; | |
298 | bcopy(&my_cred->cr_audit.as_aia_p->ai_termid, | |
299 | &ar->k_ar.ar_arg_termid_addr, sizeof(au_tid_addr_t)); | |
6d2010ae A |
300 | ar->k_ar.ar_arg_euid = kauth_cred_getuid(my_cred); |
301 | ar->k_ar.ar_arg_egid = kauth_cred_getgid(my_cred); | |
302 | ar->k_ar.ar_arg_ruid = kauth_cred_getruid(my_cred); | |
303 | ar->k_ar.ar_arg_rgid = kauth_cred_getrgid(my_cred); | |
b0d623f7 A |
304 | kauth_cred_unref(&my_cred); |
305 | ar->k_ar.ar_arg_pid = p->p_pid; | |
306 | ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | | |
307 | ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); | |
308 | } | |
309 | ||
310 | void | |
311 | audit_arg_signum(struct kaudit_record *ar, u_int signum) | |
312 | { | |
b0d623f7 A |
313 | ar->k_ar.ar_arg_signum = signum; |
314 | ARG_SET_VALID(ar, ARG_SIGNUM); | |
315 | } | |
316 | ||
317 | void | |
318 | audit_arg_socket(struct kaudit_record *ar, int sodomain, int sotype, | |
319 | int soprotocol) | |
320 | { | |
b0d623f7 A |
321 | ar->k_ar.ar_arg_sockinfo.sai_domain = sodomain; |
322 | ar->k_ar.ar_arg_sockinfo.sai_type = sotype; | |
323 | ar->k_ar.ar_arg_sockinfo.sai_protocol = soprotocol; | |
324 | ARG_SET_VALID(ar, ARG_SOCKINFO); | |
325 | } | |
326 | ||
327 | /* | |
328 | * Note that the current working directory vp must be supplied at the audit | |
329 | * call site to permit per thread current working directories, and that it | |
330 | * must take a upath starting with '/' into account for chroot if the path | |
331 | * is absolute. This results in the real (non-chroot) path being recorded | |
332 | * in the audit record. | |
333 | */ | |
334 | void | |
335 | audit_arg_sockaddr(struct kaudit_record *ar, struct vnode *cwd_vp, | |
336 | struct sockaddr *sa) | |
337 | { | |
00867663 | 338 | char path[SOCK_MAXADDRLEN - offsetof(struct sockaddr_un, sun_path) + 1] = ""; |
b0d623f7 | 339 | struct sockaddr_un *sun; |
00867663 | 340 | ssize_t namelen; |
b0d623f7 A |
341 | |
342 | KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); | |
343 | ||
0a7de745 | 344 | if (cwd_vp == NULL || sa == NULL) { |
b0d623f7 | 345 | return; |
0a7de745 | 346 | } |
b0d623f7 | 347 | |
0a7de745 | 348 | if (sa->sa_len > sizeof(ar->k_ar.ar_arg_sockaddr)) { |
813fb2f6 | 349 | bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sizeof(ar->k_ar.ar_arg_sockaddr)); |
0a7de745 | 350 | } else { |
813fb2f6 | 351 | bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); |
0a7de745 | 352 | } |
813fb2f6 | 353 | |
b0d623f7 A |
354 | switch (sa->sa_family) { |
355 | case AF_INET: | |
356 | ARG_SET_VALID(ar, ARG_SADDRINET); | |
357 | break; | |
358 | ||
359 | case AF_INET6: | |
360 | ARG_SET_VALID(ar, ARG_SADDRINET6); | |
361 | break; | |
362 | ||
363 | case AF_UNIX: | |
364 | sun = (struct sockaddr_un *)sa; | |
00867663 A |
365 | namelen = sun->sun_len - offsetof(struct sockaddr_un, sun_path); |
366 | if (namelen > 0 && (size_t)namelen < sizeof(path)) { | |
b0d623f7 | 367 | /* |
00867663 | 368 | * Make sure the path is NUL-terminated |
b0d623f7 | 369 | */ |
00867663 A |
370 | bcopy(sun->sun_path, path, namelen); |
371 | path[namelen] = 0; | |
813fb2f6 | 372 | audit_arg_upath(ar, cwd_vp, path, ARG_UPATH1); |
b0d623f7 A |
373 | } |
374 | ARG_SET_VALID(ar, ARG_SADDRUNIX); | |
375 | break; | |
0a7de745 | 376 | /* XXXAUDIT: default:? */ |
b0d623f7 A |
377 | } |
378 | } | |
379 | ||
380 | void | |
381 | audit_arg_auid(struct kaudit_record *ar, uid_t auid) | |
382 | { | |
b0d623f7 A |
383 | ar->k_ar.ar_arg_auid = auid; |
384 | ARG_SET_VALID(ar, ARG_AUID); | |
385 | } | |
386 | ||
387 | void | |
388 | audit_arg_auditinfo(struct kaudit_record *ar, struct auditinfo *au_info) | |
389 | { | |
b0d623f7 A |
390 | ar->k_ar.ar_arg_auid = au_info->ai_auid; |
391 | ar->k_ar.ar_arg_asid = au_info->ai_asid; | |
392 | ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; | |
393 | ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; | |
394 | ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; | |
395 | ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; | |
396 | ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); | |
397 | } | |
398 | ||
399 | void | |
400 | audit_arg_auditinfo_addr(struct kaudit_record *ar, | |
401 | struct auditinfo_addr *au_info) | |
402 | { | |
b0d623f7 A |
403 | ar->k_ar.ar_arg_auid = au_info->ai_auid; |
404 | ar->k_ar.ar_arg_asid = au_info->ai_asid; | |
405 | ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; | |
406 | ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; | |
407 | ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; | |
408 | ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; | |
409 | ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; | |
410 | ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; | |
411 | ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; | |
412 | ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; | |
413 | ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR); | |
414 | } | |
415 | ||
416 | void | |
417 | audit_arg_text(struct kaudit_record *ar, char *text) | |
418 | { | |
b0d623f7 A |
419 | KASSERT(text != NULL, ("audit_arg_text: text == NULL")); |
420 | ||
421 | /* Invalidate the text string */ | |
422 | ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); | |
0a7de745 | 423 | if (text == NULL) { |
b0d623f7 | 424 | return; |
0a7de745 | 425 | } |
b0d623f7 | 426 | |
0a7de745 A |
427 | if (ar->k_ar.ar_arg_text == NULL) { |
428 | ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, | |
b0d623f7 | 429 | M_WAITOK); |
0a7de745 | 430 | } |
b0d623f7 | 431 | |
f427ee49 | 432 | strlcpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); |
b0d623f7 A |
433 | ARG_SET_VALID(ar, ARG_TEXT); |
434 | } | |
435 | ||
436 | void | |
437 | audit_arg_opaque(struct kaudit_record *ar, void *data, size_t size) | |
438 | { | |
b0d623f7 A |
439 | KASSERT(data != NULL, ("audit_arg_opaque: data == NULL")); |
440 | KASSERT(size <= UINT16_MAX, ("audit_arg_opaque: size > UINT16_MAX")); | |
441 | ||
0a7de745 | 442 | if (data == NULL || size > UINT16_MAX) { |
b0d623f7 | 443 | return; |
0a7de745 | 444 | } |
b0d623f7 | 445 | |
0a7de745 | 446 | if (ar->k_ar.ar_arg_opaque == NULL) { |
b0d623f7 | 447 | ar->k_ar.ar_arg_opaque = malloc(size, M_AUDITDATA, M_WAITOK); |
0a7de745 | 448 | } else { |
b0d623f7 | 449 | return; |
0a7de745 | 450 | } |
b0d623f7 A |
451 | |
452 | memcpy(ar->k_ar.ar_arg_opaque, data, size); | |
453 | ar->k_ar.ar_arg_opq_size = (u_int16_t) size; | |
454 | ARG_SET_VALID(ar, ARG_OPAQUE); | |
455 | } | |
456 | ||
457 | void | |
458 | audit_arg_data(struct kaudit_record *ar, void *data, size_t size, size_t number) | |
459 | { | |
460 | size_t sz; | |
461 | ||
462 | KASSERT(data != NULL, ("audit_arg_data: data == NULL")); | |
463 | KASSERT(size >= AUR_BYTE_SIZE && size <= AUR_INT64_SIZE, | |
464 | ("audit_arg_data: size < AUR_BYTE_SIZE or size > AUR_INT64_SIZE")); | |
465 | KASSERT(number <= UINT8_MAX, | |
466 | ("audit_arg_data: number > UINT8_MAX")); | |
467 | ||
468 | if (data == NULL || size < AUR_BYTE_SIZE || size > AUR_INT64_SIZE || | |
0a7de745 | 469 | number > UINT8_MAX) { |
b0d623f7 | 470 | return; |
0a7de745 | 471 | } |
b0d623f7 A |
472 | |
473 | sz = size * number; | |
474 | ||
0a7de745 | 475 | if (ar->k_ar.ar_arg_data == NULL) { |
b0d623f7 | 476 | ar->k_ar.ar_arg_data = malloc(sz, M_AUDITDATA, M_WAITOK); |
0a7de745 | 477 | } else { |
b0d623f7 | 478 | return; |
0a7de745 | 479 | } |
b0d623f7 A |
480 | |
481 | memcpy(ar->k_ar.ar_arg_data, data, sz); | |
482 | ||
0a7de745 | 483 | switch (size) { |
b0d623f7 A |
484 | case AUR_BYTE_SIZE: |
485 | ar->k_ar.ar_arg_data_type = AUR_BYTE; | |
486 | break; | |
487 | ||
488 | case AUR_SHORT_SIZE: | |
489 | ar->k_ar.ar_arg_data_type = AUR_SHORT; | |
490 | break; | |
491 | ||
492 | case AUR_INT32_SIZE: | |
493 | ar->k_ar.ar_arg_data_type = AUR_INT32; | |
494 | break; | |
495 | ||
496 | case AUR_INT64_SIZE: | |
497 | ar->k_ar.ar_arg_data_type = AUR_INT64; | |
498 | break; | |
499 | ||
500 | default: | |
501 | free(ar->k_ar.ar_arg_data, M_AUDITDATA); | |
502 | ar->k_ar.ar_arg_data = NULL; | |
503 | return; | |
504 | } | |
505 | ||
506 | ar->k_ar.ar_arg_data_count = (u_char)number; | |
507 | ||
508 | ARG_SET_VALID(ar, ARG_DATA); | |
509 | } | |
510 | ||
511 | void | |
512 | audit_arg_cmd(struct kaudit_record *ar, int cmd) | |
513 | { | |
b0d623f7 A |
514 | ar->k_ar.ar_arg_cmd = cmd; |
515 | ARG_SET_VALID(ar, ARG_CMD); | |
516 | } | |
517 | ||
518 | void | |
519 | audit_arg_svipc_cmd(struct kaudit_record *ar, int cmd) | |
520 | { | |
b0d623f7 A |
521 | ar->k_ar.ar_arg_svipc_cmd = cmd; |
522 | ARG_SET_VALID(ar, ARG_SVIPC_CMD); | |
523 | } | |
524 | ||
525 | void | |
526 | audit_arg_svipc_perm(struct kaudit_record *ar, struct ipc_perm *perm) | |
527 | { | |
b0d623f7 A |
528 | bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, |
529 | sizeof(ar->k_ar.ar_arg_svipc_perm)); | |
530 | ARG_SET_VALID(ar, ARG_SVIPC_PERM); | |
531 | } | |
532 | ||
533 | void | |
534 | audit_arg_svipc_id(struct kaudit_record *ar, int id) | |
535 | { | |
b0d623f7 A |
536 | ar->k_ar.ar_arg_svipc_id = id; |
537 | ARG_SET_VALID(ar, ARG_SVIPC_ID); | |
538 | } | |
539 | ||
540 | void | |
541 | audit_arg_svipc_addr(struct kaudit_record *ar, user_addr_t addr) | |
542 | { | |
b0d623f7 A |
543 | ar->k_ar.ar_arg_svipc_addr = addr; |
544 | ARG_SET_VALID(ar, ARG_SVIPC_ADDR); | |
545 | } | |
546 | ||
547 | void | |
548 | audit_arg_posix_ipc_perm(struct kaudit_record *ar, uid_t uid, gid_t gid, | |
549 | mode_t mode) | |
550 | { | |
b0d623f7 A |
551 | ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; |
552 | ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; | |
553 | ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; | |
554 | ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); | |
555 | } | |
556 | ||
557 | void | |
558 | audit_arg_auditon(struct kaudit_record *ar, union auditon_udata *udata) | |
559 | { | |
b0d623f7 A |
560 | bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, |
561 | sizeof(ar->k_ar.ar_arg_auditon)); | |
562 | ARG_SET_VALID(ar, ARG_AUDITON); | |
563 | } | |
564 | ||
565 | /* | |
566 | * Audit information about a file, either the file's vnode info, or its | |
567 | * socket address info. | |
568 | */ | |
569 | void | |
570 | audit_arg_file(struct kaudit_record *ar, __unused proc_t p, | |
571 | struct fileproc *fp) | |
572 | { | |
573 | struct socket *so; | |
574 | struct inpcb *pcb; | |
575 | struct sockaddr_in *sin; | |
576 | struct sockaddr_in6 *sin6; | |
577 | ||
f427ee49 | 578 | switch (FILEGLOB_DTYPE(fp->fp_glob)) { |
b0d623f7 | 579 | case DTYPE_VNODE: |
0a7de745 | 580 | /* case DTYPE_FIFO: */ |
b0d623f7 | 581 | audit_arg_vnpath_withref(ar, |
f427ee49 | 582 | (struct vnode *)fp->fp_glob->fg_data, ARG_VNODE1); |
b0d623f7 A |
583 | break; |
584 | ||
585 | case DTYPE_SOCKET: | |
f427ee49 | 586 | so = (struct socket *)fp->fp_glob->fg_data; |
39236c6e | 587 | if (SOCK_CHECK_DOM(so, PF_INET)) { |
0a7de745 | 588 | if (so->so_pcb == NULL) { |
b0d623f7 | 589 | break; |
0a7de745 | 590 | } |
b0d623f7 A |
591 | ar->k_ar.ar_arg_sockinfo.sai_type = |
592 | so->so_type; | |
39236c6e A |
593 | ar->k_ar.ar_arg_sockinfo.sai_domain = SOCK_DOM(so); |
594 | ar->k_ar.ar_arg_sockinfo.sai_protocol = SOCK_PROTO(so); | |
b0d623f7 A |
595 | pcb = (struct inpcb *)so->so_pcb; |
596 | sin = (struct sockaddr_in *) | |
597 | &ar->k_ar.ar_arg_sockinfo.sai_faddr; | |
598 | sin->sin_addr.s_addr = pcb->inp_faddr.s_addr; | |
599 | sin->sin_port = pcb->inp_fport; | |
600 | sin = (struct sockaddr_in *) | |
601 | &ar->k_ar.ar_arg_sockinfo.sai_laddr; | |
602 | sin->sin_addr.s_addr = pcb->inp_laddr.s_addr; | |
603 | sin->sin_port = pcb->inp_lport; | |
604 | ARG_SET_VALID(ar, ARG_SOCKINFO); | |
605 | } | |
39236c6e | 606 | if (SOCK_CHECK_DOM(so, PF_INET6)) { |
0a7de745 | 607 | if (so->so_pcb == NULL) { |
b0d623f7 | 608 | break; |
0a7de745 | 609 | } |
b0d623f7 A |
610 | ar->k_ar.ar_arg_sockinfo.sai_type = |
611 | so->so_type; | |
39236c6e A |
612 | ar->k_ar.ar_arg_sockinfo.sai_domain = SOCK_DOM(so); |
613 | ar->k_ar.ar_arg_sockinfo.sai_protocol = SOCK_PROTO(so); | |
b0d623f7 A |
614 | pcb = (struct inpcb *)so->so_pcb; |
615 | sin6 = (struct sockaddr_in6 *) | |
616 | &ar->k_ar.ar_arg_sockinfo.sai_faddr; | |
617 | sin6->sin6_addr = pcb->in6p_faddr; | |
618 | sin6->sin6_port = pcb->in6p_fport; | |
619 | sin6 = (struct sockaddr_in6 *) | |
620 | &ar->k_ar.ar_arg_sockinfo.sai_laddr; | |
621 | sin6->sin6_addr = pcb->in6p_laddr; | |
622 | sin6->sin6_port = pcb->in6p_lport; | |
623 | ARG_SET_VALID(ar, ARG_SOCKINFO); | |
624 | } | |
625 | break; | |
626 | ||
627 | default: | |
628 | /* XXXAUDIT: else? */ | |
629 | break; | |
630 | } | |
631 | } | |
632 | ||
633 | /* | |
634 | * Store a path as given by the user process for auditing into the audit | |
635 | * record stored on the user thread. This function will allocate the memory | |
636 | * to store the path info if not already available. This memory will be | |
637 | * freed when the audit record is freed. | |
0a7de745 | 638 | * |
b0d623f7 A |
639 | * Note that the current working directory vp must be supplied at the audit call |
640 | * site to permit per thread current working directories, and that it must take | |
641 | * a upath starting with '/' into account for chroot if the path is absolute. | |
642 | * This results in the real (non-chroot) path being recorded in the audit | |
643 | * record. | |
644 | * | |
645 | * XXXAUDIT: Possibly assert that the memory isn't already allocated? | |
646 | */ | |
647 | void | |
648 | audit_arg_upath(struct kaudit_record *ar, struct vnode *cwd_vp, char *upath, u_int64_t flag) | |
649 | { | |
650 | char **pathp; | |
651 | ||
652 | KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL")); | |
653 | KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2), | |
654 | ("audit_arg_upath: flag %llu", (unsigned long long)flag)); | |
655 | KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2), | |
656 | ("audit_arg_upath: flag %llu", (unsigned long long)flag)); | |
657 | ||
0a7de745 | 658 | if (flag == ARG_UPATH1) { |
b0d623f7 | 659 | pathp = &ar->k_ar.ar_arg_upath1; |
0a7de745 | 660 | } else { |
b0d623f7 | 661 | pathp = &ar->k_ar.ar_arg_upath2; |
0a7de745 | 662 | } |
b0d623f7 | 663 | |
0a7de745 | 664 | if (*pathp == NULL) { |
b0d623f7 | 665 | *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); |
0a7de745 | 666 | } else { |
b0d623f7 | 667 | return; |
0a7de745 | 668 | } |
b0d623f7 | 669 | |
0a7de745 | 670 | if (audit_canon_path(cwd_vp, upath, *pathp) == 0) { |
b0d623f7 | 671 | ARG_SET_VALID(ar, flag); |
0a7de745 | 672 | } else { |
b0d623f7 A |
673 | free(*pathp, M_AUDITPATH); |
674 | *pathp = NULL; | |
675 | } | |
676 | } | |
677 | ||
b226f5e5 A |
678 | void |
679 | audit_arg_kpath(struct kaudit_record *ar, char *kpath, u_int64_t flag) | |
680 | { | |
681 | char **pathp; | |
682 | ||
683 | KASSERT(kpath != NULL, ("audit_arg_kpath: kpath == NULL")); | |
684 | KASSERT((flag == ARG_KPATH1) || (flag == ARG_KPATH2), | |
685 | ("audit_arg_kpath: flag %llu", (unsigned long long)flag)); | |
686 | KASSERT((flag != ARG_KPATH1) || (flag != ARG_KPATH2), | |
687 | ("audit_arg_kpath: flag %llu", (unsigned long long)flag)); | |
688 | ||
0a7de745 | 689 | if (flag == ARG_KPATH1) { |
b226f5e5 | 690 | pathp = &ar->k_ar.ar_arg_kpath1; |
0a7de745 | 691 | } else { |
b226f5e5 | 692 | pathp = &ar->k_ar.ar_arg_kpath2; |
0a7de745 | 693 | } |
b226f5e5 | 694 | |
0a7de745 | 695 | if (*pathp == NULL) { |
b226f5e5 | 696 | *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); |
0a7de745 | 697 | } else { |
b226f5e5 | 698 | return; |
0a7de745 | 699 | } |
b226f5e5 A |
700 | |
701 | strlcpy(*pathp, kpath, MAXPATHLEN); | |
702 | ARG_SET_VALID(ar, flag); | |
703 | } | |
704 | ||
b0d623f7 A |
705 | /* |
706 | * Function to save the path and vnode attr information into the audit | |
707 | * record. | |
708 | * | |
709 | * It is assumed that the caller will hold any vnode locks necessary to | |
710 | * perform a VNOP_GETATTR() on the passed vnode. | |
711 | * | |
712 | * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always | |
713 | * provides access to the generation number as we need that to construct the | |
714 | * BSM file ID. | |
715 | * | |
716 | * XXX: We should accept the process argument from the caller, since it's | |
717 | * very likely they already have a reference. | |
718 | * | |
719 | * XXX: Error handling in this function is poor. | |
720 | * | |
721 | * XXXAUDIT: Possibly KASSERT the path pointer is NULL? | |
722 | */ | |
723 | void | |
724 | audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) | |
725 | { | |
726 | struct vnode_attr va; | |
727 | int error; | |
728 | int len; | |
729 | char **pathp; | |
730 | struct vnode_au_info *vnp; | |
731 | proc_t p; | |
732 | #if CONFIG_MACF | |
733 | char **vnode_mac_labelp; | |
734 | struct mac mac; | |
735 | #endif | |
736 | ||
737 | KASSERT(vp != NULL, ("audit_arg_vnpath: vp == NULL")); | |
738 | KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2), | |
739 | ("audit_arg_vnpath: flags != ARG_VNODE[1,2]")); | |
740 | ||
741 | p = current_proc(); | |
742 | ||
0a7de745 | 743 | /* |
b0d623f7 A |
744 | * XXXAUDIT: The below clears, and then resets the flags for valid |
745 | * arguments. Ideally, either the new vnode is used, or the old one | |
746 | * would be. | |
747 | */ | |
748 | if (flags & ARG_VNODE1) { | |
749 | ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_KPATH1); | |
750 | ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1); | |
751 | pathp = &ar->k_ar.ar_arg_kpath1; | |
752 | vnp = &ar->k_ar.ar_arg_vnode1; | |
753 | #if CONFIG_MACF | |
754 | vnode_mac_labelp = &ar->k_ar.ar_vnode1_mac_labels; | |
755 | #endif | |
756 | } else { | |
757 | ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_KPATH2); | |
758 | ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2); | |
759 | pathp = &ar->k_ar.ar_arg_kpath2; | |
760 | vnp = &ar->k_ar.ar_arg_vnode2; | |
761 | #if CONFIG_MACF | |
762 | vnode_mac_labelp = &ar->k_ar.ar_vnode2_mac_labels; | |
763 | #endif | |
764 | } | |
765 | ||
0a7de745 | 766 | if (*pathp == NULL) { |
b0d623f7 | 767 | *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); |
0a7de745 | 768 | } else { |
b0d623f7 | 769 | return; |
0a7de745 | 770 | } |
b0d623f7 A |
771 | |
772 | /* | |
773 | * If vn_getpath() succeeds, place it in a string buffer | |
774 | * attached to the audit record, and set a flag indicating | |
775 | * it is present. | |
776 | */ | |
777 | len = MAXPATHLEN; | |
778 | if (vn_getpath(vp, *pathp, &len) == 0) { | |
0a7de745 | 779 | if (flags & ARG_VNODE1) { |
b0d623f7 | 780 | ARG_SET_VALID(ar, ARG_KPATH1); |
0a7de745 | 781 | } else { |
b0d623f7 | 782 | ARG_SET_VALID(ar, ARG_KPATH2); |
0a7de745 | 783 | } |
b0d623f7 A |
784 | } else { |
785 | free(*pathp, M_AUDITPATH); | |
786 | *pathp = NULL; | |
787 | } | |
788 | ||
789 | VATTR_INIT(&va); | |
790 | VATTR_WANTED(&va, va_mode); | |
791 | VATTR_WANTED(&va, va_uid); | |
792 | VATTR_WANTED(&va, va_gid); | |
793 | VATTR_WANTED(&va, va_rdev); | |
794 | VATTR_WANTED(&va, va_fsid); | |
795 | VATTR_WANTED(&va, va_fileid); | |
796 | VATTR_WANTED(&va, va_gen); | |
797 | error = vnode_getattr(vp, &va, vfs_context_current()); | |
798 | if (error) { | |
799 | /* XXX: How to handle this case? */ | |
800 | return; | |
801 | } | |
802 | ||
803 | #if CONFIG_MACF | |
804 | if (*vnode_mac_labelp == NULL && (vp->v_lflag & VL_LABELED) == VL_LABELED) { | |
805 | *vnode_mac_labelp = (char *)zalloc(audit_mac_label_zone); | |
806 | if (*vnode_mac_labelp != NULL) { | |
807 | mac.m_buflen = MAC_AUDIT_LABEL_LEN; | |
808 | mac.m_string = *vnode_mac_labelp; | |
809 | mac_vnode_label_externalize_audit(vp, &mac); | |
810 | } | |
811 | } | |
812 | #endif | |
813 | ||
814 | /* | |
815 | * XXX do we want to fall back here when these aren't supported? | |
816 | */ | |
817 | vnp->vn_mode = va.va_mode; | |
818 | vnp->vn_uid = va.va_uid; | |
819 | vnp->vn_gid = va.va_gid; | |
820 | vnp->vn_dev = va.va_rdev; | |
821 | vnp->vn_fsid = va.va_fsid; | |
822 | vnp->vn_fileid = (u_int32_t)va.va_fileid; | |
823 | vnp->vn_gen = va.va_gen; | |
0a7de745 | 824 | if (flags & ARG_VNODE1) { |
b0d623f7 | 825 | ARG_SET_VALID(ar, ARG_VNODE1); |
0a7de745 | 826 | } else { |
b0d623f7 | 827 | ARG_SET_VALID(ar, ARG_VNODE2); |
0a7de745 | 828 | } |
b0d623f7 A |
829 | } |
830 | ||
831 | void | |
832 | audit_arg_vnpath_withref(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) | |
833 | { | |
0a7de745 | 834 | if (vp == NULL || vnode_getwithref(vp)) { |
b0d623f7 | 835 | return; |
0a7de745 | 836 | } |
b0d623f7 A |
837 | audit_arg_vnpath(ar, vp, flags); |
838 | (void)vnode_put(vp); | |
839 | } | |
840 | ||
841 | void | |
842 | audit_arg_mach_port1(struct kaudit_record *ar, mach_port_name_t port) | |
843 | { | |
b0d623f7 A |
844 | ar->k_ar.ar_arg_mach_port1 = port; |
845 | ARG_SET_VALID(ar, ARG_MACHPORT1); | |
846 | } | |
847 | ||
848 | void | |
849 | audit_arg_mach_port2(struct kaudit_record *ar, mach_port_name_t port) | |
850 | { | |
b0d623f7 A |
851 | ar->k_ar.ar_arg_mach_port2 = port; |
852 | ARG_SET_VALID(ar, ARG_MACHPORT2); | |
853 | } | |
854 | ||
855 | ||
856 | /* | |
857 | * Audit the argument strings passed to exec. | |
858 | */ | |
859 | void | |
f427ee49 | 860 | audit_arg_argv(struct kaudit_record *ar, char *argv, int argc, size_t length) |
b0d623f7 | 861 | { |
0a7de745 | 862 | if (audit_argv == 0 || argc == 0) { |
b0d623f7 | 863 | return; |
0a7de745 | 864 | } |
b0d623f7 | 865 | |
0a7de745 | 866 | if (ar->k_ar.ar_arg_argv == NULL) { |
b0d623f7 | 867 | ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); |
0a7de745 | 868 | } |
b0d623f7 A |
869 | bcopy(argv, ar->k_ar.ar_arg_argv, length); |
870 | ar->k_ar.ar_arg_argc = argc; | |
871 | ARG_SET_VALID(ar, ARG_ARGV); | |
872 | } | |
873 | ||
874 | /* | |
875 | * Audit the environment strings passed to exec. | |
876 | */ | |
877 | void | |
f427ee49 | 878 | audit_arg_envv(struct kaudit_record *ar, char *envv, int envc, size_t length) |
b0d623f7 | 879 | { |
0a7de745 | 880 | if (audit_arge == 0 || envc == 0) { |
b0d623f7 | 881 | return; |
0a7de745 | 882 | } |
b0d623f7 | 883 | |
0a7de745 | 884 | if (ar->k_ar.ar_arg_envv == NULL) { |
b0d623f7 | 885 | ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); |
0a7de745 | 886 | } |
b0d623f7 A |
887 | bcopy(envv, ar->k_ar.ar_arg_envv, length); |
888 | ar->k_ar.ar_arg_envc = envc; | |
889 | ARG_SET_VALID(ar, ARG_ENVV); | |
890 | } | |
891 | ||
892 | /* | |
893 | * The close() system call uses it's own audit call to capture the path/vnode | |
894 | * information because those pieces are not easily obtained within the system | |
895 | * call itself. | |
896 | */ | |
897 | void | |
898 | audit_sysclose(struct kaudit_record *ar, proc_t p, int fd) | |
899 | { | |
900 | struct fileproc *fp; | |
901 | struct vnode *vp; | |
902 | ||
903 | KASSERT(p != NULL, ("audit_sysclose: p == NULL")); | |
904 | ||
905 | audit_arg_fd(ar, fd); | |
906 | ||
0a7de745 | 907 | if (fp_getfvp(p, fd, &fp, &vp) != 0) { |
b0d623f7 | 908 | return; |
0a7de745 | 909 | } |
b0d623f7 | 910 | |
f427ee49 | 911 | audit_arg_vnpath_withref(ar, (struct vnode *)fp->fp_glob->fg_data, |
b0d623f7 A |
912 | ARG_VNODE1); |
913 | fp_drop(p, fd, fp, 0); | |
914 | } | |
915 | ||
d9a64523 A |
916 | void |
917 | audit_identity_info_destruct(struct au_identity_info *id_info) | |
918 | { | |
919 | if (!id_info) { | |
920 | return; | |
921 | } | |
922 | ||
923 | if (id_info->signing_id != NULL) { | |
924 | free(id_info->signing_id, M_AUDITTEXT); | |
925 | id_info->signing_id = NULL; | |
926 | } | |
927 | ||
928 | if (id_info->team_id != NULL) { | |
929 | free(id_info->team_id, M_AUDITTEXT); | |
930 | id_info->team_id = NULL; | |
931 | } | |
932 | ||
933 | if (id_info->cdhash != NULL) { | |
934 | free(id_info->cdhash, M_AUDITDATA); | |
935 | id_info->cdhash = NULL; | |
936 | } | |
937 | } | |
938 | ||
939 | void | |
940 | audit_identity_info_construct(struct au_identity_info *id_info) | |
941 | { | |
942 | struct proc *p; | |
943 | struct cs_blob *blob; | |
944 | unsigned int signer_type = 0; | |
945 | const char *signing_id = NULL; | |
946 | const char* team_id = NULL; | |
947 | const uint8_t *cdhash = NULL; | |
948 | size_t src_len = 0; | |
949 | ||
950 | p = current_proc(); | |
951 | blob = csproc_get_blob(p); | |
952 | if (blob) { | |
953 | signing_id = csblob_get_identity(blob); | |
954 | cdhash = csblob_get_cdhash(blob); | |
955 | team_id = csblob_get_teamid(blob); | |
956 | signer_type = csblob_get_platform_binary(blob) ? 1 : 0; | |
957 | } | |
958 | ||
959 | id_info->signer_type = signer_type; | |
960 | ||
961 | if (id_info->signing_id == NULL && signing_id != NULL) { | |
962 | id_info->signing_id = malloc( MAX_AU_IDENTITY_SIGNING_ID_LENGTH, | |
0a7de745 | 963 | M_AUDITTEXT, M_WAITOK); |
d9a64523 A |
964 | if (id_info->signing_id != NULL) { |
965 | src_len = strlcpy(id_info->signing_id, | |
0a7de745 | 966 | signing_id, MAX_AU_IDENTITY_SIGNING_ID_LENGTH); |
d9a64523 A |
967 | |
968 | if (src_len >= MAX_AU_IDENTITY_SIGNING_ID_LENGTH) { | |
969 | id_info->signing_id_trunc = 1; | |
970 | } | |
971 | } | |
972 | } | |
973 | ||
974 | if (id_info->team_id == NULL && team_id != NULL) { | |
975 | id_info->team_id = malloc(MAX_AU_IDENTITY_TEAM_ID_LENGTH, | |
0a7de745 | 976 | M_AUDITTEXT, M_WAITOK); |
d9a64523 A |
977 | if (id_info->team_id != NULL) { |
978 | src_len = strlcpy(id_info->team_id, team_id, | |
0a7de745 | 979 | MAX_AU_IDENTITY_TEAM_ID_LENGTH); |
d9a64523 A |
980 | |
981 | if (src_len >= MAX_AU_IDENTITY_TEAM_ID_LENGTH) { | |
982 | id_info->team_id_trunc = 1; | |
983 | } | |
984 | } | |
985 | } | |
986 | ||
987 | if (id_info->cdhash == NULL && cdhash != NULL) { | |
988 | id_info->cdhash = malloc(CS_CDHASH_LEN, M_AUDITDATA, M_WAITOK); | |
989 | if (id_info->cdhash != NULL) { | |
990 | memcpy(id_info->cdhash, cdhash, CS_CDHASH_LEN); | |
991 | id_info->cdhash_len = CS_CDHASH_LEN; | |
992 | } | |
993 | } | |
994 | } | |
995 | ||
996 | void | |
997 | audit_arg_identity(struct kaudit_record *ar) | |
998 | { | |
999 | audit_identity_info_construct(&ar->k_ar.ar_arg_identity); | |
1000 | ARG_SET_VALID(ar, ARG_IDENTITY); | |
1001 | } | |
1002 | ||
b0d623f7 | 1003 | #endif /* CONFIG_AUDIT */ |