Updated patch.
Only changes from the last one is that:
AUDIT_SE_SENS became AUDIT_SE_SEN
and
AUDIT_SE_CAT became AUDIT_SE_CLR
These reflect Darrel's more knowledgeable naming of these SELinux
context label components.
Still, this is not going to be acceptable to mainline, Steve, as it doesn't
preserve backward compatibility. But it does work in allowing one to test
the SELinux context label filtering provided in the kernel space sibling
patch.
:-Dustin
diff -urpN audit-1.1.3/lib/fieldtab.h audit-1.1.3.dustin/lib/fieldtab.h
--- audit-1.1.3/lib/fieldtab.h 2006-01-05 14:30:40.000000000 -0600
+++ audit-1.1.3.dustin/lib/fieldtab.h 2006-02-16 23:20:03.000000000 -0600
@@ -34,6 +34,11 @@ _S(AUDIT_LOGINUID, "loginuid" )
_S(AUDIT_PERS, "pers" )
_S(AUDIT_ARCH, "arch" )
_S(AUDIT_MSGTYPE, "msgtype" )
+_S(AUDIT_SE_USER, "se_user" )
+_S(AUDIT_SE_ROLE, "se_role" )
+_S(AUDIT_SE_TYPE, "se_type" )
+_S(AUDIT_SE_SEN, "se_sen" )
+_S(AUDIT_SE_CLR, "se_clr" )
_S(AUDIT_DEVMAJOR, "devmajor" )
_S(AUDIT_DEVMINOR, "devminor" )
diff -urpN audit-1.1.3/lib/libaudit.c audit-1.1.3.dustin/lib/libaudit.c
--- audit-1.1.3/lib/libaudit.c 2006-02-02 11:02:12.000000000 -0600
+++ audit-1.1.3.dustin/lib/libaudit.c 2006-02-16 23:19:27.000000000 -0600
@@ -48,6 +48,7 @@ int audit_syscalladded = 0;
unsigned int audit_elf = 0U;
static int name_to_uid(const char *name, uid_t *uid);
static int name_to_gid(const char *name, gid_t *gid);
+static void print_audit_rule_data(struct audit_rule_data *rd);
int audit_request_status(int fd)
@@ -580,7 +581,7 @@ int audit_log_if_enabled(int fd, int typ
return rc;
}
-int audit_rule_syscall(struct audit_rule *rule, int scall)
+int audit_rule_syscall(struct audit_rule_data *rule, int scall)
{
int word = AUDIT_WORD(scall);
int bit = AUDIT_BIT(scall);
@@ -591,7 +592,7 @@ int audit_rule_syscall(struct audit_rule
return 0;
}
-int audit_rule_syscallbyname(struct audit_rule *rule,
+int audit_rule_syscallbyname(struct audit_rule_data *rule,
const char *scall)
{
int nr, i;
@@ -602,7 +603,10 @@ int audit_rule_syscallbyname(struct audi
rule->mask[i] = ~0;
return 0;
}
- machine = audit_elf_to_machine(audit_elf);
+ if (!audit_elf)
+ machine = audit_detect_machine();
+ else
+ machine = audit_elf_to_machine(audit_elf);
if (machine < 0)
return -2;
nr = audit_name_to_syscall(scall, machine);
@@ -626,44 +630,58 @@ int audit_rule_field(struct audit_rule *
return 0;
}
-int audit_rule_fieldpair(struct audit_rule *rule, const char *pair, int flags)
+int audit_get_operator(const char *pair, char **v)
+{
+ /* look for 2-char operators first
+ then look for 1-char operators afterwards
+ when found, null out the bytes under the operators to split
+ and set value pointer just past operator bytes
+ */
+ if ( (*v = strstr(pair, "!=")) ) {
+ *(*v)++ = '\0';
+ *(*v)++ = '\0';
+ return AUDIT_NOT_EQUAL;
+ }
+ if ( (*v = strstr(pair, ">=")) ) {
+ *(*v)++ = '\0';
+ *(*v)++ = '\0';
+ return AUDIT_GREATER_THAN_OR_EQUAL;
+ }
+ if ( (*v = strstr(pair, "<=")) ) {
+ *(*v)++ = '\0';
+ *(*v)++ = '\0';
+ return AUDIT_LESS_THAN_OR_EQUAL;
+ }
+ if ( (*v = strstr(pair, "=")) ) {
+ *(*v)++ = '\0';
+ return AUDIT_EQUAL;
+ }
+ if ( (*v = strstr(pair, ">")) ) {
+ *(*v)++ = '\0';
+ return AUDIT_GREATER_THAN;
+ }
+ if ( (*v = strstr(pair, "<")) ) {
+ *(*v)++ = '\0';
+ return AUDIT_LESS_THAN;
+ }
+ return 0;
+}
+
+int audit_rule_fieldpair(struct audit_rule_data *rule,
+ const char *pair, int flags)
{
const char *f = pair;
char *v;
int op;
int field;
int vlen;
+ int total_size;
+ int offset;
if (f == NULL)
return -1;
- /* look for 2-char operators first
- then look for 1-char operators afterwards
- when found, null out the bytes under the operators to split
- and set value pointer just past operator bytes
- */
- if ( (v = strstr(pair, "!=")) ) {
- *v++ = '\0';
- *v++ = '\0';
- op = AUDIT_NOT_EQUAL;
- } else if ( (v = strstr(pair, ">=")) ) {
- *v++ = '\0';
- *v++ = '\0';
- op = AUDIT_GREATER_THAN_OR_EQUAL;
- } else if ( (v = strstr(pair, "<=")) ) {
- *v++ = '\0';
- *v++ = '\0';
- op = AUDIT_LESS_THAN_OR_EQUAL;
- } else if ( (v = strstr(pair, "=")) ) {
- *v++ = '\0';
- op = AUDIT_EQUAL;
- } else if ( (v = strstr(pair, ">")) ) {
- *v++ = '\0';
- op = AUDIT_GREATER_THAN;
- } else if ( (v = strstr(pair, "<")) ) {
- *v++ = '\0';
- op = AUDIT_LESS_THAN;
- }
+ op = audit_get_operator(pair, &v);
if (v == NULL || f == v)
return -1;
@@ -673,7 +691,9 @@ int audit_rule_fieldpair(struct audit_ru
return -2;
audit_msg(LOG_DEBUG,"f%d%s%s\n", field, audit_operator_to_symbol(op),v);
- rule->fields[rule->field_count] = field | op;
+ rule->fields[rule->field_count] = field;
+ rule->fieldflags[rule->field_count] = op;
+
switch (field)
{
case AUDIT_UID:
@@ -819,6 +839,22 @@ int audit_rule_fieldpair(struct audit_ru
case AUDIT_DEVMAJOR...AUDIT_SUCCESS:
if (flags == AUDIT_FILTER_ENTRY)
return -7;
+ case AUDIT_SE_USER:
+ case AUDIT_SE_ROLE:
+ case AUDIT_SE_TYPE:
+ case AUDIT_SE_SEN:
+ case AUDIT_SE_CLR:
+ rule->values[rule->field_count] = strlen(v);
+ rule->buflen += strlen(v);
+ total_size = sizeof(*rule) + rule->buflen;
+ if (realloc(rule, total_size) == NULL) {
+ printf("Cannot realloc memory!\n");
+ return -3;
+ }
+ offset = total_size - sizeof(*rule) - strlen(v);
+ strncpy(&rule->buf[offset], v, strlen(v));
+ break;
+
/* fallthrough */
default:
rule->values[rule->field_count] = strtol(v, NULL, 0);
@@ -828,6 +864,30 @@ int audit_rule_fieldpair(struct audit_ru
return 0;
}
+/*
+ * Debug function useful to sanity check the contents of this new
+ * audit_rule_data structure, and in particular the variable length
+ * strings
+ */
+void print_audit_rule_data(struct audit_rule_data *rd) {
+ int i;
+ printf("====================================\n");
+ printf("flags = [0x%x]\n", rd->flags);
+ printf("action = [%d]\n", rd->action);
+ printf("field_count = [%d]\n", rd->field_count);
+ for (i=0; i<AUDIT_BITMASK_SIZE; i++)
+ if (rd->mask[i])
+ printf("mask[%d] = [0x%x]\n", i, rd->mask[i]);
+ for (i=0; i<AUDIT_MAX_FIELDS; i++) {
+ if (rd->fields[i] || rd->values[i] || rd->fieldflags[i])
+ printf("fields[%d] = [%d], values[%d] = [%d], fieldflags[%d] = [0x%x]\n", i,
rd->fields[i], i, rd->values[i], i, rd->fieldflags[i]);
+ }
+ printf("buflen = [%d]\n", rd->buflen);
+ printf("buf = [%s]\n", rd->buf);
+ printf("TOTAL_SIZE = [%d]\n", sizeof(*rd) + rd->buflen);
+ printf("====================================\n");
+}
+
void audit_rule_free(struct audit_rule *rule)
{
if (rule)
diff -urpN audit-1.1.3/lib/libaudit.h audit-1.1.3.dustin/lib/libaudit.h
--- audit-1.1.3/lib/libaudit.h 2006-02-02 11:02:12.000000000 -0600
+++ audit-1.1.3.dustin/lib/libaudit.h 2006-02-16 23:18:59.000000000 -0600
@@ -182,6 +182,13 @@ extern "C" {
#ifndef AUDIT_MSGTYPE
#define AUDIT_MSGTYPE 12
#endif
+#ifndef AUDIT_SE_USER
+#define AUDIT_SE_USER 13
+#define AUDIT_SE_ROLE 14
+#define AUDIT_SE_TYPE 15
+#define AUDIT_SE_SEN 16
+#define AUDIT_SE_CLR 17
+#endif
/* This is new list defines from audit.h */
#ifndef AUDIT_FILTER_USER
@@ -236,6 +243,30 @@ struct watch_transport {
};
#endif
+
+#ifndef AUDIT_ADD_RULE
+#define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */
+#define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */
+#define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */
+/* audit_rule_data supports filter rules with both integer and string
+ * fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
+ * AUDIT_LIST_RULES requests.
+ */
+struct audit_rule_data {
+ __u32 flags; /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
+ __u32 action; /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
+ __u32 field_count;
+ __u32 mask[AUDIT_BITMASK_SIZE];
+ __u32 fields[AUDIT_MAX_FIELDS];
+ __u32 values[AUDIT_MAX_FIELDS];
+ __u32 fieldflags[AUDIT_MAX_FIELDS];
+ __u32 buflen; /* total length of string fields */
+ char buf[0]; /* string fields buffer */
+};
+#endif
+
+
+
struct audit_watch {
uint32_t dev_major;
uint32_t dev_minor;
@@ -386,12 +417,12 @@ extern int audit_log_user_avc_message(in
const char *tty, uid_t uid);
/* Rule-building helper functions */
-extern int audit_rule_syscall(struct audit_rule *rule, int scall);
-extern int audit_rule_syscallbyname(struct audit_rule *rule,
+extern int audit_rule_syscall(struct audit_rule_data *rule, int scall);
+extern int audit_rule_syscallbyname(struct audit_rule_data *rule,
const char *scall);
extern int audit_rule_field(struct audit_rule *rule, int field,
unsigned int value);
-extern int audit_rule_fieldpair(struct audit_rule *rule, const char *pair,
+extern int audit_rule_fieldpair(struct audit_rule_data *rule, const char *pair,
int flags);
extern void audit_rule_free(struct audit_rule *rule);
diff -urpN audit-1.1.3/src/auditctl.c audit-1.1.3.dustin/src/auditctl.c
--- audit-1.1.3/src/auditctl.c 2006-01-04 16:19:55.000000000 -0600
+++ audit-1.1.3.dustin/src/auditctl.c 2006-02-02 13:15:09.000000000 -0600
@@ -70,6 +70,7 @@ static int list_requested = 0;
static int add = AUDIT_FILTER_UNSET, del = AUDIT_FILTER_UNSET, action = 0;
static int ins = 0, rem = 0, ignore = 0;
static struct audit_rule rule;
+static struct audit_rule_data *rule_data;
static struct audit_watch watch;
extern int audit_archadded;
@@ -92,6 +93,7 @@ static int reset_vars(void)
ins = 0;
rem = 0;
+ rule_data = calloc(1, sizeof(*rule_data));
memset(&rule, 0, sizeof(rule));
memset(&watch, 0, sizeof(watch));
if ((fd = audit_open()) < 0) {
@@ -158,6 +160,8 @@ static int audit_rule_setup(const char *
*act = AUDIT_ALWAYS;
else
return 1;
+ rule_data->flags = *flags;
+ rule_data->action = *act;
return 0;
}
@@ -498,7 +502,7 @@ static int setopt(int count, char *vars[
audit_elf = elf;
}
}
- switch (audit_rule_syscallbyname(&rule, optarg))
+ switch (audit_rule_syscallbyname(rule_data, optarg))
{
case 0:
audit_syscalladded = 1;
@@ -527,8 +531,8 @@ static int setopt(int count, char *vars[
fprintf(stderr, "List must be given before field\n");
retval = -1;
break;
- }
- switch (audit_rule_fieldpair(&rule, optarg, flags))
+ }
+ switch (audit_rule_fieldpair(rule_data, optarg, flags))
{
case 0:
break;
@@ -863,14 +867,14 @@ static int handle_request(int status)
// if !task add syscall any if not specified
if ((add & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK &&
audit_syscalladded != 1)
- audit_rule_syscallbyname(&rule, "all");
- rc = audit_add_rule(fd, &rule, add, action);
+ audit_rule_syscallbyname(rule_data, "all");
+ rc = audit_add_rule_data(fd, rule_data);
}
else if (del != AUDIT_FILTER_UNSET) {
if ((del & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK &&
audit_syscalladded != 1)
- audit_rule_syscallbyname(&rule, "all");
- rc = audit_delete_rule(fd, &rule, del, action);
+ audit_rule_syscallbyname(rule_data, "all");
+ rc = audit_del_rule_data(fd, rule_data);
}
else if (ins && !rem)
rc = audit_insert_watch(fd, &watch);