New operators for rules
Timothy R. Chavez
tinytim at us.ibm.com
Thu Sep 29 19:40:07 UTC 2005
On Wednesday 28 September 2005 15:47, Steve Grubb wrote:
> Hello,
>
> Dustin and I were talking about how to represent some new operators for
> writing audit rules. I am interested in seeing >, <, and range added at a
> minimum. The question came up as to how to fit this into the existing
> audit_rule structure. This is what we currently have:
>
> struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
> __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];
> };
>
>
> The fields member currently uses the msb to determine whether its = or !=.
>
> #define AUDIT_NEGATE 0x80000000
>
> I was wondering if we should go ahead and map the other operators into the
> other high bits. We are currently only using the lower 4 bits of the u32 word
> so we have plenty of room. We have to do this in a way that is backward
> compatible for old kernels. Any ideas? Any preferred bit patterns?
>
> Also, we have the issue of needing to send 2 values for a range operator. How
> should we make the kernel understand this? Or should we create a new message
> type for adding, listing, and deleting rules that we can expand the idea of
> operators for and use the current one for legacy compatibility?
>
> Need some ideas from the kernel hackers....
>
> -Steve
>
> --
> Linux-audit mailing list
> Linux-audit at redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
>
>
You could add a zero-sized array at the bottom like, so:
struct op_t {
char op[2];
}
struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
__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];
struct op_t operator[0];
};
Then you iterate over field count to get each operator corresponding to the value.
Haha, I wrote this number... which is nice and ugly to convey the point... but, I do think using
the high bits is probably a good approach to stick with...
-tim
#include <stdio.h>
#include <errno.h>
#define OP_LESS ((char[2]){'<', ' '})
#define OP_LESS_EQUAL ((char[2]){'<', '='})
struct op_t {
char op[2];
};
struct compare_t {
struct op_t ops[0];
};
int main(void)
{
int i;
struct op_t op_one;
struct op_t op_two;
struct op_t this_op;
struct compare_t *c;
op_one.op[0] = '<';
op_one.op[1] = ' ';
op_two.op[0] = '<';
op_two.op[1] = '=';
c = (struct compare_t *)malloc(sizeof(*c) + (2 * sizeof(struct op_t)));
if (!c) {
perror("malloc");
exit(errno);
}
c->ops[0] = op_one;
c->ops[1] = op_two;
for (i = 0; i < 2; i++) {
this_op = c->ops[i];
if (!memcmp(this_op.op, OP_LESS, 2))
printf("Less than\n");
if (!memcmp(this_op.op, OP_LESS_EQUAL, 2))
printf("Less than or equal\n");
}
free(c);
return 0;
}
More information about the Linux-audit
mailing list