From owner-p4-projects@FreeBSD.ORG Sun May 11 17:55:49 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 272521065674; Sun, 11 May 2008 17:55:49 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C515F106564A for ; Sun, 11 May 2008 17:55:48 +0000 (UTC) (envelope-from snagg@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B466E8FC18 for ; Sun, 11 May 2008 17:55:48 +0000 (UTC) (envelope-from snagg@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m4BHtmk7001200 for ; Sun, 11 May 2008 17:55:48 GMT (envelope-from snagg@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m4BHtmP6001198 for perforce@freebsd.org; Sun, 11 May 2008 17:55:48 GMT (envelope-from snagg@FreeBSD.org) Date: Sun, 11 May 2008 17:55:48 GMT Message-Id: <200805111755.m4BHtmP6001198@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to snagg@FreeBSD.org using -f From: Vincenzo Iozzo To: Perforce Change Reviews Cc: Subject: PERFORCE change 141469 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 May 2008 17:55:49 -0000 http://perforce.freebsd.org/chv.cgi?CH=141469 Change 141469 by snagg@snagg_macosx on 2008/05/11 17:55:03 Added the preselection functions for dealing with per-event auditing. In particular a new struct audit_pipe_preselection was created with some more fields in order to have the capability of storing events and pid information. audit_pipe_preselection_events_* are the new functions introduced. I still have to modify the KPI and other internal behavior for example the ioctl function in order to have it tested. Reviewed by: attilio, rwatson Discussed with: attilio, rwatson Affected files ... .. //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_ioctl.h#2 edit .. //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_pipe.c#2 edit Differences ... ==== //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_ioctl.h#2 (text) ==== @@ -48,7 +48,7 @@ */ #define AUDITPIPE_PRESELECT_MODE_TRAIL 1 /* Global audit trail. */ #define AUDITPIPE_PRESELECT_MODE_LOCAL 2 /* Local audit trail. */ - +#define AUDITPIPE_PRESELECT_MODE_SYSCALL 3 /* Events based audit trail */ /* * Ioctls to read and control the behavior of individual audit pipe devices. */ ==== //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_pipe.c#2 (text) ==== @@ -68,6 +68,7 @@ "Audit pipe entries and buffers"); static MALLOC_DEFINE(M_AUDIT_PIPE_PRESELECT, "audit_pipe_presel", "Audit pipe preselection structure"); +static MALLOC_DEFINE(M_AUDIT_PIPE_PRESELECT_EVENT, "audit_pipe_preselection", "Audit pipe preselection events structure"); /* * Audit pipe buffer parameters. @@ -75,6 +76,7 @@ #define AUDIT_PIPE_QLIMIT_DEFAULT (128) #define AUDIT_PIPE_QLIMIT_MIN (0) #define AUDIT_PIPE_QLIMIT_MAX (1024) +#define AUDIT_NEVENTS (256) /* * Description of an entry in an audit_pipe. @@ -102,6 +104,21 @@ TAILQ_ENTRY(audit_pipe_preselect) app_list; }; +struct audit_pipe_preselect_event { + int app_event; + int app_flag; +}; + +struct audit_pipe_preselect +{ + au_id_t app_auid; + au_mask_t app_mask; + pid_t app_pid; + struct audit_pipe_preselect_event *app_auevents; + int app_event_len; + TAILQ_ENTRY(audit_pipe_preselect) app_list; +}; + /* * Description of an individual audit_pipe. Consists largely of a bounded * length queue. @@ -217,8 +234,37 @@ } /* + * Find an audit pipe preselection specification for an event and flag, if any. + */ +static struct audit_pipe_preselect * +audit_pipe_preselect_find_event(struct audit_pipe *ap, int app_event, pid_t app_pid, int event_flag) +{ + struct audit_pipe_preselect *app; + int i; + + mtx_assert(&audit_pipe_mtx, MA_OWNED); + + TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) { + if(app->app_pid == app_pid) { + if(event == -1) + return (app); + for(i = 0; i < app->app_event_len; i++) + if((app->app_auevents + i)->app_event == app_event) + if(event_flag == -1) + return (app) + else if ((app->app_auevents + i)->app_flag == event_flag) + return (app); + + return (app); + } + } + + return (NULL); +} + +/* * Find an audit pipe preselection specification for an auid, if any. - */ + */ static struct audit_pipe_preselect * audit_pipe_preselect_find(struct audit_pipe *ap, au_id_t auid) { @@ -255,7 +301,57 @@ } /* - * Set the per-pipe mask for a specific auid. Add a new entry if needed; + * Add a new entry for a specifc event. Add a new entry if needed; + * otherwise, update the current entry. + */ +static void +audit_pipe_preselect_set_events(struct audit_pipe *ap, pid_t app_pid, struct audit_pipe_preselect_event *events, int num) +{ + struct audit_pipe_preselect *app, *app_new; + int i; + int found; + + /* + * Pessimistically assume that the entry for this pid doesn't + * exist, and allocate. We will free it if it is unneeded. + */ + app_new = malloc(sizeof(*app_new), M_AUDIT_PIPE_PRESELECT, M_WAITOK); + app_new->app_events= malloc(sizeof(struct audit_pipe_preselect_event) * AUDIT_NEVENTS, M_AUDIT_PIPE_PRESELECT_EVENT, M_WAITOK); + mtx_lock(&audit_pipe_mtx); + + /* + * First search for the entry by its pid + */ + app = audit_pipe_preselect_find_event(ap, -1, pid, -1); + found = (app != NULL) ? 1: 0; + if(found) { + KASSERT(num <= app->app_event_len, "Number of events is out of range"); + for (i = 0; i < num; i++) { + (app->app_auevents + i)->app_event = (events + i)->app_event; + (app->app_auevents + i)->app-flag = (events + i)->app-flag; + } + } else { + app = app_new; + app_new = NULL; + app->app_pid = app_pid; + app->app_event_len = AUDIT_NEVENTS; + for (i = 0; i < num; i++) { + (app->app_auevents + i)->app_event = (events + i)->app_event; + (app->app_auevents + i)->app-flag = (events + i)->app-flag; + } + TAILQ_INSERT_TAIL(&ap->ap_preselect_list, app, app_list); + } + + + mtx_unlock(&audit_pipe_mtx); + if (app_new != NULL) { + free(app_new, M_AUDIT_PIPE_PRESELECT); + free(app_new->app_auevents, M_AUDIT_PIPE_PRESELECT_ENTRY); + } +} + +/* + * Set the per-pipe mask for a specific event. Add a new entry if needed; * otherwise, update the current entry. */ static void @@ -283,6 +379,59 @@ } /* + * Delete a per-event entry on an audit pipe. + */ +static int +audit_pipe_preselect_delete_event(struct audit_pipe *ap, int app_event, pid_t pid, int app_flag) +{ + struct audit_pipe_preselect *app; + int i; + + mtx_lock(&audit_pipe_mtx); + app = audit_pipe_preselect_find(ap, event, pid, -1); + if (app != NULL) { + for( i = 0; i < app->app_event_len; i++) { + if((app->app_auevents + i)->app_event == app_event && (app->app_auevents + i)->app_flag == app_flag) { + free((app->app_auevents + i), M_AUDIT_PIPE_EVENT); + break; + } + } + mtx_unlock(&audit_pipe_mtx); + return(0); + } + mtx_unlock(&audit_pipe_mtx); + + return (ENOENT); + +} + +/* + * Delete a per-pid entry on an audit pipe wiping the whole entry. + */ +static int +audit_pipe_preselect_delete_pid(struct audit_pipe *ap, pid_t pid) +{ + struct audit_pipe_preselect *app; + int i; + + mtx_lock(&audit_pipe_mtx); + app = audit_pipe_preselect_find(ap, -1, pid, -1); + if (app != NULL) { + TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); + mtx_unlock(&audit_pipe_mtx); + } + + mtx_unlock(&audit_pipe_mtx); + if (app != NULL) { + for(i = 0; i < app->app_event_len; i++) + free((app->app_auevents + i), M_AUDIT_PIPE_PRESELECT_EVENT); + free(app, M_AUDIT_PIPE_PRESELECT); + return (0); + } + return (ENOENT); +} + +/* * Delete a per-auid mask on an audit pipe. */ static int @@ -305,6 +454,36 @@ } /* + * Delete all per-events entry on an audit pipe. + */ +static void +audit_pipe_preselect_events_flush_locked(struct audit_pipe *ap) +{ + struct audit_pipe_preselect *app; + int i; + + mtx_assert(&audit_pipe_mtx, MA_OWNED); + + while ((app = TAILQ_FIRST(&ap->ap_preselect_list)) != NULL) { + TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); + if (app != NULL) { + for(i = 0; i < app->app_event_len; i++) + free((app->app_auevents + i), M_AUDIT_PIPE_PRESELECT_EVENT); + free(app, M_AUDIT_PIPE_PRESELECT); + } + } +} + +static void +audit_pipe_preselect_events_flush(struct audit_pipe *ap) +{ + + mtx_lock(&audit_pipe_mtx); + audit_pipe_preselect_events_flush_locked(ap); + mtx_unlock(&audit_pipe_mtx); +} + +/* * Delete all per-auid masks on an audit pipe. */ static void @@ -341,7 +520,7 @@ */ static int audit_pipe_preselect_check(struct audit_pipe *ap, au_id_t auid, - au_event_t event, au_class_t class, int sorf, int trail_preselect) + au_event_t event, au_class_t class, int sorf, int trail_preselect, pid_t pid) { struct audit_pipe_preselect *app; @@ -363,7 +542,12 @@ } else return (au_preselect(event, class, &app->app_mask, sorf)); - + + case AUDITPIPE_PRESELECT_MODE_SYSCALL: + app = audit_pipe_preselect_find_event(ap, event, pid, sorf); + if(app != NULL) + return (1); + default: panic("audit_pipe_preselect_check: mode %d", ap->ap_preselect_mode); @@ -374,7 +558,8 @@ /* * Determine whether there exists a pipe interested in a record with specific - * properties. + * properties. MISS the PID in the declaration, to be done later, just don't know to change the whole kernel:P + * */ int audit_pipe_preselect(au_id_t auid, au_event_t event, au_class_t class, @@ -385,7 +570,7 @@ mtx_lock(&audit_pipe_mtx); TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { if (audit_pipe_preselect_check(ap, auid, event, class, sorf, - trail_preselect)) { + trail_preselect, -1)) { mtx_unlock(&audit_pipe_mtx); return (1); } @@ -449,7 +634,7 @@ */ void audit_pipe_submit(au_id_t auid, au_event_t event, au_class_t class, int sorf, - int trail_select, void *record, u_int record_len) + int trail_select, void *record, u_int record_len, pid_t pid) { struct audit_pipe *ap; @@ -462,7 +647,7 @@ mtx_lock(&audit_pipe_mtx); TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { if (audit_pipe_preselect_check(ap, auid, event, class, sorf, - trail_select)) + trail_select, pid)) audit_pipe_append(ap, record, record_len); } audit_pipe_records++;