audit_pipe.c (183381) | audit_pipe.c (184488) |
---|---|
1/*- 2 * Copyright (c) 2006 Robert N. M. Watson | 1/*- 2 * Copyright (c) 2006 Robert N. M. Watson |
3 * Copyright (c) 2008 Apple, Inc. |
|
3 * All rights reserved. 4 * 5 * This software was developed by Robert Watson for the TrustedBSD Project. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 4 * All rights reserved. 5 * 6 * This software was developed by Robert Watson for the TrustedBSD Project. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/security/audit/audit_pipe.c 183381 2008-09-26 14:19:52Z ed $"); | 31__FBSDID("$FreeBSD: head/sys/security/audit/audit_pipe.c 184488 2008-10-30 21:58:39Z rwatson $"); |
31 32#include <sys/param.h> 33#include <sys/condvar.h> 34#include <sys/conf.h> 35#include <sys/eventhandler.h> 36#include <sys/filio.h> 37#include <sys/kernel.h> 38#include <sys/lock.h> 39#include <sys/malloc.h> 40#include <sys/mutex.h> 41#include <sys/poll.h> 42#include <sys/proc.h> 43#include <sys/queue.h> | 32 33#include <sys/param.h> 34#include <sys/condvar.h> 35#include <sys/conf.h> 36#include <sys/eventhandler.h> 37#include <sys/filio.h> 38#include <sys/kernel.h> 39#include <sys/lock.h> 40#include <sys/malloc.h> 41#include <sys/mutex.h> 42#include <sys/poll.h> 43#include <sys/proc.h> 44#include <sys/queue.h> |
45#include <sys/rwlock.h> |
|
44#include <sys/selinfo.h> 45#include <sys/sigio.h> 46#include <sys/signal.h> 47#include <sys/signalvar.h> 48#include <sys/systm.h> 49#include <sys/uio.h> 50 51#include <security/audit/audit.h> --- 58 unchanged lines hidden (view full) --- 110#define AUDIT_PIPE_NBIO 0x00000002 111struct audit_pipe { 112 int ap_open; /* Device open? */ 113 u_int ap_flags; 114 115 struct selinfo ap_selinfo; 116 struct sigio *ap_sigio; 117 | 46#include <sys/selinfo.h> 47#include <sys/sigio.h> 48#include <sys/signal.h> 49#include <sys/signalvar.h> 50#include <sys/systm.h> 51#include <sys/uio.h> 52 53#include <security/audit/audit.h> --- 58 unchanged lines hidden (view full) --- 112#define AUDIT_PIPE_NBIO 0x00000002 113struct audit_pipe { 114 int ap_open; /* Device open? */ 115 u_int ap_flags; 116 117 struct selinfo ap_selinfo; 118 struct sigio *ap_sigio; 119 |
120 /* 121 * Per-pipe mutex protecting most fields in this data structure. 122 */ 123 struct mtx ap_lock; 124 125 /* 126 * Condition variable to signal when data has been delivered to a 127 * pipe. 128 */ 129 struct cv ap_cv; 130 |
|
118 u_int ap_qlen; 119 u_int ap_qlimit; 120 121 u_int64_t ap_inserts; /* Records added. */ 122 u_int64_t ap_reads; /* Records read. */ 123 u_int64_t ap_drops; /* Records dropped. */ 124 u_int64_t ap_truncates; /* Records too long. */ 125 --- 13 unchanged lines hidden (view full) --- 139 TAILQ_HEAD(, audit_pipe_entry) ap_queue; 140 141 /* 142 * Global pipe list. 143 */ 144 TAILQ_ENTRY(audit_pipe) ap_list; 145}; 146 | 131 u_int ap_qlen; 132 u_int ap_qlimit; 133 134 u_int64_t ap_inserts; /* Records added. */ 135 u_int64_t ap_reads; /* Records read. */ 136 u_int64_t ap_drops; /* Records dropped. */ 137 u_int64_t ap_truncates; /* Records too long. */ 138 --- 13 unchanged lines hidden (view full) --- 152 TAILQ_HEAD(, audit_pipe_entry) ap_queue; 153 154 /* 155 * Global pipe list. 156 */ 157 TAILQ_ENTRY(audit_pipe) ap_list; 158}; 159 |
160#define AUDIT_PIPE_LOCK(ap) mtx_lock(&(ap)->ap_lock) 161#define AUDIT_PIPE_LOCK_ASSERT(ap) mtx_assert(&(ap)->ap_lock, MA_OWNED) 162#define AUDIT_PIPE_LOCK_DESTROY(ap) mtx_destroy(&(ap)->ap_lock) 163#define AUDIT_PIPE_LOCK_INIT(ap) mtx_init(&(ap)->ap_lock, \ 164 "audit_pipe_lock", NULL, MTX_DEF) 165#define AUDIT_PIPE_UNLOCK(ap) mtx_unlock(&(ap)->ap_lock) 166#define AUDIT_PIPE_MTX(ap) (&(ap)->ap_lock) 167 |
|
147/* | 168/* |
148 * Global list of audit pipes, mutex to protect it and the pipes. Finer 149 * grained locking may be desirable at some point. | 169 * Global list of audit pipes, rwlock to protect it. Individual record 170 * queues on pipes are protected by per-pipe locks; these locks synchronize 171 * between threads walking the list to deliver to individual pipes and add/ 172 * remove of pipes, and are mostly acquired for read. |
150 */ 151static TAILQ_HEAD(, audit_pipe) audit_pipe_list; | 173 */ 174static TAILQ_HEAD(, audit_pipe) audit_pipe_list; |
152static struct mtx audit_pipe_mtx; | 175static struct rwlock audit_pipe_lock; |
153 | 176 |
154/* 155 * This CV is used to wakeup on an audit record write. Eventually, it might 156 * be per-pipe to avoid unnecessary wakeups when several pipes with different 157 * preselection masks are present. 158 */ 159static struct cv audit_pipe_cv; | 177#define AUDIT_PIPE_LIST_LOCK_INIT() rw_init(&audit_pipe_lock, \ 178 "audit_pipe_list_lock") 179#define AUDIT_PIPE_LIST_RLOCK() rw_rlock(&audit_pipe_lock) 180#define AUDIT_PIPE_LIST_RUNLOCK() rw_runlock(&audit_pipe_lock) 181#define AUDIT_PIPE_LIST_WLOCK() rw_wlock(&audit_pipe_lock) 182#define AUDIT_PIPE_LIST_WLOCK_ASSERT() rw_assert(&audit_pipe_lock, \ 183 RA_WLOCKED) 184#define AUDIT_PIPE_LIST_WUNLOCK() rw_wunlock(&audit_pipe_lock) |
160 161/* 162 * Cloning related variables and constants. 163 */ 164#define AUDIT_PIPE_NAME "auditpipe" 165static eventhandler_tag audit_pipe_eh_tag; 166static struct clonedevs *audit_pipe_clones; 167 --- 51 unchanged lines hidden (view full) --- 219/* 220 * Find an audit pipe preselection specification for an auid, if any. 221 */ 222static struct audit_pipe_preselect * 223audit_pipe_preselect_find(struct audit_pipe *ap, au_id_t auid) 224{ 225 struct audit_pipe_preselect *app; 226 | 185 186/* 187 * Cloning related variables and constants. 188 */ 189#define AUDIT_PIPE_NAME "auditpipe" 190static eventhandler_tag audit_pipe_eh_tag; 191static struct clonedevs *audit_pipe_clones; 192 --- 51 unchanged lines hidden (view full) --- 244/* 245 * Find an audit pipe preselection specification for an auid, if any. 246 */ 247static struct audit_pipe_preselect * 248audit_pipe_preselect_find(struct audit_pipe *ap, au_id_t auid) 249{ 250 struct audit_pipe_preselect *app; 251 |
227 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 252 AUDIT_PIPE_LOCK_ASSERT(ap); |
228 229 TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) { 230 if (app->app_auid == auid) 231 return (app); 232 } 233 return (NULL); 234} 235 236/* 237 * Query the per-pipe mask for a specific auid. 238 */ 239static int 240audit_pipe_preselect_get(struct audit_pipe *ap, au_id_t auid, 241 au_mask_t *maskp) 242{ 243 struct audit_pipe_preselect *app; 244 int error; 245 | 253 254 TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) { 255 if (app->app_auid == auid) 256 return (app); 257 } 258 return (NULL); 259} 260 261/* 262 * Query the per-pipe mask for a specific auid. 263 */ 264static int 265audit_pipe_preselect_get(struct audit_pipe *ap, au_id_t auid, 266 au_mask_t *maskp) 267{ 268 struct audit_pipe_preselect *app; 269 int error; 270 |
246 mtx_lock(&audit_pipe_mtx); | 271 AUDIT_PIPE_LOCK(ap); |
247 app = audit_pipe_preselect_find(ap, auid); 248 if (app != NULL) { 249 *maskp = app->app_mask; 250 error = 0; 251 } else 252 error = ENOENT; | 272 app = audit_pipe_preselect_find(ap, auid); 273 if (app != NULL) { 274 *maskp = app->app_mask; 275 error = 0; 276 } else 277 error = ENOENT; |
253 mtx_unlock(&audit_pipe_mtx); | 278 AUDIT_PIPE_UNLOCK(ap); |
254 return (error); 255} 256 257/* 258 * Set the per-pipe mask for a specific auid. Add a new entry if needed; 259 * otherwise, update the current entry. 260 */ 261static void 262audit_pipe_preselect_set(struct audit_pipe *ap, au_id_t auid, au_mask_t mask) 263{ 264 struct audit_pipe_preselect *app, *app_new; 265 266 /* 267 * Pessimistically assume that the auid doesn't already have a mask 268 * set, and allocate. We will free it if it is unneeded. 269 */ 270 app_new = malloc(sizeof(*app_new), M_AUDIT_PIPE_PRESELECT, M_WAITOK); | 279 return (error); 280} 281 282/* 283 * Set the per-pipe mask for a specific auid. Add a new entry if needed; 284 * otherwise, update the current entry. 285 */ 286static void 287audit_pipe_preselect_set(struct audit_pipe *ap, au_id_t auid, au_mask_t mask) 288{ 289 struct audit_pipe_preselect *app, *app_new; 290 291 /* 292 * Pessimistically assume that the auid doesn't already have a mask 293 * set, and allocate. We will free it if it is unneeded. 294 */ 295 app_new = malloc(sizeof(*app_new), M_AUDIT_PIPE_PRESELECT, M_WAITOK); |
271 mtx_lock(&audit_pipe_mtx); | 296 AUDIT_PIPE_LOCK(ap); |
272 app = audit_pipe_preselect_find(ap, auid); 273 if (app == NULL) { 274 app = app_new; 275 app_new = NULL; 276 app->app_auid = auid; 277 TAILQ_INSERT_TAIL(&ap->ap_preselect_list, app, app_list); 278 } 279 app->app_mask = mask; | 297 app = audit_pipe_preselect_find(ap, auid); 298 if (app == NULL) { 299 app = app_new; 300 app_new = NULL; 301 app->app_auid = auid; 302 TAILQ_INSERT_TAIL(&ap->ap_preselect_list, app, app_list); 303 } 304 app->app_mask = mask; |
280 mtx_unlock(&audit_pipe_mtx); | 305 AUDIT_PIPE_UNLOCK(ap); |
281 if (app_new != NULL) 282 free(app_new, M_AUDIT_PIPE_PRESELECT); 283} 284 285/* 286 * Delete a per-auid mask on an audit pipe. 287 */ 288static int 289audit_pipe_preselect_delete(struct audit_pipe *ap, au_id_t auid) 290{ 291 struct audit_pipe_preselect *app; 292 int error; 293 | 306 if (app_new != NULL) 307 free(app_new, M_AUDIT_PIPE_PRESELECT); 308} 309 310/* 311 * Delete a per-auid mask on an audit pipe. 312 */ 313static int 314audit_pipe_preselect_delete(struct audit_pipe *ap, au_id_t auid) 315{ 316 struct audit_pipe_preselect *app; 317 int error; 318 |
294 mtx_lock(&audit_pipe_mtx); | 319 AUDIT_PIPE_LOCK(ap); |
295 app = audit_pipe_preselect_find(ap, auid); 296 if (app != NULL) { 297 TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); 298 error = 0; 299 } else 300 error = ENOENT; | 320 app = audit_pipe_preselect_find(ap, auid); 321 if (app != NULL) { 322 TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); 323 error = 0; 324 } else 325 error = ENOENT; |
301 mtx_unlock(&audit_pipe_mtx); | 326 AUDIT_PIPE_UNLOCK(ap); |
302 if (app != NULL) 303 free(app, M_AUDIT_PIPE_PRESELECT); 304 return (error); 305} 306 307/* 308 * Delete all per-auid masks on an audit pipe. 309 */ 310static void 311audit_pipe_preselect_flush_locked(struct audit_pipe *ap) 312{ 313 struct audit_pipe_preselect *app; 314 | 327 if (app != NULL) 328 free(app, M_AUDIT_PIPE_PRESELECT); 329 return (error); 330} 331 332/* 333 * Delete all per-auid masks on an audit pipe. 334 */ 335static void 336audit_pipe_preselect_flush_locked(struct audit_pipe *ap) 337{ 338 struct audit_pipe_preselect *app; 339 |
315 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 340 AUDIT_PIPE_LOCK_ASSERT(ap); |
316 317 while ((app = TAILQ_FIRST(&ap->ap_preselect_list)) != NULL) { 318 TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); 319 free(app, M_AUDIT_PIPE_PRESELECT); 320 } 321} 322 323static void 324audit_pipe_preselect_flush(struct audit_pipe *ap) 325{ 326 | 341 342 while ((app = TAILQ_FIRST(&ap->ap_preselect_list)) != NULL) { 343 TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); 344 free(app, M_AUDIT_PIPE_PRESELECT); 345 } 346} 347 348static void 349audit_pipe_preselect_flush(struct audit_pipe *ap) 350{ 351 |
327 mtx_lock(&audit_pipe_mtx); | 352 AUDIT_PIPE_LOCK(ap); |
328 audit_pipe_preselect_flush_locked(ap); | 353 audit_pipe_preselect_flush_locked(ap); |
329 mtx_unlock(&audit_pipe_mtx); | 354 AUDIT_PIPE_UNLOCK(ap); |
330} 331 332/*- 333 * Determine whether a specific audit pipe matches a record with these 334 * properties. Algorithm is as follows: 335 * 336 * - If the pipe is configured to track the default trail configuration, then 337 * use the results of global preselection matching. 338 * - If not, search for a specifically configured auid entry matching the 339 * event. If an entry is found, use that. 340 * - Otherwise, use the default flags or naflags configured for the pipe. 341 */ 342static int 343audit_pipe_preselect_check(struct audit_pipe *ap, au_id_t auid, 344 au_event_t event, au_class_t class, int sorf, int trail_preselect) 345{ 346 struct audit_pipe_preselect *app; 347 | 355} 356 357/*- 358 * Determine whether a specific audit pipe matches a record with these 359 * properties. Algorithm is as follows: 360 * 361 * - If the pipe is configured to track the default trail configuration, then 362 * use the results of global preselection matching. 363 * - If not, search for a specifically configured auid entry matching the 364 * event. If an entry is found, use that. 365 * - Otherwise, use the default flags or naflags configured for the pipe. 366 */ 367static int 368audit_pipe_preselect_check(struct audit_pipe *ap, au_id_t auid, 369 au_event_t event, au_class_t class, int sorf, int trail_preselect) 370{ 371 struct audit_pipe_preselect *app; 372 |
348 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 373 AUDIT_PIPE_LOCK_ASSERT(ap); |
349 350 switch (ap->ap_preselect_mode) { 351 case AUDITPIPE_PRESELECT_MODE_TRAIL: 352 return (trail_preselect); 353 354 case AUDITPIPE_PRESELECT_MODE_LOCAL: 355 app = audit_pipe_preselect_find(ap, auid); 356 if (app == NULL) { --- 20 unchanged lines hidden (view full) --- 377 * properties. 378 */ 379int 380audit_pipe_preselect(au_id_t auid, au_event_t event, au_class_t class, 381 int sorf, int trail_preselect) 382{ 383 struct audit_pipe *ap; 384 | 374 375 switch (ap->ap_preselect_mode) { 376 case AUDITPIPE_PRESELECT_MODE_TRAIL: 377 return (trail_preselect); 378 379 case AUDITPIPE_PRESELECT_MODE_LOCAL: 380 app = audit_pipe_preselect_find(ap, auid); 381 if (app == NULL) { --- 20 unchanged lines hidden (view full) --- 402 * properties. 403 */ 404int 405audit_pipe_preselect(au_id_t auid, au_event_t event, au_class_t class, 406 int sorf, int trail_preselect) 407{ 408 struct audit_pipe *ap; 409 |
385 mtx_lock(&audit_pipe_mtx); | 410 AUDIT_PIPE_LIST_RLOCK(); |
386 TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { | 411 TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { |
412 AUDIT_PIPE_LOCK(ap); |
|
387 if (audit_pipe_preselect_check(ap, auid, event, class, sorf, 388 trail_preselect)) { | 413 if (audit_pipe_preselect_check(ap, auid, event, class, sorf, 414 trail_preselect)) { |
389 mtx_unlock(&audit_pipe_mtx); | 415 AUDIT_PIPE_UNLOCK(ap); 416 AUDIT_PIPE_LIST_RUNLOCK(); |
390 return (1); 391 } | 417 return (1); 418 } |
419 AUDIT_PIPE_UNLOCK(ap); |
|
392 } | 420 } |
393 mtx_unlock(&audit_pipe_mtx); | 421 AUDIT_PIPE_LIST_RUNLOCK(); |
394 return (0); 395} 396 397/* 398 * Append individual record to a queue -- allocate queue-local buffer, and 399 * add to the queue. We try to drop from the head of the queue so that more 400 * recent events take precedence over older ones, but if allocation fails we 401 * do drop the new event. 402 */ 403static void 404audit_pipe_append(struct audit_pipe *ap, void *record, u_int record_len) 405{ 406 struct audit_pipe_entry *ape, *ape_remove; 407 | 422 return (0); 423} 424 425/* 426 * Append individual record to a queue -- allocate queue-local buffer, and 427 * add to the queue. We try to drop from the head of the queue so that more 428 * recent events take precedence over older ones, but if allocation fails we 429 * do drop the new event. 430 */ 431static void 432audit_pipe_append(struct audit_pipe *ap, void *record, u_int record_len) 433{ 434 struct audit_pipe_entry *ape, *ape_remove; 435 |
408 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 436 AUDIT_PIPE_LOCK_ASSERT(ap); |
409 410 ape = malloc(sizeof(*ape), M_AUDIT_PIPE_ENTRY, M_NOWAIT | M_ZERO); 411 if (ape == NULL) { 412 ap->ap_drops++; 413 audit_pipe_drops++; 414 return; 415 } 416 --- 19 unchanged lines hidden (view full) --- 436 437 TAILQ_INSERT_TAIL(&ap->ap_queue, ape, ape_queue); 438 ap->ap_inserts++; 439 ap->ap_qlen++; 440 selwakeuppri(&ap->ap_selinfo, PSOCK); 441 KNOTE_LOCKED(&ap->ap_selinfo.si_note, 0); 442 if (ap->ap_flags & AUDIT_PIPE_ASYNC) 443 pgsigio(&ap->ap_sigio, SIGIO, 0); | 437 438 ape = malloc(sizeof(*ape), M_AUDIT_PIPE_ENTRY, M_NOWAIT | M_ZERO); 439 if (ape == NULL) { 440 ap->ap_drops++; 441 audit_pipe_drops++; 442 return; 443 } 444 --- 19 unchanged lines hidden (view full) --- 464 465 TAILQ_INSERT_TAIL(&ap->ap_queue, ape, ape_queue); 466 ap->ap_inserts++; 467 ap->ap_qlen++; 468 selwakeuppri(&ap->ap_selinfo, PSOCK); 469 KNOTE_LOCKED(&ap->ap_selinfo.si_note, 0); 470 if (ap->ap_flags & AUDIT_PIPE_ASYNC) 471 pgsigio(&ap->ap_sigio, SIGIO, 0); |
472 cv_broadcast(&ap->ap_cv); |
|
444} 445 446/* 447 * audit_pipe_submit(): audit_worker submits audit records via this 448 * interface, which arranges for them to be delivered to pipe queues. 449 */ 450void 451audit_pipe_submit(au_id_t auid, au_event_t event, au_class_t class, int sorf, 452 int trail_select, void *record, u_int record_len) 453{ 454 struct audit_pipe *ap; 455 456 /* | 473} 474 475/* 476 * audit_pipe_submit(): audit_worker submits audit records via this 477 * interface, which arranges for them to be delivered to pipe queues. 478 */ 479void 480audit_pipe_submit(au_id_t auid, au_event_t event, au_class_t class, int sorf, 481 int trail_select, void *record, u_int record_len) 482{ 483 struct audit_pipe *ap; 484 485 /* |
457 * Lockless read to avoid mutex overhead if pipes are not in use. | 486 * Lockless read to avoid lock overhead if pipes are not in use. |
458 */ 459 if (TAILQ_FIRST(&audit_pipe_list) == NULL) 460 return; 461 | 487 */ 488 if (TAILQ_FIRST(&audit_pipe_list) == NULL) 489 return; 490 |
462 mtx_lock(&audit_pipe_mtx); | 491 AUDIT_PIPE_LIST_RLOCK(); |
463 TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { | 492 TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { |
493 AUDIT_PIPE_LOCK(ap); |
|
464 if (audit_pipe_preselect_check(ap, auid, event, class, sorf, 465 trail_select)) 466 audit_pipe_append(ap, record, record_len); | 494 if (audit_pipe_preselect_check(ap, auid, event, class, sorf, 495 trail_select)) 496 audit_pipe_append(ap, record, record_len); |
497 AUDIT_PIPE_UNLOCK(ap); |
|
467 } | 498 } |
499 AUDIT_PIPE_LIST_RUNLOCK(); 500 501 /* Unlocked increment. */ |
|
468 audit_pipe_records++; | 502 audit_pipe_records++; |
469 mtx_unlock(&audit_pipe_mtx); 470 cv_broadcastpri(&audit_pipe_cv, PSOCK); | |
471} 472 473/* 474 * audit_pipe_submit_user(): the same as audit_pipe_submit(), except that 475 * since we don't currently have selection information available, it is 476 * delivered to the pipe unconditionally. 477 * 478 * XXXRW: This is a bug. The BSM check routine for submitting a user record 479 * should parse that information and return it. 480 */ 481void 482audit_pipe_submit_user(void *record, u_int record_len) 483{ 484 struct audit_pipe *ap; 485 486 /* | 503} 504 505/* 506 * audit_pipe_submit_user(): the same as audit_pipe_submit(), except that 507 * since we don't currently have selection information available, it is 508 * delivered to the pipe unconditionally. 509 * 510 * XXXRW: This is a bug. The BSM check routine for submitting a user record 511 * should parse that information and return it. 512 */ 513void 514audit_pipe_submit_user(void *record, u_int record_len) 515{ 516 struct audit_pipe *ap; 517 518 /* |
487 * Lockless read to avoid mutex overhead if pipes are not in use. | 519 * Lockless read to avoid lock overhead if pipes are not in use. |
488 */ 489 if (TAILQ_FIRST(&audit_pipe_list) == NULL) 490 return; 491 | 520 */ 521 if (TAILQ_FIRST(&audit_pipe_list) == NULL) 522 return; 523 |
492 mtx_lock(&audit_pipe_mtx); 493 TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) | 524 AUDIT_PIPE_LIST_RLOCK(); 525 TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { 526 AUDIT_PIPE_LOCK(ap); |
494 audit_pipe_append(ap, record, record_len); | 527 audit_pipe_append(ap, record, record_len); |
528 AUDIT_PIPE_UNLOCK(ap); 529 } 530 AUDIT_PIPE_LIST_RUNLOCK(); 531 532 /* Unlocked increment. */ |
|
495 audit_pipe_records++; | 533 audit_pipe_records++; |
496 mtx_unlock(&audit_pipe_mtx); 497 cv_broadcastpri(&audit_pipe_cv, PSOCK); | |
498} 499 500/* 501 * Pop the next record off of an audit pipe. 502 */ 503static struct audit_pipe_entry * 504audit_pipe_pop(struct audit_pipe *ap) 505{ 506 struct audit_pipe_entry *ape; 507 | 534} 535 536/* 537 * Pop the next record off of an audit pipe. 538 */ 539static struct audit_pipe_entry * 540audit_pipe_pop(struct audit_pipe *ap) 541{ 542 struct audit_pipe_entry *ape; 543 |
508 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 544 AUDIT_PIPE_LOCK_ASSERT(ap); |
509 510 ape = TAILQ_FIRST(&ap->ap_queue); 511 KASSERT((ape == NULL && ap->ap_qlen == 0) || 512 (ape != NULL && ap->ap_qlen != 0), ("audit_pipe_pop: qlen")); 513 if (ape == NULL) 514 return (NULL); 515 TAILQ_REMOVE(&ap->ap_queue, ape, ape_queue); 516 ap->ap_qlen--; --- 4 unchanged lines hidden (view full) --- 521 * Allocate a new audit pipe. Connects the pipe, on success, to the global 522 * list and updates statistics. 523 */ 524static struct audit_pipe * 525audit_pipe_alloc(void) 526{ 527 struct audit_pipe *ap; 528 | 545 546 ape = TAILQ_FIRST(&ap->ap_queue); 547 KASSERT((ape == NULL && ap->ap_qlen == 0) || 548 (ape != NULL && ap->ap_qlen != 0), ("audit_pipe_pop: qlen")); 549 if (ape == NULL) 550 return (NULL); 551 TAILQ_REMOVE(&ap->ap_queue, ape, ape_queue); 552 ap->ap_qlen--; --- 4 unchanged lines hidden (view full) --- 557 * Allocate a new audit pipe. Connects the pipe, on success, to the global 558 * list and updates statistics. 559 */ 560static struct audit_pipe * 561audit_pipe_alloc(void) 562{ 563 struct audit_pipe *ap; 564 |
529 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 565 AUDIT_PIPE_LIST_WLOCK_ASSERT(); |
530 531 ap = malloc(sizeof(*ap), M_AUDIT_PIPE, M_NOWAIT | M_ZERO); 532 if (ap == NULL) 533 return (NULL); 534 ap->ap_qlimit = AUDIT_PIPE_QLIMIT_DEFAULT; 535 TAILQ_INIT(&ap->ap_queue); | 566 567 ap = malloc(sizeof(*ap), M_AUDIT_PIPE, M_NOWAIT | M_ZERO); 568 if (ap == NULL) 569 return (NULL); 570 ap->ap_qlimit = AUDIT_PIPE_QLIMIT_DEFAULT; 571 TAILQ_INIT(&ap->ap_queue); |
536 knlist_init(&ap->ap_selinfo.si_note, &audit_pipe_mtx, NULL, NULL, | 572 knlist_init(&ap->ap_selinfo.si_note, AUDIT_PIPE_MTX(ap), NULL, NULL, |
537 NULL); | 573 NULL); |
574 AUDIT_PIPE_LOCK_INIT(ap); 575 cv_init(&ap->ap_cv, "audit_pipe"); |
|
538 539 /* 540 * Default flags, naflags, and auid-specific preselection settings to 541 * 0. Initialize the mode to the global trail so that if praudit(1) 542 * is run on /dev/auditpipe, it sees events associated with the 543 * default trail. Pipe-aware application can clear the flag, set 544 * custom masks, and flush the pipe as needed. 545 */ --- 15 unchanged lines hidden (view full) --- 561/* 562 * Flush all records currently present in an audit pipe; assume mutex is held. 563 */ 564static void 565audit_pipe_flush(struct audit_pipe *ap) 566{ 567 struct audit_pipe_entry *ape; 568 | 576 577 /* 578 * Default flags, naflags, and auid-specific preselection settings to 579 * 0. Initialize the mode to the global trail so that if praudit(1) 580 * is run on /dev/auditpipe, it sees events associated with the 581 * default trail. Pipe-aware application can clear the flag, set 582 * custom masks, and flush the pipe as needed. 583 */ --- 15 unchanged lines hidden (view full) --- 599/* 600 * Flush all records currently present in an audit pipe; assume mutex is held. 601 */ 602static void 603audit_pipe_flush(struct audit_pipe *ap) 604{ 605 struct audit_pipe_entry *ape; 606 |
569 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 607 AUDIT_PIPE_LOCK_ASSERT(ap); |
570 571 while ((ape = TAILQ_FIRST(&ap->ap_queue)) != NULL) { 572 TAILQ_REMOVE(&ap->ap_queue, ape, ape_queue); 573 audit_pipe_entry_free(ape); 574 ap->ap_qlen--; 575 } 576 KASSERT(ap->ap_qlen == 0, ("audit_pipe_free: ap_qlen")); 577} 578 579/* 580 * Free an audit pipe; this means freeing all preselection state and all | 608 609 while ((ape = TAILQ_FIRST(&ap->ap_queue)) != NULL) { 610 TAILQ_REMOVE(&ap->ap_queue, ape, ape_queue); 611 audit_pipe_entry_free(ape); 612 ap->ap_qlen--; 613 } 614 KASSERT(ap->ap_qlen == 0, ("audit_pipe_free: ap_qlen")); 615} 616 617/* 618 * Free an audit pipe; this means freeing all preselection state and all |
581 * records in the pipe. Assumes mutex is held to prevent any new records 582 * from being inserted during the free, and that the audit pipe is still on 583 * the global list. | 619 * records in the pipe. Assumes global write lock and pipe mutex are held to 620 * prevent any new records from being inserted during the free, and that the 621 * audit pipe is still on the global list. |
584 */ 585static void 586audit_pipe_free(struct audit_pipe *ap) 587{ 588 | 622 */ 623static void 624audit_pipe_free(struct audit_pipe *ap) 625{ 626 |
589 mtx_assert(&audit_pipe_mtx, MA_OWNED); | 627 AUDIT_PIPE_LIST_WLOCK_ASSERT(); 628 AUDIT_PIPE_LOCK_ASSERT(ap); |
590 591 audit_pipe_preselect_flush_locked(ap); 592 audit_pipe_flush(ap); | 629 630 audit_pipe_preselect_flush_locked(ap); 631 audit_pipe_flush(ap); |
632 cv_destroy(&ap->ap_cv); 633 AUDIT_PIPE_LOCK_DESTROY(ap); |
|
593 knlist_destroy(&ap->ap_selinfo.si_note); 594 TAILQ_REMOVE(&audit_pipe_list, ap, ap_list); 595 free(ap, M_AUDIT_PIPE); 596 audit_pipe_count--; 597} 598 599/* 600 * Audit pipe clone routine -- provide specific requested audit pipe, or a --- 29 unchanged lines hidden (view full) --- 630 * allows file permissions on the special device to be used to grant audit 631 * review access. Those file permissions should be managed carefully. 632 */ 633static int 634audit_pipe_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 635{ 636 struct audit_pipe *ap; 637 | 634 knlist_destroy(&ap->ap_selinfo.si_note); 635 TAILQ_REMOVE(&audit_pipe_list, ap, ap_list); 636 free(ap, M_AUDIT_PIPE); 637 audit_pipe_count--; 638} 639 640/* 641 * Audit pipe clone routine -- provide specific requested audit pipe, or a --- 29 unchanged lines hidden (view full) --- 671 * allows file permissions on the special device to be used to grant audit 672 * review access. Those file permissions should be managed carefully. 673 */ 674static int 675audit_pipe_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 676{ 677 struct audit_pipe *ap; 678 |
638 mtx_lock(&audit_pipe_mtx); | 679 AUDIT_PIPE_LIST_WLOCK(); |
639 ap = dev->si_drv1; 640 if (ap == NULL) { 641 ap = audit_pipe_alloc(); 642 if (ap == NULL) { | 680 ap = dev->si_drv1; 681 if (ap == NULL) { 682 ap = audit_pipe_alloc(); 683 if (ap == NULL) { |
643 mtx_unlock(&audit_pipe_mtx); | 684 AUDIT_PIPE_LIST_WUNLOCK(); |
644 return (ENOMEM); 645 } 646 dev->si_drv1 = ap; 647 } else { 648 KASSERT(ap->ap_open, ("audit_pipe_open: ap && !ap_open")); | 685 return (ENOMEM); 686 } 687 dev->si_drv1 = ap; 688 } else { 689 KASSERT(ap->ap_open, ("audit_pipe_open: ap && !ap_open")); |
649 mtx_unlock(&audit_pipe_mtx); | 690 AUDIT_PIPE_LIST_WUNLOCK(); |
650 return (EBUSY); 651 } | 691 return (EBUSY); 692 } |
652 ap->ap_open = 1; 653 mtx_unlock(&audit_pipe_mtx); | 693 ap->ap_open = 1; /* No lock required yet. */ 694 AUDIT_PIPE_LIST_WUNLOCK(); |
654 fsetown(td->td_proc->p_pid, &ap->ap_sigio); 655 return (0); 656} 657 658/* 659 * Close audit pipe, tear down all records, etc. 660 */ 661static int 662audit_pipe_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 663{ 664 struct audit_pipe *ap; 665 666 ap = dev->si_drv1; 667 KASSERT(ap != NULL, ("audit_pipe_close: ap == NULL")); 668 KASSERT(ap->ap_open, ("audit_pipe_close: !ap_open")); | 695 fsetown(td->td_proc->p_pid, &ap->ap_sigio); 696 return (0); 697} 698 699/* 700 * Close audit pipe, tear down all records, etc. 701 */ 702static int 703audit_pipe_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 704{ 705 struct audit_pipe *ap; 706 707 ap = dev->si_drv1; 708 KASSERT(ap != NULL, ("audit_pipe_close: ap == NULL")); 709 KASSERT(ap->ap_open, ("audit_pipe_close: !ap_open")); |
710 |
|
669 funsetown(&ap->ap_sigio); | 711 funsetown(&ap->ap_sigio); |
670 mtx_lock(&audit_pipe_mtx); | 712 AUDIT_PIPE_LIST_WLOCK(); 713 AUDIT_PIPE_LOCK(ap); |
671 ap->ap_open = 0; 672 audit_pipe_free(ap); 673 dev->si_drv1 = NULL; | 714 ap->ap_open = 0; 715 audit_pipe_free(ap); 716 dev->si_drv1 = NULL; |
674 mtx_unlock(&audit_pipe_mtx); | 717 AUDIT_PIPE_LIST_WUNLOCK(); |
675 return (0); 676} 677 678/* 679 * Audit pipe ioctl() routine. Handle file descriptor and audit pipe layer 680 * commands. 681 * 682 * Would be desirable to support filtering, although perhaps something simple --- 14 unchanged lines hidden (view full) --- 697 698 /* 699 * Audit pipe ioctls: first come standard device node ioctls, then 700 * manipulation of pipe settings, and finally, statistics query 701 * ioctls. 702 */ 703 switch (cmd) { 704 case FIONBIO: | 718 return (0); 719} 720 721/* 722 * Audit pipe ioctl() routine. Handle file descriptor and audit pipe layer 723 * commands. 724 * 725 * Would be desirable to support filtering, although perhaps something simple --- 14 unchanged lines hidden (view full) --- 740 741 /* 742 * Audit pipe ioctls: first come standard device node ioctls, then 743 * manipulation of pipe settings, and finally, statistics query 744 * ioctls. 745 */ 746 switch (cmd) { 747 case FIONBIO: |
705 mtx_lock(&audit_pipe_mtx); | 748 AUDIT_PIPE_LOCK(ap); |
706 if (*(int *)data) 707 ap->ap_flags |= AUDIT_PIPE_NBIO; 708 else 709 ap->ap_flags &= ~AUDIT_PIPE_NBIO; | 749 if (*(int *)data) 750 ap->ap_flags |= AUDIT_PIPE_NBIO; 751 else 752 ap->ap_flags &= ~AUDIT_PIPE_NBIO; |
710 mtx_unlock(&audit_pipe_mtx); | 753 AUDIT_PIPE_UNLOCK(ap); |
711 error = 0; 712 break; 713 714 case FIONREAD: | 754 error = 0; 755 break; 756 757 case FIONREAD: |
715 mtx_lock(&audit_pipe_mtx); | 758 AUDIT_PIPE_LOCK(ap); |
716 if (TAILQ_FIRST(&ap->ap_queue) != NULL) 717 *(int *)data = 718 TAILQ_FIRST(&ap->ap_queue)->ape_record_len; 719 else 720 *(int *)data = 0; | 759 if (TAILQ_FIRST(&ap->ap_queue) != NULL) 760 *(int *)data = 761 TAILQ_FIRST(&ap->ap_queue)->ape_record_len; 762 else 763 *(int *)data = 0; |
721 mtx_unlock(&audit_pipe_mtx); | 764 AUDIT_PIPE_UNLOCK(ap); |
722 error = 0; 723 break; 724 725 case FIOASYNC: | 765 error = 0; 766 break; 767 768 case FIOASYNC: |
726 mtx_lock(&audit_pipe_mtx); | 769 AUDIT_PIPE_LOCK(ap); |
727 if (*(int *)data) 728 ap->ap_flags |= AUDIT_PIPE_ASYNC; 729 else 730 ap->ap_flags &= ~AUDIT_PIPE_ASYNC; | 770 if (*(int *)data) 771 ap->ap_flags |= AUDIT_PIPE_ASYNC; 772 else 773 ap->ap_flags &= ~AUDIT_PIPE_ASYNC; |
731 mtx_unlock(&audit_pipe_mtx); | 774 AUDIT_PIPE_UNLOCK(ap); |
732 error = 0; 733 break; 734 735 case FIOSETOWN: 736 error = fsetown(*(int *)data, &ap->ap_sigio); 737 break; 738 739 case FIOGETOWN: --- 27 unchanged lines hidden (view full) --- 767 break; 768 769 case AUDITPIPE_GET_QLIMIT_MAX: 770 *(u_int *)data = AUDIT_PIPE_QLIMIT_MAX; 771 error = 0; 772 break; 773 774 case AUDITPIPE_GET_PRESELECT_FLAGS: | 775 error = 0; 776 break; 777 778 case FIOSETOWN: 779 error = fsetown(*(int *)data, &ap->ap_sigio); 780 break; 781 782 case FIOGETOWN: --- 27 unchanged lines hidden (view full) --- 810 break; 811 812 case AUDITPIPE_GET_QLIMIT_MAX: 813 *(u_int *)data = AUDIT_PIPE_QLIMIT_MAX; 814 error = 0; 815 break; 816 817 case AUDITPIPE_GET_PRESELECT_FLAGS: |
775 mtx_lock(&audit_pipe_mtx); | 818 AUDIT_PIPE_LOCK(ap); |
776 maskp = (au_mask_t *)data; 777 *maskp = ap->ap_preselect_flags; | 819 maskp = (au_mask_t *)data; 820 *maskp = ap->ap_preselect_flags; |
778 mtx_unlock(&audit_pipe_mtx); | 821 AUDIT_PIPE_UNLOCK(ap); |
779 error = 0; 780 break; 781 782 case AUDITPIPE_SET_PRESELECT_FLAGS: | 822 error = 0; 823 break; 824 825 case AUDITPIPE_SET_PRESELECT_FLAGS: |
783 mtx_lock(&audit_pipe_mtx); | 826 AUDIT_PIPE_LOCK(ap); |
784 maskp = (au_mask_t *)data; 785 ap->ap_preselect_flags = *maskp; | 827 maskp = (au_mask_t *)data; 828 ap->ap_preselect_flags = *maskp; |
786 mtx_unlock(&audit_pipe_mtx); | 829 AUDIT_PIPE_UNLOCK(ap); |
787 error = 0; 788 break; 789 790 case AUDITPIPE_GET_PRESELECT_NAFLAGS: | 830 error = 0; 831 break; 832 833 case AUDITPIPE_GET_PRESELECT_NAFLAGS: |
791 mtx_lock(&audit_pipe_mtx); | 834 AUDIT_PIPE_LOCK(ap); |
792 maskp = (au_mask_t *)data; 793 *maskp = ap->ap_preselect_naflags; | 835 maskp = (au_mask_t *)data; 836 *maskp = ap->ap_preselect_naflags; |
794 mtx_unlock(&audit_pipe_mtx); | 837 AUDIT_PIPE_UNLOCK(ap); |
795 error = 0; 796 break; 797 798 case AUDITPIPE_SET_PRESELECT_NAFLAGS: | 838 error = 0; 839 break; 840 841 case AUDITPIPE_SET_PRESELECT_NAFLAGS: |
799 mtx_lock(&audit_pipe_mtx); | 842 AUDIT_PIPE_LOCK(ap); |
800 maskp = (au_mask_t *)data; 801 ap->ap_preselect_naflags = *maskp; | 843 maskp = (au_mask_t *)data; 844 ap->ap_preselect_naflags = *maskp; |
802 mtx_unlock(&audit_pipe_mtx); | 845 AUDIT_PIPE_UNLOCK(ap); |
803 error = 0; 804 break; 805 806 case AUDITPIPE_GET_PRESELECT_AUID: 807 aip = (struct auditpipe_ioctl_preselect *)data; 808 error = audit_pipe_preselect_get(ap, aip->aip_auid, 809 &aip->aip_mask); 810 break; --- 10 unchanged lines hidden (view full) --- 821 break; 822 823 case AUDITPIPE_FLUSH_PRESELECT_AUID: 824 audit_pipe_preselect_flush(ap); 825 error = 0; 826 break; 827 828 case AUDITPIPE_GET_PRESELECT_MODE: | 846 error = 0; 847 break; 848 849 case AUDITPIPE_GET_PRESELECT_AUID: 850 aip = (struct auditpipe_ioctl_preselect *)data; 851 error = audit_pipe_preselect_get(ap, aip->aip_auid, 852 &aip->aip_mask); 853 break; --- 10 unchanged lines hidden (view full) --- 864 break; 865 866 case AUDITPIPE_FLUSH_PRESELECT_AUID: 867 audit_pipe_preselect_flush(ap); 868 error = 0; 869 break; 870 871 case AUDITPIPE_GET_PRESELECT_MODE: |
829 mtx_lock(&audit_pipe_mtx); | 872 AUDIT_PIPE_LOCK(ap); |
830 *(int *)data = ap->ap_preselect_mode; | 873 *(int *)data = ap->ap_preselect_mode; |
831 mtx_unlock(&audit_pipe_mtx); | 874 AUDIT_PIPE_UNLOCK(ap); |
832 error = 0; 833 break; 834 835 case AUDITPIPE_SET_PRESELECT_MODE: 836 mode = *(int *)data; 837 switch (mode) { 838 case AUDITPIPE_PRESELECT_MODE_TRAIL: 839 case AUDITPIPE_PRESELECT_MODE_LOCAL: | 875 error = 0; 876 break; 877 878 case AUDITPIPE_SET_PRESELECT_MODE: 879 mode = *(int *)data; 880 switch (mode) { 881 case AUDITPIPE_PRESELECT_MODE_TRAIL: 882 case AUDITPIPE_PRESELECT_MODE_LOCAL: |
840 mtx_lock(&audit_pipe_mtx); | 883 AUDIT_PIPE_LOCK(ap); |
841 ap->ap_preselect_mode = mode; | 884 ap->ap_preselect_mode = mode; |
842 mtx_unlock(&audit_pipe_mtx); | 885 AUDIT_PIPE_UNLOCK(ap); |
843 error = 0; 844 break; 845 846 default: 847 error = EINVAL; 848 } 849 break; 850 851 case AUDITPIPE_FLUSH: | 886 error = 0; 887 break; 888 889 default: 890 error = EINVAL; 891 } 892 break; 893 894 case AUDITPIPE_FLUSH: |
852 mtx_lock(&audit_pipe_mtx); | 895 AUDIT_PIPE_LOCK(ap); |
853 audit_pipe_flush(ap); | 896 audit_pipe_flush(ap); |
854 mtx_unlock(&audit_pipe_mtx); | 897 AUDIT_PIPE_UNLOCK(ap); |
855 error = 0; 856 break; 857 858 case AUDITPIPE_GET_MAXAUDITDATA: 859 *(u_int *)data = MAXAUDITDATA; 860 error = 0; 861 break; 862 --- 42 unchanged lines hidden (view full) --- 905audit_pipe_read(struct cdev *dev, struct uio *uio, int flag) 906{ 907 struct audit_pipe_entry *ape; 908 struct audit_pipe *ap; 909 int error; 910 911 ap = dev->si_drv1; 912 KASSERT(ap != NULL, ("audit_pipe_read: ap == NULL")); | 898 error = 0; 899 break; 900 901 case AUDITPIPE_GET_MAXAUDITDATA: 902 *(u_int *)data = MAXAUDITDATA; 903 error = 0; 904 break; 905 --- 42 unchanged lines hidden (view full) --- 948audit_pipe_read(struct cdev *dev, struct uio *uio, int flag) 949{ 950 struct audit_pipe_entry *ape; 951 struct audit_pipe *ap; 952 int error; 953 954 ap = dev->si_drv1; 955 KASSERT(ap != NULL, ("audit_pipe_read: ap == NULL")); |
913 mtx_lock(&audit_pipe_mtx); | 956 957 AUDIT_PIPE_LOCK(ap); |
914 do { 915 /* 916 * Wait for a record that fits into the read buffer, dropping 917 * records that would be truncated if actually passed to the 918 * process. This helps maintain the discreet record read 919 * interface. 920 */ 921 while ((ape = audit_pipe_pop(ap)) == NULL) { 922 if (ap->ap_flags & AUDIT_PIPE_NBIO) { | 958 do { 959 /* 960 * Wait for a record that fits into the read buffer, dropping 961 * records that would be truncated if actually passed to the 962 * process. This helps maintain the discreet record read 963 * interface. 964 */ 965 while ((ape = audit_pipe_pop(ap)) == NULL) { 966 if (ap->ap_flags & AUDIT_PIPE_NBIO) { |
923 mtx_unlock(&audit_pipe_mtx); | 967 AUDIT_PIPE_UNLOCK(ap); |
924 return (EAGAIN); 925 } | 968 return (EAGAIN); 969 } |
926 error = cv_wait_sig(&audit_pipe_cv, &audit_pipe_mtx); | 970 error = cv_wait_sig(&ap->ap_cv, AUDIT_PIPE_MTX(ap)); |
927 if (error) { | 971 if (error) { |
928 mtx_unlock(&audit_pipe_mtx); | 972 AUDIT_PIPE_UNLOCK(ap); |
929 return (error); 930 } 931 } 932 if (ape->ape_record_len <= uio->uio_resid) 933 break; 934 audit_pipe_entry_free(ape); 935 ap->ap_truncates++; 936 } while (1); 937 ap->ap_reads++; | 973 return (error); 974 } 975 } 976 if (ape->ape_record_len <= uio->uio_resid) 977 break; 978 audit_pipe_entry_free(ape); 979 ap->ap_truncates++; 980 } while (1); 981 ap->ap_reads++; |
938 mtx_unlock(&audit_pipe_mtx); | 982 AUDIT_PIPE_UNLOCK(ap); |
939 940 /* 941 * Now read record to user space memory. Even if the read is short, 942 * we abandon the remainder of the record, supporting only discreet 943 * record reads. 944 */ 945 error = uiomove(ape->ape_record, ape->ape_record_len, uio); 946 audit_pipe_entry_free(ape); --- 7 unchanged lines hidden (view full) --- 954audit_pipe_poll(struct cdev *dev, int events, struct thread *td) 955{ 956 struct audit_pipe *ap; 957 int revents; 958 959 revents = 0; 960 ap = dev->si_drv1; 961 KASSERT(ap != NULL, ("audit_pipe_poll: ap == NULL")); | 983 984 /* 985 * Now read record to user space memory. Even if the read is short, 986 * we abandon the remainder of the record, supporting only discreet 987 * record reads. 988 */ 989 error = uiomove(ape->ape_record, ape->ape_record_len, uio); 990 audit_pipe_entry_free(ape); --- 7 unchanged lines hidden (view full) --- 998audit_pipe_poll(struct cdev *dev, int events, struct thread *td) 999{ 1000 struct audit_pipe *ap; 1001 int revents; 1002 1003 revents = 0; 1004 ap = dev->si_drv1; 1005 KASSERT(ap != NULL, ("audit_pipe_poll: ap == NULL")); |
1006 |
|
962 if (events & (POLLIN | POLLRDNORM)) { | 1007 if (events & (POLLIN | POLLRDNORM)) { |
963 mtx_lock(&audit_pipe_mtx); | 1008 AUDIT_PIPE_LOCK(ap); |
964 if (TAILQ_FIRST(&ap->ap_queue) != NULL) 965 revents |= events & (POLLIN | POLLRDNORM); 966 else 967 selrecord(td, &ap->ap_selinfo); | 1009 if (TAILQ_FIRST(&ap->ap_queue) != NULL) 1010 revents |= events & (POLLIN | POLLRDNORM); 1011 else 1012 selrecord(td, &ap->ap_selinfo); |
968 mtx_unlock(&audit_pipe_mtx); | 1013 AUDIT_PIPE_UNLOCK(ap); |
969 } 970 return (revents); 971} 972 973/* 974 * Audit pipe kqfilter. 975 */ 976static int --- 5 unchanged lines hidden (view full) --- 982 KASSERT(ap != NULL, ("audit_pipe_kqfilter: ap == NULL")); 983 984 if (kn->kn_filter != EVFILT_READ) 985 return (EINVAL); 986 987 kn->kn_fop = &audit_pipe_read_filterops; 988 kn->kn_hook = ap; 989 | 1014 } 1015 return (revents); 1016} 1017 1018/* 1019 * Audit pipe kqfilter. 1020 */ 1021static int --- 5 unchanged lines hidden (view full) --- 1027 KASSERT(ap != NULL, ("audit_pipe_kqfilter: ap == NULL")); 1028 1029 if (kn->kn_filter != EVFILT_READ) 1030 return (EINVAL); 1031 1032 kn->kn_fop = &audit_pipe_read_filterops; 1033 kn->kn_hook = ap; 1034 |
990 mtx_lock(&audit_pipe_mtx); | 1035 AUDIT_PIPE_LOCK(ap); |
991 knlist_add(&ap->ap_selinfo.si_note, kn, 1); | 1036 knlist_add(&ap->ap_selinfo.si_note, kn, 1); |
992 mtx_unlock(&audit_pipe_mtx); | 1037 AUDIT_PIPE_UNLOCK(ap); |
993 return (0); 994} 995 996/* 997 * Return true if there are records available for reading on the pipe. 998 */ 999static int 1000audit_pipe_kqread(struct knote *kn, long hint) 1001{ 1002 struct audit_pipe_entry *ape; 1003 struct audit_pipe *ap; 1004 | 1038 return (0); 1039} 1040 1041/* 1042 * Return true if there are records available for reading on the pipe. 1043 */ 1044static int 1045audit_pipe_kqread(struct knote *kn, long hint) 1046{ 1047 struct audit_pipe_entry *ape; 1048 struct audit_pipe *ap; 1049 |
1005 mtx_assert(&audit_pipe_mtx, MA_OWNED); 1006 | |
1007 ap = (struct audit_pipe *)kn->kn_hook; 1008 KASSERT(ap != NULL, ("audit_pipe_kqread: ap == NULL")); 1009 | 1050 ap = (struct audit_pipe *)kn->kn_hook; 1051 KASSERT(ap != NULL, ("audit_pipe_kqread: ap == NULL")); 1052 |
1053 AUDIT_PIPE_LOCK_ASSERT(ap); 1054 |
|
1010 if (ap->ap_qlen != 0) { 1011 ape = TAILQ_FIRST(&ap->ap_queue); 1012 KASSERT(ape != NULL, ("audit_pipe_kqread: ape == NULL")); 1013 1014 kn->kn_data = ape->ape_record_len; 1015 return (1); 1016 } else { 1017 kn->kn_data = 0; --- 7 unchanged lines hidden (view full) --- 1025static void 1026audit_pipe_kqdetach(struct knote *kn) 1027{ 1028 struct audit_pipe *ap; 1029 1030 ap = (struct audit_pipe *)kn->kn_hook; 1031 KASSERT(ap != NULL, ("audit_pipe_kqdetach: ap == NULL")); 1032 | 1055 if (ap->ap_qlen != 0) { 1056 ape = TAILQ_FIRST(&ap->ap_queue); 1057 KASSERT(ape != NULL, ("audit_pipe_kqread: ape == NULL")); 1058 1059 kn->kn_data = ape->ape_record_len; 1060 return (1); 1061 } else { 1062 kn->kn_data = 0; --- 7 unchanged lines hidden (view full) --- 1070static void 1071audit_pipe_kqdetach(struct knote *kn) 1072{ 1073 struct audit_pipe *ap; 1074 1075 ap = (struct audit_pipe *)kn->kn_hook; 1076 KASSERT(ap != NULL, ("audit_pipe_kqdetach: ap == NULL")); 1077 |
1033 mtx_lock(&audit_pipe_mtx); | 1078 AUDIT_PIPE_LOCK(ap); |
1034 knlist_remove(&ap->ap_selinfo.si_note, kn, 1); | 1079 knlist_remove(&ap->ap_selinfo.si_note, kn, 1); |
1035 mtx_unlock(&audit_pipe_mtx); | 1080 AUDIT_PIPE_UNLOCK(ap); |
1036} 1037 1038/* 1039 * Initialize the audit pipe system. 1040 */ 1041static void 1042audit_pipe_init(void *unused) 1043{ 1044 1045 TAILQ_INIT(&audit_pipe_list); | 1081} 1082 1083/* 1084 * Initialize the audit pipe system. 1085 */ 1086static void 1087audit_pipe_init(void *unused) 1088{ 1089 1090 TAILQ_INIT(&audit_pipe_list); |
1046 mtx_init(&audit_pipe_mtx, "audit_pipe_mtx", NULL, MTX_DEF); 1047 cv_init(&audit_pipe_cv, "audit_pipe_cv"); | 1091 AUDIT_PIPE_LIST_LOCK_INIT(); |
1048 1049 clone_setup(&audit_pipe_clones); 1050 audit_pipe_eh_tag = EVENTHANDLER_REGISTER(dev_clone, 1051 audit_pipe_clone, 0, 1000); 1052 if (audit_pipe_eh_tag == NULL) 1053 panic("audit_pipe_init: EVENTHANDLER_REGISTER"); 1054} 1055 1056SYSINIT(audit_pipe_init, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, audit_pipe_init, 1057 NULL); | 1092 1093 clone_setup(&audit_pipe_clones); 1094 audit_pipe_eh_tag = EVENTHANDLER_REGISTER(dev_clone, 1095 audit_pipe_clone, 0, 1000); 1096 if (audit_pipe_eh_tag == NULL) 1097 panic("audit_pipe_init: EVENTHANDLER_REGISTER"); 1098} 1099 1100SYSINIT(audit_pipe_init, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, audit_pipe_init, 1101 NULL); |