Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c94c257c authored by Serge Hallyn's avatar Serge Hallyn Committed by David Woodhouse
Browse files

Add audit uid to netlink credentials



Most audit control messages are sent over netlink.In order to properly
log the identity of the sender of audit control messages, we would like
to add the loginuid to the netlink_creds structure, as per the attached
patch.

Signed-off-by: default avatarSerge Hallyn <serue@us.ibm.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 85c8721f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ extern void audit_inode(const char *name, const struct inode *inode);

				/* Private API (for audit.c only) */
extern int  audit_receive_filter(int type, int pid, int uid, int seq,
				 void *data);
				 void *data, uid_t loginuid);
extern void audit_get_stamp(struct audit_context *ctx,
			    struct timespec *t, unsigned int *serial);
extern int  audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ struct netlink_skb_parms
	__u32			dst_pid;
	__u32			dst_groups;
	kernel_cap_t		eff_cap;
	__u32			loginuid;	/* Login (audit) uid */
};

#define NETLINK_CB(skb)		(*(struct netlink_skb_parms*)&((skb)->cb))
+25 −21
Original line number Diff line number Diff line
@@ -239,36 +239,36 @@ void audit_log_lost(const char *message)

}

static int audit_set_rate_limit(int limit)
static int audit_set_rate_limit(int limit, uid_t loginuid)
{
	int old		 = audit_rate_limit;
	audit_rate_limit = limit;
	audit_log(current->audit_context, "audit_rate_limit=%d old=%d",
		  audit_rate_limit, old);
	audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
			audit_rate_limit, old, loginuid);
	return old;
}

static int audit_set_backlog_limit(int limit)
static int audit_set_backlog_limit(int limit, uid_t loginuid)
{
	int old		 = audit_backlog_limit;
	audit_backlog_limit = limit;
	audit_log(current->audit_context, "audit_backlog_limit=%d old=%d",
		  audit_backlog_limit, old);
	audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
			audit_backlog_limit, old, loginuid);
	return old;
}

static int audit_set_enabled(int state)
static int audit_set_enabled(int state, uid_t loginuid)
{
	int old		 = audit_enabled;
	if (state != 0 && state != 1)
		return -EINVAL;
	audit_enabled = state;
	audit_log(current->audit_context, "audit_enabled=%d old=%d",
		  audit_enabled, old);
	audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
		  audit_enabled, old, loginuid);
	return old;
}

static int audit_set_failure(int state)
static int audit_set_failure(int state, uid_t loginuid)
{
	int old		 = audit_failure;
	if (state != AUDIT_FAIL_SILENT
@@ -276,8 +276,8 @@ static int audit_set_failure(int state)
	    && state != AUDIT_FAIL_PANIC)
		return -EINVAL;
	audit_failure = state;
	audit_log(current->audit_context, "audit_failure=%d old=%d",
		  audit_failure, old);
	audit_log(NULL, "audit_failure=%d old=%d by auid %u",
		  audit_failure, old, loginuid);
	return old;
}

@@ -344,6 +344,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
	int			err;
	struct audit_buffer	*ab;
	u16			msg_type = nlh->nlmsg_type;
	uid_t			loginuid; /* loginuid of sender */

	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
	if (err)
@@ -351,6 +352,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)

	pid  = NETLINK_CREDS(skb)->pid;
	uid  = NETLINK_CREDS(skb)->uid;
	loginuid = NETLINK_CB(skb).loginuid;
	seq  = nlh->nlmsg_seq;
	data = NLMSG_DATA(nlh);

@@ -371,34 +373,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
			return -EINVAL;
		status_get   = (struct audit_status *)data;
		if (status_get->mask & AUDIT_STATUS_ENABLED) {
			err = audit_set_enabled(status_get->enabled);
			err = audit_set_enabled(status_get->enabled, loginuid);
			if (err < 0) return err;
		}
		if (status_get->mask & AUDIT_STATUS_FAILURE) {
			err = audit_set_failure(status_get->failure);
			err = audit_set_failure(status_get->failure, loginuid);
			if (err < 0) return err;
		}
		if (status_get->mask & AUDIT_STATUS_PID) {
			int old   = audit_pid;
			audit_pid = status_get->pid;
			audit_log(current->audit_context,
				  "audit_pid=%d old=%d", audit_pid, old);
			audit_log(NULL, "audit_pid=%d old=%d by auid %u",
				  audit_pid, old, loginuid);
		}
		if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
			audit_set_rate_limit(status_get->rate_limit);
			audit_set_rate_limit(status_get->rate_limit, loginuid);
		if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
			audit_set_backlog_limit(status_get->backlog_limit);
			audit_set_backlog_limit(status_get->backlog_limit,
							loginuid);
		break;
	case AUDIT_USER:
		ab = audit_log_start(NULL);
		if (!ab)
			break;	/* audit_panic has been called */
		audit_log_format(ab,
				 "user pid=%d uid=%d length=%d msg='%.1024s'",
				 "user pid=%d uid=%d length=%d loginuid=%u"
				 " msg='%.1024s'",
				 pid, uid,
				 (int)(nlh->nlmsg_len
				       - ((char *)data - (char *)nlh)),
				 (char *)data);
				 loginuid, (char *)data);
		ab->type = AUDIT_USER;
		ab->pid  = pid;
		audit_log_end(ab);
@@ -411,7 +415,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
	case AUDIT_LIST:
#ifdef CONFIG_AUDITSYSCALL
		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
					   uid, seq, data);
					   uid, seq, data, loginuid);
#else
		err = -EOPNOTSUPP;
#endif
+4 −1
Original line number Diff line number Diff line
@@ -251,7 +251,8 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
	return 0;
}

int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
							uid_t loginuid)
{
	u32		   flags;
	struct audit_entry *entry;
@@ -286,6 +287,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
			err = audit_add_rule(entry, &audit_entlist);
		if (!err && (flags & AUDIT_AT_EXIT))
			err = audit_add_rule(entry, &audit_extlist);
		audit_log(NULL, "auid %u added an audit rule\n", loginuid);
		break;
	case AUDIT_DEL:
		flags =((struct audit_rule *)data)->flags;
@@ -295,6 +297,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
			err = audit_del_rule(data, &audit_entlist);
		if (!err && (flags & AUDIT_AT_EXIT))
			err = audit_del_rule(data, &audit_extlist);
		audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
		break;
	default:
		return -EINVAL;
+1 −0
Original line number Diff line number Diff line
@@ -905,6 +905,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
	NETLINK_CB(skb).groups	= nlk->groups;
	NETLINK_CB(skb).dst_pid = dst_pid;
	NETLINK_CB(skb).dst_groups = dst_groups;
	NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
	memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));

	/* What can I do? Netlink is asynchronous, so that