⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auditfilter.c

📁 Kernel code of linux kernel
💻 C
📖 第 1 页 / 共 4 页
字号:
		case AUDIT_ARG1:		case AUDIT_ARG2:		case AUDIT_ARG3:			break;		/* arch is only allowed to be = or != */		case AUDIT_ARCH:			if ((f->op != AUDIT_NOT_EQUAL) && (f->op != AUDIT_EQUAL)					&& (f->op != AUDIT_NEGATE) && (f->op)) {				err = -EINVAL;				goto exit_free;			}			entry->rule.arch_f = f;			break;		case AUDIT_PERM:			if (f->val & ~15)				goto exit_free;			break;		case AUDIT_FILETYPE:			if ((f->val & ~S_IFMT) > S_IFMT)				goto exit_free;			break;		case AUDIT_INODE:			err = audit_to_inode(&entry->rule, f);			if (err)				goto exit_free;			break;		}		entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1;		/* Support for legacy operators where		 * AUDIT_NEGATE bit signifies != and otherwise assumes == */		if (f->op & AUDIT_NEGATE)			f->op = AUDIT_NOT_EQUAL;		else if (!f->op)			f->op = AUDIT_EQUAL;		else if (f->op == AUDIT_OPERATORS) {			err = -EINVAL;			goto exit_free;		}	}	ino_f = entry->rule.inode_f;	if (ino_f) {		switch(ino_f->op) {		case AUDIT_NOT_EQUAL:			entry->rule.inode_f = NULL;		case AUDIT_EQUAL:			break;		default:			err = -EINVAL;			goto exit_free;		}	}exit_nofree:	return entry;exit_free:	audit_free_rule(entry);	return ERR_PTR(err);}/* Translate struct audit_rule_data to kernel's rule respresentation. */static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,					       size_t datasz){	int err = 0;	struct audit_entry *entry;	struct audit_field *ino_f;	void *bufp;	size_t remain = datasz - sizeof(struct audit_rule_data);	int i;	char *str;	entry = audit_to_entry_common((struct audit_rule *)data);	if (IS_ERR(entry))		goto exit_nofree;	bufp = data->buf;	entry->rule.vers_ops = 2;	for (i = 0; i < data->field_count; i++) {		struct audit_field *f = &entry->rule.fields[i];		err = -EINVAL;		if (!(data->fieldflags[i] & AUDIT_OPERATORS) ||		    data->fieldflags[i] & ~AUDIT_OPERATORS)			goto exit_free;		f->op = data->fieldflags[i] & AUDIT_OPERATORS;		f->type = data->fields[i];		f->val = data->values[i];		f->lsm_str = NULL;		f->lsm_rule = NULL;		switch(f->type) {		case AUDIT_PID:		case AUDIT_UID:		case AUDIT_EUID:		case AUDIT_SUID:		case AUDIT_FSUID:		case AUDIT_GID:		case AUDIT_EGID:		case AUDIT_SGID:		case AUDIT_FSGID:		case AUDIT_LOGINUID:		case AUDIT_PERS:		case AUDIT_MSGTYPE:		case AUDIT_PPID:		case AUDIT_DEVMAJOR:		case AUDIT_DEVMINOR:		case AUDIT_EXIT:		case AUDIT_SUCCESS:		case AUDIT_ARG0:		case AUDIT_ARG1:		case AUDIT_ARG2:		case AUDIT_ARG3:			break;		case AUDIT_ARCH:			entry->rule.arch_f = f;			break;		case AUDIT_SUBJ_USER:		case AUDIT_SUBJ_ROLE:		case AUDIT_SUBJ_TYPE:		case AUDIT_SUBJ_SEN:		case AUDIT_SUBJ_CLR:		case AUDIT_OBJ_USER:		case AUDIT_OBJ_ROLE:		case AUDIT_OBJ_TYPE:		case AUDIT_OBJ_LEV_LOW:		case AUDIT_OBJ_LEV_HIGH:			str = audit_unpack_string(&bufp, &remain, f->val);			if (IS_ERR(str))				goto exit_free;			entry->rule.buflen += f->val;			err = security_audit_rule_init(f->type, f->op, str,						       (void **)&f->lsm_rule);			/* Keep currently invalid fields around in case they			 * become valid after a policy reload. */			if (err == -EINVAL) {				printk(KERN_WARNING "audit rule for LSM "				       "\'%s\' is invalid\n",  str);				err = 0;			}			if (err) {				kfree(str);				goto exit_free;			} else				f->lsm_str = str;			break;		case AUDIT_WATCH:			str = audit_unpack_string(&bufp, &remain, f->val);			if (IS_ERR(str))				goto exit_free;			entry->rule.buflen += f->val;			err = audit_to_watch(&entry->rule, str, f->val, f->op);			if (err) {				kfree(str);				goto exit_free;			}			break;		case AUDIT_DIR:			str = audit_unpack_string(&bufp, &remain, f->val);			if (IS_ERR(str))				goto exit_free;			entry->rule.buflen += f->val;			err = audit_make_tree(&entry->rule, str, f->op);			kfree(str);			if (err)				goto exit_free;			break;		case AUDIT_INODE:			err = audit_to_inode(&entry->rule, f);			if (err)				goto exit_free;			break;		case AUDIT_FILTERKEY:			err = -EINVAL;			if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN)				goto exit_free;			str = audit_unpack_string(&bufp, &remain, f->val);			if (IS_ERR(str))				goto exit_free;			entry->rule.buflen += f->val;			entry->rule.filterkey = str;			break;		case AUDIT_PERM:			if (f->val & ~15)				goto exit_free;			break;		case AUDIT_FILETYPE:			if ((f->val & ~S_IFMT) > S_IFMT)				goto exit_free;			break;		default:			goto exit_free;		}	}	ino_f = entry->rule.inode_f;	if (ino_f) {		switch(ino_f->op) {		case AUDIT_NOT_EQUAL:			entry->rule.inode_f = NULL;		case AUDIT_EQUAL:			break;		default:			err = -EINVAL;			goto exit_free;		}	}exit_nofree:	return entry;exit_free:	audit_free_rule(entry);	return ERR_PTR(err);}/* Pack a filter field's string representation into data block. */static inline size_t audit_pack_string(void **bufp, const char *str){	size_t len = strlen(str);	memcpy(*bufp, str, len);	*bufp += len;	return len;}/* Translate kernel rule respresentation to struct audit_rule. * Exists for backward compatibility with userspace. */static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule){	struct audit_rule *rule;	int i;	rule = kzalloc(sizeof(*rule), GFP_KERNEL);	if (unlikely(!rule))		return NULL;	rule->flags = krule->flags | krule->listnr;	rule->action = krule->action;	rule->field_count = krule->field_count;	for (i = 0; i < rule->field_count; i++) {		rule->values[i] = krule->fields[i].val;		rule->fields[i] = krule->fields[i].type;		if (krule->vers_ops == 1) {			if (krule->fields[i].op & AUDIT_NOT_EQUAL)				rule->fields[i] |= AUDIT_NEGATE;		} else {			rule->fields[i] |= krule->fields[i].op;		}	}	for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i];	return rule;}/* Translate kernel rule respresentation to struct audit_rule_data. */static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule){	struct audit_rule_data *data;	void *bufp;	int i;	data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL);	if (unlikely(!data))		return NULL;	memset(data, 0, sizeof(*data));	data->flags = krule->flags | krule->listnr;	data->action = krule->action;	data->field_count = krule->field_count;	bufp = data->buf;	for (i = 0; i < data->field_count; i++) {		struct audit_field *f = &krule->fields[i];		data->fields[i] = f->type;		data->fieldflags[i] = f->op;		switch(f->type) {		case AUDIT_SUBJ_USER:		case AUDIT_SUBJ_ROLE:		case AUDIT_SUBJ_TYPE:		case AUDIT_SUBJ_SEN:		case AUDIT_SUBJ_CLR:		case AUDIT_OBJ_USER:		case AUDIT_OBJ_ROLE:		case AUDIT_OBJ_TYPE:		case AUDIT_OBJ_LEV_LOW:		case AUDIT_OBJ_LEV_HIGH:			data->buflen += data->values[i] =				audit_pack_string(&bufp, f->lsm_str);			break;		case AUDIT_WATCH:			data->buflen += data->values[i] =				audit_pack_string(&bufp, krule->watch->path);			break;		case AUDIT_DIR:			data->buflen += data->values[i] =				audit_pack_string(&bufp,						  audit_tree_path(krule->tree));			break;		case AUDIT_FILTERKEY:			data->buflen += data->values[i] =				audit_pack_string(&bufp, krule->filterkey);			break;		default:			data->values[i] = f->val;		}	}	for (i = 0; i < AUDIT_BITMASK_SIZE; i++) data->mask[i] = krule->mask[i];	return data;}/* Compare two rules in kernel format.  Considered success if rules * don't match. */static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b){	int i;	if (a->flags != b->flags ||	    a->listnr != b->listnr ||	    a->action != b->action ||	    a->field_count != b->field_count)		return 1;	for (i = 0; i < a->field_count; i++) {		if (a->fields[i].type != b->fields[i].type ||		    a->fields[i].op != b->fields[i].op)			return 1;		switch(a->fields[i].type) {		case AUDIT_SUBJ_USER:		case AUDIT_SUBJ_ROLE:		case AUDIT_SUBJ_TYPE:		case AUDIT_SUBJ_SEN:		case AUDIT_SUBJ_CLR:		case AUDIT_OBJ_USER:		case AUDIT_OBJ_ROLE:		case AUDIT_OBJ_TYPE:		case AUDIT_OBJ_LEV_LOW:		case AUDIT_OBJ_LEV_HIGH:			if (strcmp(a->fields[i].lsm_str, b->fields[i].lsm_str))				return 1;			break;		case AUDIT_WATCH:			if (strcmp(a->watch->path, b->watch->path))				return 1;			break;		case AUDIT_DIR:			if (strcmp(audit_tree_path(a->tree),				   audit_tree_path(b->tree)))				return 1;			break;		case AUDIT_FILTERKEY:			/* both filterkeys exist based on above type compare */			if (strcmp(a->filterkey, b->filterkey))				return 1;			break;		default:			if (a->fields[i].val != b->fields[i].val)				return 1;		}	}	for (i = 0; i < AUDIT_BITMASK_SIZE; i++)		if (a->mask[i] != b->mask[i])			return 1;	return 0;}/* Duplicate the given audit watch.  The new watch's rules list is initialized * to an empty list and wlist is undefined. */static struct audit_watch *audit_dupe_watch(struct audit_watch *old){	char *path;	struct audit_watch *new;	path = kstrdup(old->path, GFP_KERNEL);	if (unlikely(!path))		return ERR_PTR(-ENOMEM);	new = audit_init_watch(path);	if (IS_ERR(new)) {		kfree(path);		goto out;	}	new->dev = old->dev;	new->ino = old->ino;	get_inotify_watch(&old->parent->wdata);	new->parent = old->parent;out:	return new;}/* Duplicate LSM field information.  The lsm_rule is opaque, so must be * re-initialized. */static inline int audit_dupe_lsm_field(struct audit_field *df,					   struct audit_field *sf){	int ret = 0;	char *lsm_str;	/* our own copy of lsm_str */	lsm_str = kstrdup(sf->lsm_str, GFP_KERNEL);	if (unlikely(!lsm_str))		return -ENOMEM;	df->lsm_str = lsm_str;	/* our own (refreshed) copy of lsm_rule */	ret = security_audit_rule_init(df->type, df->op, df->lsm_str,				       (void **)&df->lsm_rule);	/* Keep currently invalid fields around in case they	 * become valid after a policy reload. */	if (ret == -EINVAL) {		printk(KERN_WARNING "audit rule for LSM \'%s\' is "		       "invalid\n", df->lsm_str);		ret = 0;	}	return ret;}/* Duplicate an audit rule.  This will be a deep copy with the exception * of the watch - that pointer is carried over.  The LSM specific fields * will be updated in the copy.  The point is to be able to replace the old * rule with the new rule in the filterlist, then free the old rule. * The rlist element is undefined; list manipulations are handled apart from * the initial copy. */static struct audit_entry *audit_dupe_rule(struct audit_krule *old,					   struct audit_watch *watch){	u32 fcount = old->field_count;	struct audit_entry *entry;	struct audit_krule *new;	char *fk;	int i, err = 0;	entry = audit_init_entry(fcount);	if (unlikely(!entry))		return ERR_PTR(-ENOMEM);	new = &entry->rule;	new->vers_ops = old->vers_ops;	new->flags = old->flags;	new->listnr = old->listnr;	new->action = old->action;	for (i = 0; i < AUDIT_BITMASK_SIZE; i++)		new->mask[i] = old->mask[i];	new->buflen = old->buflen;	new->inode_f = old->inode_f;	new->watch = NULL;	new->field_count = old->field_count;	/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -