1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 2425 gww * Common Development and Distribution License (the "License"). 6 2425 gww * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 10210 Paul * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #ifndef _BSM_AUDIT_KERNEL_H 27 0 stevel #define _BSM_AUDIT_KERNEL_H 28 0 stevel 29 0 stevel 30 0 stevel /* 31 0 stevel * This file contains the basic auditing control structure definitions. 32 0 stevel */ 33 0 stevel 34 0 stevel #include <c2/audit_kevents.h> 35 0 stevel #include <sys/priv_impl.h> 36 0 stevel #include <sys/taskq.h> 37 0 stevel #include <sys/zone.h> 38 2425 gww 39 2425 gww #include <sys/tsol/label.h> 40 0 stevel 41 0 stevel #ifdef __cplusplus 42 0 stevel extern "C" { 43 0 stevel #endif 44 0 stevel 45 0 stevel /* 46 0 stevel * This table contains the mapping from the system call ID to a corresponding 47 0 stevel * audit event. 48 0 stevel * 49 0 stevel * au_init() is a function called at the beginning of the system call that 50 0 stevel * performs any necessary setup/processing. It maps the call into the 51 0 stevel * appropriate event, depending on the system call arguments. It is called 52 0 stevel * by audit_start() from trap.c . 53 0 stevel * 54 0 stevel * au_event is the audit event associated with the system call. Most of the 55 0 stevel * time it will map directly from the system call i.e. There is one system 56 0 stevel * call associated with the event. In some cases, such as shmsys, or open, 57 0 stevel * the au_start() function will map the system call to more than one event, 58 0 stevel * depending on the system call arguments. 59 0 stevel * 60 0 stevel * au_start() is a function that provides per system call processing at the 61 0 stevel * beginning of a system call. It is mainly concerned with preseving the 62 0 stevel * audit record components that may be altered so that we can determine 63 0 stevel * what the original paramater was before as well as after the system call. 64 0 stevel * It is possible that au_start() may be taken away. It might be cleaner to 65 0 stevel * define flags in au_ctrl to save a designated argument. For the moment we 66 0 stevel * support both mechanisms, however the use of au_start() will be reviewed 67 0 stevel * for 4.1.1 and CMW and ZEUS to see if such a general method is justified. 68 0 stevel * 69 0 stevel * au_finish() is a function that provides per system call processing at the 70 0 stevel * completion of a system call. In certain circumstances, the type of audit 71 0 stevel * event depends on intermidiate results during the processing of the system 72 0 stevel * call. It is called in audit_finish() from trap.c . 73 0 stevel * 74 0 stevel * au_ctrl is a control vector that indicates what processing might have to 75 0 stevel * be performed, even if there is no auditing for this system call. At 76 0 stevel * present this is mostly for path processing for chmod, chroot. We need to 77 0 stevel * process the path information in vfs_lookup, even when we are not auditing 78 0 stevel * the system call in the case of chdir and chroot. 79 0 stevel */ 80 0 stevel /* 81 0 stevel * Defines for au_ctrl 82 0 stevel */ 83 0 stevel #define S2E_SP PAD_SAVPATH /* save path for later use */ 84 0 stevel #define S2E_MLD PAD_MLD /* only one lookup per system call */ 85 0 stevel #define S2E_NPT PAD_NOPATH /* force no path in audit record */ 86 0 stevel #define S2E_PUB PAD_PUBLIC_EV /* syscall is defined as a public op */ 87 0 stevel 88 0 stevel /* 89 0 stevel * At present, we are using the audit classes imbedded with in the kernel. Each 90 0 stevel * event has a bit mask determining which classes the event is associated. 91 0 stevel * The table audit_e2s maps the audit event ID to the audit state. 92 0 stevel * 93 0 stevel * Note that this may change radically. If we use a bit vector for the audit 94 0 stevel * class, we can allow granularity at the event ID for each user. In this 95 0 stevel * case, the vector would be determined at user level and passed to the kernel 96 0 stevel * via the setaudit system call. 97 0 stevel */ 98 0 stevel 99 0 stevel /* 100 0 stevel * The audit_pad structure holds paths for the current root and directory 101 0 stevel * for the process, as well as for open files and directly manipulated objects. 102 0 stevel * The reference count minimizes data copies since the process's current 103 0 stevel * directory changes very seldom. 104 0 stevel */ 105 0 stevel struct audit_path { 106 0 stevel uint_t audp_ref; /* reference count */ 107 0 stevel uint_t audp_size; /* allocated size of this structure */ 108 0 stevel uint_t audp_cnt; /* number of path sections */ 109 0 stevel char *audp_sect[1]; /* path section pointers */ 110 0 stevel /* audp_sect[0] is the path name */ 111 0 stevel /* audp_sect[1+] are attribute paths */ 112 0 stevel }; 113 0 stevel 114 0 stevel /* 115 0 stevel * The structure of the terminal ID within the kernel is different from the 116 0 stevel * terminal ID in user space. It is a combination of port and IP address. 117 0 stevel */ 118 0 stevel 119 0 stevel struct au_termid { 120 0 stevel dev_t at_port; 121 0 stevel uint_t at_type; 122 0 stevel uint_t at_addr[4]; 123 0 stevel }; 124 0 stevel typedef struct au_termid au_termid_t; 125 0 stevel 126 0 stevel /* 127 0 stevel * Attributes for deferring the queuing of an event. 128 0 stevel */ 129 0 stevel typedef struct au_defer_info { 130 0 stevel struct au_defer_info *audi_next; /* next on linked list */ 131 0 stevel void *audi_ad; /* audit record */ 132 7753 Ton au_event_t audi_e_type; /* audit event id */ 133 7753 Ton au_emod_t audi_e_mod; /* audit event modifier */ 134 0 stevel int audi_flag; /* au_close*() flags */ 135 0 stevel timestruc_t audi_atime; /* audit event timestamp */ 136 0 stevel } au_defer_info_t; 137 0 stevel 138 0 stevel /* 139 0 stevel * The structure p_audit_data hangs off of the process structure. It contains 140 0 stevel * all of the audit information necessary to manage the audit record generation 141 0 stevel * for each process. 142 0 stevel * 143 0 stevel * The pad_lock is constructed in the kmem_cache; the rest is combined 144 0 stevel * in a sub structure so it can be copied/zeroed in one statement. 145 0 stevel * 146 0 stevel * The members have been reordered for maximum packing on 64 bit Solaris. 147 0 stevel */ 148 0 stevel struct p_audit_data { 149 0 stevel kmutex_t pad_lock; /* lock pad data during changes */ 150 0 stevel struct _pad_data { 151 0 stevel struct audit_path *pad_root; /* process root path */ 152 0 stevel struct audit_path *pad_cwd; /* process cwd path */ 153 0 stevel au_mask_t pad_newmask; /* pending new mask */ 154 0 stevel int pad_flags; 155 0 stevel } pad_data; 156 0 stevel }; 157 0 stevel typedef struct p_audit_data p_audit_data_t; 158 0 stevel 159 0 stevel #define pad_root pad_data.pad_root 160 0 stevel #define pad_cwd pad_data.pad_cwd 161 0 stevel #define pad_newmask pad_data.pad_newmask 162 0 stevel #define pad_flags pad_data.pad_flags 163 0 stevel 164 0 stevel /* 165 0 stevel * Defines for pad_flags 166 0 stevel */ 167 0 stevel #define PAD_SETMASK 0x00000001 /* need to complete pending setmask */ 168 0 stevel 169 0 stevel extern kmem_cache_t *au_pad_cache; 170 0 stevel 171 0 stevel /* 172 0 stevel * Defines for pad_ctrl 173 0 stevel */ 174 0 stevel #define PAD_SAVPATH 0x00000001 /* save path for further processing */ 175 0 stevel #define PAD_MLD 0x00000002 /* system call involves MLD */ 176 0 stevel #define PAD_NOPATH 0x00000004 /* force no paths in audit record */ 177 0 stevel #define PAD_ABSPATH 0x00000008 /* path from lookup is absolute */ 178 0 stevel #define PAD_NOATTRB 0x00000010 /* do not automatically add attribute */ 179 0 stevel /* 0x20, 0x40 unused */ 180 0 stevel #define PAD_LFLOAT 0x00000080 /* Label float */ 181 0 stevel #define PAD_NOAUDIT 0x00000100 /* discard audit record */ 182 0 stevel #define PAD_PATHFND 0x00000200 /* found path, don't retry lookup */ 183 0 stevel #define PAD_SPRIV 0x00000400 /* succ priv use. extra audit_finish */ 184 0 stevel #define PAD_FPRIV 0x00000800 /* fail priv use. extra audit_finish */ 185 0 stevel #define PAD_SMAC 0x00001000 /* succ mac use. extra audit_finish */ 186 0 stevel #define PAD_FMAC 0x00002000 /* fail mac use. extra audit_finish */ 187 0 stevel #define PAD_AUDITME 0x00004000 /* audit me because of NFS operation */ 188 0 stevel #define PAD_ATPATH 0x00008000 /* attribute file lookup */ 189 0 stevel #define PAD_TRUE_CREATE 0x00010000 /* true create, file not found */ 190 0 stevel #define PAD_CORE 0x00020000 /* save attribute during core dump */ 191 0 stevel #define PAD_ERRJMP 0x00040000 /* abort record generation on error */ 192 0 stevel #define PAD_PUBLIC_EV 0x00080000 /* syscall is defined as a public op */ 193 0 stevel 194 0 stevel /* 195 0 stevel * The structure t_audit_data hangs off of the thread structure. It contains 196 0 stevel * all of the audit information necessary to manage the audit record generation 197 0 stevel * for each thread. 198 0 stevel * 199 0 stevel */ 200 0 stevel 201 0 stevel struct t_audit_data { 202 0 stevel kthread_id_t tad_thread; /* DEBUG pointer to parent thread */ 203 0 stevel unsigned int tad_scid; /* system call ID for finish */ 204 7753 Ton au_event_t tad_event; /* event for audit record */ 205 7753 Ton au_emod_t tad_evmod; /* event modifier for audit record */ 206 0 stevel int tad_ctrl; /* audit control/status flags */ 207 0 stevel void *tad_errjmp; /* error longjmp (audit record aborted) */ 208 0 stevel int tad_flag; /* to audit or not to audit */ 209 0 stevel struct audit_path *tad_aupath; /* captured at vfs_lookup */ 210 0 stevel struct audit_path *tad_atpath; /* openat prefix, path of fd */ 211 0 stevel struct vnode *tad_vn; /* saved inode from vfs_lookup */ 212 0 stevel caddr_t tad_ad; /* base of accumulated audit data */ 213 0 stevel au_defer_info_t *tad_defer_head; /* queue of records to defer */ 214 0 stevel /* until syscall end: */ 215 0 stevel au_defer_info_t *tad_defer_tail; /* tail of defer queue */ 216 0 stevel priv_set_t tad_sprivs; /* saved (success) used privs */ 217 0 stevel priv_set_t tad_fprivs; /* saved (failed) used privs */ 218 0 stevel }; 219 0 stevel typedef struct t_audit_data t_audit_data_t; 220 0 stevel 221 0 stevel /* 222 0 stevel * The f_audit_data structure hangs off of the file structure. It contains 223 0 stevel * three fields of data. The audit ID, the audit state, and a path name. 224 0 stevel */ 225 0 stevel 226 0 stevel struct f_audit_data { 227 0 stevel kthread_id_t fad_thread; /* DEBUG creating thread */ 228 0 stevel int fad_flags; /* audit control flags */ 229 0 stevel struct audit_path *fad_aupath; /* path from vfs_lookup */ 230 0 stevel }; 231 0 stevel typedef struct f_audit_data f_audit_data_t; 232 0 stevel 233 0 stevel #define FAD_READ 0x0001 /* read system call seen */ 234 0 stevel #define FAD_WRITE 0x0002 /* write system call seen */ 235 0 stevel 236 0 stevel #define P2A(p) (p->p_audit_data) 237 0 stevel #define T2A(t) (t->t_audit_data) 238 0 stevel #define U2A(u) (curthread->t_audit_data) 239 0 stevel #define F2A(f) (f->f_audit_data) 240 0 stevel 241 0 stevel #define u_ad ((U2A(u))->tad_ad) 242 0 stevel #define ad_ctrl ((U2A(u))->tad_ctrl) 243 0 stevel #define ad_flag ((U2A(u))->tad_flag) 244 0 stevel 245 0 stevel #define AU_BUFSIZE 128 /* buffer size for the buffer pool */ 246 0 stevel 247 0 stevel struct au_buff { 248 0 stevel char buf[AU_BUFSIZE]; 249 0 stevel struct au_buff *next_buf; 250 0 stevel struct au_buff *next_rec; 251 0 stevel ushort_t rec_len; 252 0 stevel uchar_t len; 253 0 stevel uchar_t flag; 254 0 stevel }; 255 0 stevel 256 0 stevel typedef struct au_buff au_buff_t; 257 0 stevel 258 0 stevel /* 259 0 stevel * Kernel audit queue structure. 260 0 stevel */ 261 0 stevel struct audit_queue { 262 0 stevel au_buff_t *head; /* head of queue */ 263 0 stevel au_buff_t *tail; /* tail of queue */ 264 0 stevel ssize_t cnt; /* number elements on queue */ 265 0 stevel size_t hiwater; /* high water mark to block */ 266 0 stevel size_t lowater; /* low water mark to restart */ 267 0 stevel size_t bufsz; /* audit trail write buffer size */ 268 0 stevel size_t buflen; /* audit trail buffer length in use */ 269 0 stevel clock_t delay; /* delay before flushing queue */ 270 0 stevel int wt_block; /* writer is blocked (1) */ 271 0 stevel int rd_block; /* reader is blocked (1) */ 272 0 stevel kmutex_t lock; /* mutex lock for queue modification */ 273 0 stevel kcondvar_t write_cv; /* sleep structure for write block */ 274 0 stevel kcondvar_t read_cv; /* sleep structure for read block */ 275 0 stevel }; 276 0 stevel 277 0 stevel 278 0 stevel union rval; 279 0 stevel struct audit_s2e { 280 0 stevel au_event_t (*au_init)(au_event_t); 281 0 stevel /* convert au_event to real audit event ID */ 282 0 stevel 283 0 stevel int au_event; /* default audit event for this system call */ 284 0 stevel void (*au_start)(struct t_audit_data *); 285 0 stevel /* pre-system call audit processing */ 286 0 stevel void (*au_finish)(struct t_audit_data *, int, union rval *); 287 0 stevel /* post-system call audit processing */ 288 0 stevel int au_ctrl; /* control flags for auditing actions */ 289 0 stevel }; 290 0 stevel 291 0 stevel extern struct audit_s2e audit_s2e[]; 292 0 stevel 293 0 stevel #define AUK_VALID 0x5A5A5A5A 294 0 stevel #define AUK_INVALID 0 295 0 stevel /* 296 0 stevel * per zone audit context 297 0 stevel */ 298 0 stevel struct au_kcontext { 299 0 stevel uint32_t auk_valid; 300 0 stevel zoneid_t auk_zid; 301 0 stevel 302 0 stevel boolean_t auk_hostaddr_valid; 303 0 stevel int auk_sequence; 304 0 stevel int auk_auditstate; 305 0 stevel int auk_output_active; 306 0 stevel struct vnode *auk_current_vp; 307 0 stevel int auk_policy; 308 0 stevel 309 0 stevel struct audit_queue auk_queue; 310 0 stevel 311 0 stevel au_dbuf_t *auk_dbuffer; /* auditdoor output */ 312 0 stevel 313 0 stevel au_stat_t auk_statistics; 314 0 stevel 315 0 stevel struct auditinfo_addr auk_info; 316 0 stevel kmutex_t auk_eagain_mutex; /* door call retry */ 317 0 stevel kcondvar_t auk_eagain_cv; 318 0 stevel 319 0 stevel taskq_t *auk_taskq; /* output thread */ 320 0 stevel 321 0 stevel /* Only one audit svc per zone at a time */ 322 5992 gww /* With the elimination of auditsvc, can this also go? see 6648414 */ 323 0 stevel kmutex_t auk_svc_lock; 324 5992 gww 325 2640 rica au_state_t auk_ets[MAX_KEVENTS + 1]; 326 0 stevel }; 327 0 stevel #ifndef AUK_CONTEXT_T 328 0 stevel #define AUK_CONTEXT_T 329 0 stevel typedef struct au_kcontext au_kcontext_t; 330 0 stevel #endif 331 0 stevel 332 0 stevel extern zone_key_t au_zone_key; 333 0 stevel 334 0 stevel /* 335 0 stevel * Kernel auditing external variables 336 0 stevel */ 337 0 stevel extern int audit_policy; 338 0 stevel extern int audit_active; 339 0 stevel extern int audit_load; 340 0 stevel extern int au_auditstate; 341 0 stevel 342 0 stevel extern struct audit_queue au_queue; 343 0 stevel extern struct p_audit_data *pad0; 344 0 stevel extern struct t_audit_data *tad0; 345 0 stevel 346 0 stevel /* 347 0 stevel * audit_path support routines 348 0 stevel */ 349 0 stevel void au_pathhold(struct audit_path *); 350 0 stevel void au_pathrele(struct audit_path *); 351 0 stevel struct audit_path *au_pathdup(const struct audit_path *, int, int); 352 0 stevel 353 0 stevel /* 354 0 stevel * Macros to hide asynchronous, non-blocking audit record start and finish 355 0 stevel * processing. 356 0 stevel * 357 0 stevel * NOTE: must be used in (void) funcction () { ... } 358 0 stevel */ 359 0 stevel 360 0 stevel #define AUDIT_ASYNC_START(rp, audit_event, sorf) \ 361 0 stevel { \ 362 0 stevel label_t jb; \ 363 0 stevel if (setjmp(&jb)) { \ 364 0 stevel /* cleanup any residual audit data */ \ 365 0 stevel audit_async_drop((caddr_t *)&(rp), 0); \ 366 0 stevel return; \ 367 0 stevel } \ 368 0 stevel /* auditing enabled and we're preselected for this event? */ \ 369 0 stevel if (audit_async_start(&jb, audit_event, sorf)) { \ 370 0 stevel return; \ 371 0 stevel } \ 372 0 stevel } 373 0 stevel 374 0 stevel #define AUDIT_ASYNC_FINISH(rp, audit_event, event_modifier) \ 375 0 stevel audit_async_finish((caddr_t *)&(rp), audit_event, event_modifier); 376 0 stevel 377 0 stevel 378 0 stevel #ifdef _KERNEL 379 0 stevel au_buff_t *au_get_buff(void), *au_free_buff(au_buff_t *); 380 0 stevel #endif 381 0 stevel 382 0 stevel /* 383 2425 gww * Macro for uniform "subject" token(s) generation 384 0 stevel */ 385 6900 jf206706 #define AUDIT_SETSUBJ_GENERIC(u, c, a, k, p) \ 386 6900 jf206706 (au_write((u), au_to_subject(crgetuid(c), \ 387 6900 jf206706 crgetgid(c), crgetruid(c), crgetrgid(c), \ 388 6900 jf206706 p, (a)->ai_auid, (a)->ai_asid, \ 389 6900 jf206706 &((a)->ai_termid)))); \ 390 6900 jf206706 ((is_system_labeled()) ? au_write((u), \ 391 6900 jf206706 au_to_label(CR_SL((c)))) : (void) 0); \ 392 6900 jf206706 (((k)->auk_policy & AUDIT_GROUP) ? au_write((u),\ 393 6900 jf206706 au_to_groups(crgetgroups(c), \ 394 6900 jf206706 crgetngroups(c))) : (void) 0) 395 4165 tz204579 396 4165 tz204579 #define AUDIT_SETSUBJ(u, c, a, k) \ 397 4165 tz204579 AUDIT_SETSUBJ_GENERIC(u, c, a, k, curproc->p_pid) 398 0 stevel 399 0 stevel /* 400 0 stevel * Macros for type conversion 401 0 stevel */ 402 0 stevel 403 0 stevel /* au_membuf head, to typed data */ 404 0 stevel #define memtod(x, t) ((t)x->buf) 405 0 stevel 406 0 stevel /* au_membuf types */ 407 0 stevel #define MT_FREE 0 /* should be on free list */ 408 0 stevel #define MT_DATA 1 /* dynamic (data) allocation */ 409 0 stevel 410 0 stevel /* flags to au_memget */ 411 0 stevel #define DONTWAIT 0 412 0 stevel #define WAIT 1 413 0 stevel 414 0 stevel #define AU_PACK 1 /* pack data in au_append_rec() */ 415 0 stevel #define AU_LINK 0 /* link data in au_append_rec() */ 416 0 stevel 417 0 stevel /* flags to async routines */ 418 0 stevel #define AU_BACKEND 1 /* called from softcall backend */ 419 0 stevel 420 0 stevel #ifdef __cplusplus 421 0 stevel } 422 0 stevel #endif 423 0 stevel 424 0 stevel #endif /* _BSM_AUDIT_KERNEL_H */ 425