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