Skip to content

Commit

Permalink
Add support for logging rule number of decision in the audit event
Browse files Browse the repository at this point in the history
  • Loading branch information
RH-steve-grubb committed Feb 7, 2023
1 parent 81d64b4 commit ee9c99a
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 13 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- On shutdown when running reports, if trust db empty warn (Nobuhiro Iwamatsu)
- Extend state machine to skip opens after exec until dyn linker found
- Control filtering of unwanted files in rpm backend with config file
- Add support for logging rule number of decision in the audit event

1.1.7
- Re-add dropped FAN_MARK_MOUNT for monitoring events (Steven Brzozowski)
Expand Down
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ AC_CHECK_PROG([FILE_COMM], "file", "yes", "no")
if test "$FILE_COMM" = "no"; then
AC_MSG_ERROR([Unable to find the file program need to build magic databases])
fi
AC_CHECK_MEMBER([struct fanotify_response_info_audit_rule.rule_number],
[perm=yes], [perm=no], [[#include <linux/fanotify.h>]])
if test $perm = "yes"; then
AC_DEFINE(FAN_AUDIT_RULE_NUM, 1,[Define if kernel supports audit rule numbers])
fi

echo .
echo Checking compiler options
Expand Down
9 changes: 5 additions & 4 deletions src/daemon/notify.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* notify.c - functions handle recieving and enqueuing events
* Copyright (c) 2016-18,22 Red Hat Inc.
* Copyright (c) 2016-18,2022-23 Red Hat Inc.
* All Rights Reserved.
*
* This software may be freely redistributed and/or modified under the
Expand Down Expand Up @@ -350,7 +350,7 @@ static void enqueue_event(const struct fanotify_event_metadata *metadata)
// We have to deny. This allows the kernel to free it's
// memory related to this request. reply_event also closes
// the descriptor, so we don't need to do it here.
reply_event(fd, metadata, FAN_DENY);
reply_event(fd, metadata, FAN_DENY, NULL);
msg(LOG_DEBUG, "enqueue error");
} else
set_ready();
Expand Down Expand Up @@ -392,14 +392,15 @@ void handle_events(void)
if (metadata->fd >= 0) {
if (metadata->mask & mask) {
if (metadata->pid == our_pid)
reply_event(fd, metadata, FAN_ALLOW);
reply_event(fd, metadata, FAN_ALLOW,
NULL);
else
enqueue_event(metadata);
} else {
// This should never happen. Reply with deny
// which releases the descriptor and kernel
// memory. Continue processing what was read.
reply_event(fd, metadata, FAN_DENY);
reply_event(fd, metadata, FAN_DENY, NULL);
}
}
metadata = FAN_EVENT_NEXT(metadata, len);
Expand Down
3 changes: 2 additions & 1 deletion src/library/event.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* event.c - Functions to access event attributes
* Copyright (c) 2016,2018-20 Red Hat Inc.
* Copyright (c) 2016,2018-20,2023 Red Hat Inc.
* All Rights Reserved.
*
* This software may be freely redistributed and/or modified under the
Expand Down Expand Up @@ -109,6 +109,7 @@ int new_event(const struct fanotify_event_metadata *m, event_t *e)
e->pid = m->pid;
e->fd = m->fd;
e->type = m->mask & ALL_EVENTS;
e->num = 0;

key = compute_subject_key(subj_cache, m->pid);
q_node = check_lru_cache(subj_cache, key);
Expand Down
3 changes: 2 additions & 1 deletion src/library/event.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* event.h - Header file for event.c
* Copyright (c) 2016,2018-19 Red Hat Inc.
* Copyright (c) 2016,2018-19,2023 Red Hat Inc.
* All Rights Reserved.
*
* This software may be freely redistributed and/or modified under the
Expand Down Expand Up @@ -37,6 +37,7 @@ typedef struct ev {
pid_t pid;
int fd;
int type;
unsigned num;
s_array *s;
o_array *o;
} event_t;
Expand Down
85 changes: 80 additions & 5 deletions src/library/policy.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* policy.c - functions that encapsulate the notion of a policy
* Copyright (c) 2016,2019-22 Red Hat
* Copyright (c) 2016,2019-23 Red Hat
* All Rights Reserved.
*
* This software may be freely redistributed and/or modified under the
Expand Down Expand Up @@ -71,6 +71,13 @@ static const nv_t table[] = {
#define F_PERM 32
#define F_COLON 33

#ifdef FAN_AUDIT_RULE_NUM
struct fan_audit_response
{
struct fanotify_response r;
struct fanotify_response_info_audit_rule a;
};
#endif

// This function returns 1 on success and 0 on failure
static int parsing_obj;
Expand Down Expand Up @@ -408,21 +415,87 @@ decision_t process_event(event_t *e)
(debug > 1 && (results & DENY)) )
log_it2(r ? r->num : 0xFFFFFFFF, results, e);

// Record which rule (rules are 1 based when listed by the cli tool)
if (r)
e->num = r->num + 1;

// If we are not in permissive mode, return any decision
if (results != NO_OPINION)
return results;

return ALLOW;
}

#ifdef FAN_AUDIT_RULE_NUM
static int test_info_api(int fd)
{
int rc;
struct fan_audit_response f;

f.r.fd = FAN_NOFD;
f.r.response = FAN_DENY | FAN_INFO;
f.a.hdr.type = FAN_RESPONSE_INFO_AUDIT_RULE;
f.a.hdr.pad = 0;
f.a.hdr.len = sizeof(struct fanotify_response_info_audit_rule);
f.a.rule_number = 0;
f.a.subj_trust = 2;
f.a.obj_trust = 2;
rc = write(fd, &f, sizeof(struct fan_audit_response));
msg(LOG_DEBUG, "Rule number API supported %s", rc < 0 ? "no" : "yes");
if (rc < 0)
return 0;
else
return 1;
}
#endif

void reply_event(int fd, const struct fanotify_event_metadata *metadata,
unsigned reply)
unsigned reply, event_t *e)
{
close(metadata->fd);
#ifdef FAN_AUDIT_RULE_NUM
static int use_new = 2;
if (use_new == 2)
use_new = test_info_api(fd);
if (reply & FAN_AUDIT && use_new) {
struct fan_audit_response f;
subject_attr_t *sn;
object_attr_t *obj;

f.r.fd = metadata->fd;
f.r.response = reply | FAN_INFO;
f.a.hdr.type = FAN_RESPONSE_INFO_AUDIT_RULE;
f.a.hdr.pad = 0;
f.a.hdr.len = sizeof(struct fanotify_response_info_audit_rule);
if (e)
f.a.rule_number = e->num;
else
f.a.rule_number = 0;

// Subj trust is rare. See if we have it.
if (e && (sn = subject_access(e->s, SUBJ_TRUST))) {
if (sn)
f.a.subj_trust = sn->val;
else
f.a.subj_trust = 2;
} else
f.a.subj_trust = 2;
// All objects have a trust value
if (e && (obj = get_obj_attr(e, OBJ_TRUST))) {
if (obj)
f.a.obj_trust = obj->val;
else // Only serious errors cause this
f.a.obj_trust = 2;
} else
f.a.obj_trust = 2;
write(fd, &f, sizeof(struct fan_audit_response));
return;
}
#endif
struct fanotify_response response;

response.fd = metadata->fd;
response.response = reply;
close(metadata->fd);
write(fd, &response, sizeof(struct fanotify_response));
}

