PERFORCE change 135579 for review
Christian S.J. Peron
csjp at FreeBSD.org
Sun Feb 17 09:43:31 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=135579
Change 135579 by csjp at csjp_xor on 2008/02/17 17:42:30
Lets try that again, but this time on the correct branch.
Affected files ...
.. //depot/projects/trustedbsd/bsmtrace/Makefile#2 edit
.. //depot/projects/trustedbsd/bsmtrace/README#2 edit
.. //depot/projects/trustedbsd/bsmtrace/bsm.c#2 edit
.. //depot/projects/trustedbsd/bsmtrace/bsmtrace.c#2 edit
.. //depot/projects/trustedbsd/bsmtrace/bsmtrace.conf#2 edit
.. //depot/projects/trustedbsd/bsmtrace/bsmtrace.conf.5#2 edit
.. //depot/projects/trustedbsd/bsmtrace/bsmtrace.ebnf#2 edit
.. //depot/projects/trustedbsd/bsmtrace/bsmtrace.h#2 edit
.. //depot/projects/trustedbsd/bsmtrace/conf.c#2 edit
.. //depot/projects/trustedbsd/bsmtrace/deuce.h#2 edit
.. //depot/projects/trustedbsd/bsmtrace/grammar.y#2 edit
.. //depot/projects/trustedbsd/bsmtrace/includes.h#2 edit
.. //depot/projects/trustedbsd/bsmtrace/log.c#2 edit
.. //depot/projects/trustedbsd/bsmtrace/pipe.c#1 add
.. //depot/projects/trustedbsd/bsmtrace/pipe.h#1 add
.. //depot/projects/trustedbsd/bsmtrace/token.l#2 edit
.. //depot/projects/trustedbsd/bsmtrace/trigger.c#2 edit
Differences ...
==== //depot/projects/trustedbsd/bsmtrace/Makefile#2 (text+ko) ====
@@ -1,18 +1,18 @@
-# $Id: Makefile,v 1.7 2007/04/13 14:45:12 csjp Exp $
+# $Id: Makefile,v 1.8 2007/07/13 00:03:50 csjp Exp $
CC = gcc
CFLAGS = -Wall -g
TARGETS = bsmtrace
-OBJ = bsm.o bsmtrace.o conf.o y.tab.o lex.yy.o log.o trigger.o
+OBJ = bsm.o bsmtrace.o conf.o y.tab.o lex.yy.o log.o pipe.o trigger.o
PREFIX = /usr/local
LIBS = -lbsm
-.ifdef PCRE
-CFLAGS += -I /usr/local/include
-CFLAGS += -L /usr/local/lib
-CFLAGS += -D PCRE
-LIBS += -lpcre
-.endif
+#.ifdef PCRE
+#CFLAGS += -I /usr/local/include
+#CFLAGS += -L /usr/local/lib
+#CFLAGS += -D PCRE
+#LIBS += -lpcre
+#.endif
all: $(TARGETS)
==== //depot/projects/trustedbsd/bsmtrace/README#2 (text+ko) ====
==== //depot/projects/trustedbsd/bsmtrace/bsm.c#2 (text+ko) ====
@@ -3,7 +3,7 @@
* Copyright (c) 2007 Christian S.J. Peron
* All rights reserved.
*
- * $Id: bsm.c,v 1.44 2007/04/15 01:23:49 csjp Exp $
+ * $Id: bsm.c,v 1.45 2007/10/09 02:24:30 csjp Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -122,8 +122,7 @@
* on the object we are interested in, but a write on some anonymous
* object has occured, should we still raise an alert?
*/
- if (bd->br_path == NULL)
- return (0);
+
/*
* Check to see if the user has supplied any objects. If not, then this
* is a member match.
@@ -132,6 +131,12 @@
if (ap->a_cnt == 0)
return (1);
/*
+ * We are interested in particular objects, but the audit record has
+ * not supplied any. We will treat this as a fail to match.
+ */
+ if (bd->br_path == NULL)
+ return (0);
+ /*
* Otherwise, the record contains a pathname which may be represented as
* a static string, or as a pcre.
*/
@@ -185,7 +190,7 @@
* sequence, use stderr. This really needs to be fixed to look at what
* if anything is specified in the global logging options.
*/
- if (TAILQ_EMPTY(&bs->bs_log_channel)) {
+ if (TAILQ_EMPTY(&bs->bs_log_channel) && opts.Fflag != 0) {
log_bsm_stderr(NULL, bs, bd);
return;
}
@@ -361,12 +366,38 @@
#endif
}
+/*
+ * Implement a function which produces random values with an interesting
+ * property. This function will produce a random value, where the probability
+ * of this value being between 0 and size is specified by prob.
+ *
+ * Let v be > 0 and < 1 (random value)
+ * Let P (probability) be > 0 and < 1
+ *
+ * Rv = v * (range / P);
+ *
+ */
+static float
+bsm_rand_bias(float size, float prob)
+{
+ unsigned int val;
+ float r;
+
+ val = arc4random();
+ r = (float)val;
+ while (r > 1)
+ r = r / 10;
+ return (r * (size / prob));
+}
+
static struct bsm_sequence *
bsm_sequence_clone(struct bsm_sequence *bs, u_int subj,
struct bsm_record_data *bd)
{
struct bsm_sequence *bs_new;
struct bsm_state *bm;
+ float size, prob;
+ int rnd;
bs_new = bsm_dyn_sequence_find(bs, bd, subj);
if (bs_new != NULL) {
@@ -403,6 +434,18 @@
bm->bm_raw = bsm_copy_record_data(bd);
bm->bm_raw_len = bd->br_raw_len;
bs_new->bs_cur_state = TAILQ_NEXT(bm, bm_glue);
+ /*
+ * Handle the randomization of the timeout window here.
+ */
+ if (bs_new->bs_seq_time_wnd != 0) {
+ size = bs_new->bs_seq_time_wnd;
+ if (bs_new->bs_seq_time_wnd_prob > 0)
+ prob = (float)bs_new->bs_seq_time_wnd_prob / 100;
+ else
+ prob = (float)(65 / 100);
+ rnd = bsm_rand_bias(size, prob);
+ bs_new->bs_timeout = bs_new->bs_timeout + rnd;
+ }
return (bs_new);
}
@@ -490,7 +533,7 @@
bsm_loop(char *atrail)
{
struct bsm_record_data bd;
- int reclen, bytesread;
+ int reclen, bytesread, recsread;
u_char *bsm_rec;
tokenstr_t tok;
FILE *fp;
@@ -501,10 +544,22 @@
fp = fopen(opts.aflag, "r");
if (fp == NULL)
bsmtrace_error(1, "%s: %s", opts.aflag, strerror(errno));
+ if (strcmp(opts.aflag, DEFAULT_AUDIT_TRAIL) == 0)
+ audit_pipe_fd = fileno(fp);
+ dprintf("opened '%s' for audit monitoring\n", opts.aflag);
/*
* Process the BSM record, one token at a time.
*/
+ recsread = 0;
while ((reclen = au_read_rec(fp, &bsm_rec)) != -1) {
+ /*
+ * If we are reading data from the audit pipe, we need check
+ * how many records, if any have been dropped by the kernel.
+ * If any record loss has been identified, pipe_analyze_loss()
+ * should increase the internal audit pipe queue length.
+ */
+ if (audit_pipe_fd > 0 && (recsread % 50) == 0)
+ pipe_analyze_loss(audit_pipe_fd);
bzero(&bd, sizeof(bd));
bd.br_raw = bsm_rec;
bd.br_raw_len = reclen;
@@ -581,6 +636,7 @@
}
bsm_sequence_scan(&bd);
free(bsm_rec);
+ recsread++;
}
- fclose(fp);
+ (void) fclose(fp);
}
==== //depot/projects/trustedbsd/bsmtrace/bsmtrace.c#2 (text+ko) ====
@@ -3,7 +3,7 @@
* Copyright (c) 2007 Christian S.J. Peron
* All rights reserved.
*
- * $Id: bsmtrace.c,v 1.18 2007/04/13 14:45:12 csjp Exp $
+ * $Id: bsmtrace.c,v 1.19 2007/10/09 02:22:15 csjp Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -48,7 +48,7 @@
(void) sprintf(pidbuf, "%d", getpid());
if (write(fd, pidbuf, strlen(pidbuf)) < 0)
bsmtrace_error(1, "write pid file faled");
- close(fd);
+ (void) close(fd);
}
/*
@@ -68,7 +68,7 @@
else
pri = LOG_WARNING;
va_start(ap, fmt);
- vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap);
+ (void) vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap);
va_end(ap);
syslog(pri, "%s: %s", flag != 0 ? "fatal" : "warning", fmtbuf);
/* if we are not yet a daemon, we also write the error message
@@ -87,6 +87,7 @@
void
bsmtrace_exit(int x)
{
+
exit(x);
}
@@ -99,10 +100,22 @@
if (!opts.dflag)
return;
va_start(ap, fmt);
- memset(buf, 0, sizeof(buf));
- vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
+ (void) memset(buf, 0, sizeof(buf));
+ (void) vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
va_end(ap);
- fprintf(stderr, "debug: %s", buf);
+ (void) fprintf(stderr, "debug: %s", buf);
+ (void) fflush(stderr);
+}
+
+void
+bsmtrace_handle_sigint(int sig)
+{
+
+ if (audit_pipe_fd != 0) {
+ (void) fputs("\n", stderr);
+ pipe_report_stats(audit_pipe_fd);
+ }
+ bsmtrace_exit(1);
}
void
@@ -115,13 +128,30 @@
openlog("bsmtrace", LOG_NDELAY | LOG_PID, LOG_AUTH | LOG_ALERT);
}
+static void
+bsmtrace_seed(void)
+{
+ unsigned long seed;
+ int fd;
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd < 0)
+ bsmtrace_error(1, "open random device failed");
+ if (read(fd, &seed, sizeof(seed)) != sizeof(seed))
+ bsmtrace_error(1, "read random device failed");
+ srandom(seed);
+ (void) close(fd);
+}
+
int
main(int argc, char *argv[])
{
int ret, fd;
char ch;
- signal(SIGCHLD, SIG_IGN); /* Ignore dying children */
+ bsmtrace_seed();
+ (void) signal(SIGCHLD, SIG_IGN); /* Ignore dying children */
+ (void) signal(SIGINT, bsmtrace_handle_sigint);
set_default_settings(&opts);
while ((ch = getopt(argc, argv, "Fa:bdf:hp:v")) != -1) {
switch (ch) {
@@ -172,7 +202,9 @@
(void) dup2(fd, STDERR_FILENO);
if (fd > 2)
(void) close(fd);
- setsid();
+ if (setsid() < 0)
+ bsmtrace_error(1, "setsid failed: %s",
+ strerror(errno));
bsmtrace_write_pidfile(opts.pflag);
daemonized = 1;
}
==== //depot/projects/trustedbsd/bsmtrace/bsmtrace.conf#2 (text+ko) ====
@@ -67,9 +67,13 @@
#
############################################################
+#
+#
+# XXX add a sequence which detects system accounts executing code
+#
+#
sequence firewall.change.attempt {
subject not $fwadmins;
- log <logchannel> { $bsm; };
state {
event $execution;
object $fwtools;
@@ -79,7 +83,6 @@
sequence non.trusted.exec {
subject any;
- log <logchannel> { $bsm; };
state {
event $execution;
object not $trusteddirs;
@@ -90,7 +93,6 @@
sequence mktemp.race {
subject any;
- log <logchannel> { $bsm; };
state {
event <auditevent> { AUE_SYMLINK; };
object $opendirs;
@@ -104,7 +106,7 @@
state {
event $login;
status failure;
- multiplier 5;
+ multiplier 2;
};
state {
event $login;
@@ -114,7 +116,6 @@
sequence httpd.exec {
subject <auid> { nobody; };
- log <logchannel> { $bsm; };
state {
event <auditevent> { AUE_SOCKET; };
status success;
@@ -131,7 +132,7 @@
sequence named.exec {
subject <auid> { bind; };
- log <logchannel> { $bsm; };
+ scope process;
state {
event <auditevent> { AUE_SOCKET; };
status success;
@@ -146,24 +147,47 @@
};
};
+sequence failed.file.write {
+ subject <auid> { csjp; };
+ state {
+ event <auditclass> { fw; };
+ status failure;
+ };
+};
+
#
-# Test for PCRE's
+# This is a comment
#
-#sequence passwd.access {
-# subject any;
-# log <logchannel> { $bsm; };
-# state {
-# event <auditclass> { fr; };
-# status any;
-# object <pcre> { ^/etc/pass[Ww][Dd]; };
-# };
-#};
-#sequence etc.access {
-# subject any;
-# log <logchannel> { $bsm; };
-# state {
-# event <auditclass> { fr; };
-# status any;
-# object <pcre> { ^/[Ee][Tt][Cc]/*; };
-# };
-#};
+sequence five.config.file.read {
+ subject <auid> { csjp; };
+ serial 2343445445;
+ timeout 60 seconds;
+ scope global;
+ priority 100;
+ state {
+ event <auditclass> { fr; };
+ status any;
+ object <path> { /etc; };
+ trigger "/usr/bin/logger config file read";
+ multiplier 5;
+ };
+};
+
+sequence passwd.access {
+ subject any;
+ state {
+ event <auditclass> { fr; };
+ status any;
+ object <pcre> { /etc/pass[Ww][Dd]; };
+ multiplier 5;
+ };
+};
+
+sequence etc.access {
+ subject any;
+ state {
+ event <auditclass> { fr; };
+ status any;
+ object <pcre> { /[Ee][Tt][Cc]/*; };
+ };
+};
==== //depot/projects/trustedbsd/bsmtrace/bsmtrace.conf.5#2 (text+ko) ====
@@ -90,6 +90,8 @@
<sequence> ::= "sequence" <sequence_name> "{"
"subject" ["not"] ( <set> | (<set_name> | "any")) ";"
["timeout" <value> <time_scale> ";"]
+ ["timeout-window" <value> <time_scale> ";"]
+ ["timeout-probability" <value> ";"]
["priority" <value> ";"]
["log" (<set> | <set_name>) ";"]
["serial" <value> ";"]
==== //depot/projects/trustedbsd/bsmtrace/bsmtrace.ebnf#2 (text+ko) ====
@@ -55,6 +55,8 @@
<sequence> ::= "sequence" <sequence_name> "{"
"subject" ["not"] ( <set> | (<set_name> | "any")) ";"
["timeout" <value> <time_scale> ";"]
+ ["timeout-window" <value> <time_scale> ";"]
+ ["timeout-probability" <value> ";"]
["priority" <value> ";"]
["log" (<set> | <set_name>) ";"]
["serial" <value> ";"]
==== //depot/projects/trustedbsd/bsmtrace/bsmtrace.h#2 (text+ko) ====
@@ -28,7 +28,7 @@
#ifndef BSM_TRACE_H_
#define BSM_TRACE_H_
-#define BSMTRACE_VERSION "BSMTRACE 1.0.0-BETA"
+#define BSMTRACE_VERSION "BSMTRACE 1.2.0-HEAD"
struct g_conf {
char *aflag;
int bflag;
@@ -39,6 +39,7 @@
};
struct g_conf opts;
+int audit_pipe_fd; /* XXX not happy about this global */
void bsmtrace_error(int, char *, ...);
void bsmtrace_exit(int);
==== //depot/projects/trustedbsd/bsmtrace/conf.c#2 (text+ko) ====
@@ -97,7 +97,7 @@
yyin = f;
TAILQ_INIT(&bsm_set_head);
yyparse();
- fclose(f);
+ (void) fclose(f);
}
/*
==== //depot/projects/trustedbsd/bsmtrace/deuce.h#2 (text+ko) ====
@@ -131,6 +131,8 @@
int bs_seq_scope;
pid_t bs_seq_scope_data;
int bs_seq_serial;
+ int bs_seq_time_wnd;
+ int bs_seq_time_wnd_prob;
};
struct bsm_record_data {
==== //depot/projects/trustedbsd/bsmtrace/grammar.y#2 (text+ko) ====
@@ -51,9 +51,10 @@
%token STATUS MULTIPLIER OBRACE EBRACE SEMICOLON COMMA SUBJECT
%token STRING ANY SUCCESS FAILURE INTEGER TIMEOUT NOT HOURS MINUTES DAYS
%token PRIORITY WEEKS SECONDS NONE QUOTE OPBRACKET EPBRACKET LOGCHAN
-%token DIRECTORY LOG SCOPE SERIAL
+%token DIRECTORY LOG SCOPE SERIAL TIMEOUTWND TIMEOUTPROB
%type <num> status_spec SUCCESS FAILURE INTEGER multiplier_spec timeout_spec
-%type <num> serial_spec negate_spec priority_spec scope_spec
+%type <num> serial_spec negate_spec priority_spec scope_spec timeout_wnd_spec
+%type <num> timeout_prob_spec time_spec
%type <str> STRING
%type <array> set_list set_list_ent
%type <bsm_set> anon_set
@@ -207,33 +208,54 @@
}
;
-timeout_spec:
- TIMEOUT INTEGER SECONDS SEMICOLON
+timeout_prob_spec:
+ TIMEOUTPROB INTEGER SEMICOLON
+ {
+ $$ = $2;
+ }
+ ;
+
+timeout_wnd_spec:
+ TIMEOUTWND time_spec SEMICOLON
{
$$ = $2;
}
- | TIMEOUT INTEGER HOURS SEMICOLON
+ ;
+
+time_spec:
+ INTEGER SECONDS
+ {
+ $$ = $1;
+ }
+ | INTEGER HOURS
{
- $$ = $2 * 3600;
+ $$ = $1 * 3600;
}
- | TIMEOUT INTEGER MINUTES SEMICOLON
+ | INTEGER MINUTES
{
- $$ = $2 * 60;
+ $$ = $1 * 60;
}
- | TIMEOUT INTEGER DAYS SEMICOLON
+ | INTEGER DAYS
{
- $$ = $2 * 3600 * 24;
+ $$ = $1 * 3600 * 24;
}
- | TIMEOUT INTEGER WEEKS SEMICOLON
+ | INTEGER WEEKS
{
- $$ = $2 * 3600 * 24 * 7;
+ $$ = $1 * 3600 * 24 * 7;
}
- | TIMEOUT NONE SEMICOLON
+ | NONE
{
$$ = 0;
}
;
+timeout_spec:
+ TIMEOUT time_spec SEMICOLON
+ {
+ $$ = $2;
+ }
+ ;
+
sequence_def:
SEQUENCE
{
@@ -337,8 +359,19 @@
}
| sequence_options serial_spec
{
+ assert(bs_state != NULL);
bs_state->bs_seq_serial = $2;
}
+ | sequence_options timeout_wnd_spec
+ {
+ assert(bs_state != NULL);
+ bs_state->bs_seq_time_wnd = $2;
+ }
+ | sequence_options timeout_prob_spec
+ {
+ assert(bs_state != NULL);
+ bs_state->bs_seq_time_wnd_prob = $2;
+ }
;
type_spec:
==== //depot/projects/trustedbsd/bsmtrace/includes.h#2 (text+ko) ====
@@ -3,7 +3,7 @@
* Copyright (c) 2007 Christian S.J. Peron
* All rights reserved.
*
- * $Id: includes.h,v 1.4 2007/04/13 14:45:12 csjp Exp $
+ * $Id: includes.h,v 1.5 2007/07/13 00:03:50 csjp Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +33,11 @@
#endif
#include <sys/stat.h>
#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/msg.h>
+#include <sys/uio.h>
+#include <sys/un.h>
#include <stdio.h>
#include <string.h>
@@ -50,7 +55,9 @@
#include <bsm/libbsm.h>
#include <bsm/audit.h>
+#ifndef __APPLE__
#include <security/audit/audit_ioctl.h>
+#endif
#ifdef PCRE
#include <pcre.h>
#endif
@@ -64,4 +71,5 @@
#include "conf.h"
#include "bsm.h"
#include "log.h"
+#include "pipe.h"
#include "trigger.h"
==== //depot/projects/trustedbsd/bsmtrace/log.c#2 (text+ko) ====
@@ -104,18 +104,18 @@
struct bsm_state *bm;
(void) snprintf(dir, MAXPATHLEN,
- "%s/%s", lc->log_data.bsm_log_dir,
- bs->bs_label);
+ "%s/%s", lc->log_data.bsm_log_dir, bs->bs_label);
error = stat(dir, &sb);
if (error < 0 && errno == ENOENT) {
if (mkdir(dir, S_IRWXU) < 0)
bsmtrace_error(1, "mkdir failed");
} else if (error < 0)
bsmtrace_error(1, "stat failed");
- (void) sprintf(path, "%s/%d.%d", dir, br->br_sec, br->br_usec);
+ (void) sprintf(path, "%s/%d.%d.%lu",
+ dir, br->br_sec, br->br_usec, random());
fd = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0)
- bsmtrace_error(1, "open failed");
+ bsmtrace_error(1, "open: %s: %s", path, strerror(errno));
/*
* The logic here becomes a bit complex. We need to check to see if
* this is a single state sequence, and if it is, log the BSM record
@@ -126,13 +126,13 @@
if ((bs->bs_seq_flags & BSM_SEQUENCE_PARENT) != 0) {
if (write(fd, br->br_raw, br->br_raw_len) < 0)
bsmtrace_error(1, "write failed");
- close(fd);
+ (void) close(fd);
return (0);
}
TAILQ_FOREACH(bm, &bs->bs_mhead, bm_glue)
if (write(fd, bm->bm_raw, bm->bm_raw_len) < 0)
bsmtrace_error(1, "write failed");
- close(fd);
+ (void) close(fd);
return (0);
}
==== //depot/projects/trustedbsd/bsmtrace/token.l#2 (text+ko) ====
@@ -64,6 +64,8 @@
subject return (SUBJECT);
success return (SUCCESS);
timeout return (TIMEOUT);
+timeout-window return (TIMEOUTWND);
+timeout-prob return (TIMEOUTPROB);
trigger return (TRIGGER);
weeks return (WEEKS);
{integer} {
==== //depot/projects/trustedbsd/bsmtrace/trigger.c#2 (text+ko) ====
@@ -72,15 +72,15 @@
switch (expptr->val) {
case EXP_USER:
if ((pw = getpwuid(bd->br_auid)) == NULL)
- strlcpy(token, "non-attributable",
+ (void) strlcpy(token, "non-attributable",
sizeof(token));
else
- strlcpy(token, pw->pw_name,
+ (void) strlcpy(token, pw->pw_name,
sizeof(token));
break;
case EXP_OBJECT:
if (bd->br_path != NULL)
- strlcpy(token, bd->br_path,
+ (void) strlcpy(token, bd->br_path,
sizeof(token));
else {
free(ret);
@@ -90,7 +90,7 @@
default:
assert(0);
}
- strlcat(ret, token, allocated);
+ (void) strlcat(ret, token, allocated);
p1 = ret + strlen(ret);
} else
*(p1++) = *(p0++);
More information about the p4-projects
mailing list