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