Expand Down Expand Up @@ -451,9 +524,11 @@ void make_policy_decision(const struct fanotify_event_metadata *metadata,
// If permissive, always allow and honor the audit bit
// if not in debug mode
if (permissive)
reply_event(fd, metadata,FAN_ALLOW |(decision & AUDIT));
reply_event(fd, metadata,FAN_ALLOW | (decision & AUDIT),
&e);
else
reply_event(fd, metadata, decision & FAN_RESPONSE_MASK);
reply_event(fd, metadata, decision & FAN_RESPONSE_MASK,
&e);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/library/policy.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* policy.h - Header file for policy.c
* Copyright (c) 2016,2020 Red Hat
* Copyright (c) 2016,2020,2023 Red Hat
* All Rights Reserved.
*
* This software may be freely redistributed and/or modified under the
Expand Down Expand Up @@ -64,7 +64,7 @@ int load_config(const conf_t *config);
int reload_config(const conf_t *config);
decision_t process_event(event_t *e);
void reply_event(int fd, const struct fanotify_event_metadata *metadata,
unsigned reply);
unsigned reply, event_t *e);
void make_policy_decision(const struct fanotify_event_metadata *metadata,
int fd, uint64_t mask);
unsigned long getAllowed(void);
Expand Down

0 comments on commit ee9c99a

Please sign in to comment.