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