You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.infradead.org/users/eparis/audit
Pull audit update from Eric Paris: "Again we stayed pretty well contained inside the audit system. Venturing out was fixing a couple of function prototypes which were inconsistent (didn't hurt anything, but we used the same value as an int, uint, u32, and I think even a long in a couple of places). We also made a couple of minor changes to when a couple of LSMs called the audit system. We hoped to add aarch64 audit support this go round, but it wasn't ready. I'm disappearing on vacation on Thursday. I should have internet access, but it'll be spotty. If anything goes wrong please be sure to cc rgb@redhat.com. He'll make fixing things his top priority" * git://git.infradead.org/users/eparis/audit: (50 commits) audit: whitespace fix in kernel-parameters.txt audit: fix location of __net_initdata for audit_net_ops audit: remove pr_info for every network namespace audit: Modify a set of system calls in audit class definitions audit: Convert int limit uses to u32 audit: Use more current logging style audit: Use hex_byte_pack_upper audit: correct a type mismatch in audit_syscall_exit() audit: reorder AUDIT_TTY_SET arguments audit: rework AUDIT_TTY_SET to only grab spin_lock once audit: remove needless switch in AUDIT_SET audit: use define's for audit version audit: documentation of audit= kernel parameter audit: wait_for_auditd rework for readability audit: update MAINTAINERS audit: log task info on feature change audit: fix incorrect set of audit_sock audit: print error message when fail to create audit socket audit: fix dangling keywords in audit_log_set_loginuid() output audit: log on errors from filter user rules ...
This commit is contained in:
+236
-131
File diff suppressed because it is too large
Load Diff
+10
-5
@@ -209,7 +209,7 @@ struct audit_context {
|
||||
#endif
|
||||
};
|
||||
|
||||
extern int audit_ever_enabled;
|
||||
extern u32 audit_ever_enabled;
|
||||
|
||||
extern void audit_copy_inode(struct audit_names *name,
|
||||
const struct dentry *dentry,
|
||||
@@ -240,18 +240,23 @@ extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
|
||||
extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
|
||||
extern int parent_len(const char *path);
|
||||
extern int audit_compare_dname_path(const char *dname, const char *path, int plen);
|
||||
extern struct sk_buff * audit_make_reply(int pid, int seq, int type,
|
||||
int done, int multi,
|
||||
const void *payload, int size);
|
||||
extern struct sk_buff *audit_make_reply(__u32 portid, int seq, int type,
|
||||
int done, int multi,
|
||||
const void *payload, int size);
|
||||
extern void audit_panic(const char *message);
|
||||
|
||||
struct audit_netlink_list {
|
||||
int pid;
|
||||
__u32 portid;
|
||||
pid_t pid;
|
||||
struct sk_buff_head q;
|
||||
};
|
||||
|
||||
int audit_send_list(void *);
|
||||
|
||||
struct audit_net {
|
||||
struct sock *nlsk;
|
||||
};
|
||||
|
||||
extern int selinux_audit_rule_update(void);
|
||||
|
||||
extern struct mutex audit_filter_mutex;
|
||||
|
||||
+55
-38
@@ -972,7 +972,7 @@ out:
|
||||
}
|
||||
|
||||
/* List rules using struct audit_rule_data. */
|
||||
static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
|
||||
static void audit_list_rules(__u32 portid, int seq, struct sk_buff_head *q)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct audit_krule *r;
|
||||
@@ -987,14 +987,15 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
|
||||
data = audit_krule_to_data(r);
|
||||
if (unlikely(!data))
|
||||
break;
|
||||
skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
|
||||
data, sizeof(*data) + data->buflen);
|
||||
skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES,
|
||||
0, 1, data,
|
||||
sizeof(*data) + data->buflen);
|
||||
if (skb)
|
||||
skb_queue_tail(q, skb);
|
||||
kfree(data);
|
||||
}
|
||||
}
|
||||
skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
|
||||
skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
|
||||
if (skb)
|
||||
skb_queue_tail(q, skb);
|
||||
}
|
||||
@@ -1004,7 +1005,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(current));
|
||||
u32 sessionid = audit_get_sessionid(current);
|
||||
unsigned int sessionid = audit_get_sessionid(current);
|
||||
|
||||
if (!audit_enabled)
|
||||
return;
|
||||
@@ -1022,45 +1023,20 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
|
||||
}
|
||||
|
||||
/**
|
||||
* audit_receive_filter - apply all rules to the specified message type
|
||||
* audit_rule_change - apply all rules to the specified message type
|
||||
* @type: audit message type
|
||||
* @pid: target pid for netlink audit messages
|
||||
* @portid: target port id for netlink audit messages
|
||||
* @seq: netlink audit message sequence (serial) number
|
||||
* @data: payload data
|
||||
* @datasz: size of payload data
|
||||
*/
|
||||
int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz)
|
||||
int audit_rule_change(int type, __u32 portid, int seq, void *data,
|
||||
size_t datasz)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
struct audit_netlink_list *dest;
|
||||
int err = 0;
|
||||
struct audit_entry *entry;
|
||||
|
||||
switch (type) {
|
||||
case AUDIT_LIST_RULES:
|
||||
/* We can't just spew out the rules here because we might fill
|
||||
* the available socket buffer space and deadlock waiting for
|
||||
* auditctl to read from it... which isn't ever going to
|
||||
* happen if we're actually running in the context of auditctl
|
||||
* trying to _send_ the stuff */
|
||||
|
||||
dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
|
||||
if (!dest)
|
||||
return -ENOMEM;
|
||||
dest->pid = pid;
|
||||
skb_queue_head_init(&dest->q);
|
||||
|
||||
mutex_lock(&audit_filter_mutex);
|
||||
audit_list_rules(pid, seq, &dest->q);
|
||||
mutex_unlock(&audit_filter_mutex);
|
||||
|
||||
tsk = kthread_run(audit_send_list, dest, "audit_send_list");
|
||||
if (IS_ERR(tsk)) {
|
||||
skb_queue_purge(&dest->q);
|
||||
kfree(dest);
|
||||
err = PTR_ERR(tsk);
|
||||
}
|
||||
break;
|
||||
case AUDIT_ADD_RULE:
|
||||
entry = audit_data_to_entry(data, datasz);
|
||||
if (IS_ERR(entry))
|
||||
@@ -1087,6 +1063,44 @@ int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz)
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* audit_list_rules_send - list the audit rules
|
||||
* @portid: target portid for netlink audit messages
|
||||
* @seq: netlink audit message sequence (serial) number
|
||||
*/
|
||||
int audit_list_rules_send(__u32 portid, int seq)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
struct audit_netlink_list *dest;
|
||||
int err = 0;
|
||||
|
||||
/* We can't just spew out the rules here because we might fill
|
||||
* the available socket buffer space and deadlock waiting for
|
||||
* auditctl to read from it... which isn't ever going to
|
||||
* happen if we're actually running in the context of auditctl
|
||||
* trying to _send_ the stuff */
|
||||
|
||||
dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
|
||||
if (!dest)
|
||||
return -ENOMEM;
|
||||
dest->portid = portid;
|
||||
dest->pid = task_pid_vnr(current);
|
||||
skb_queue_head_init(&dest->q);
|
||||
|
||||
mutex_lock(&audit_filter_mutex);
|
||||
audit_list_rules(portid, seq, &dest->q);
|
||||
mutex_unlock(&audit_filter_mutex);
|
||||
|
||||
tsk = kthread_run(audit_send_list, dest, "audit_send_list");
|
||||
if (IS_ERR(tsk)) {
|
||||
skb_queue_purge(&dest->q);
|
||||
kfree(dest);
|
||||
err = PTR_ERR(tsk);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int audit_comparator(u32 left, u32 op, u32 right)
|
||||
{
|
||||
switch (op) {
|
||||
@@ -1276,19 +1290,22 @@ int audit_filter_user(int type)
|
||||
{
|
||||
enum audit_state state = AUDIT_DISABLED;
|
||||
struct audit_entry *e;
|
||||
int ret = 1;
|
||||
int rc, ret;
|
||||
|
||||
ret = 1; /* Audit by default */
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
|
||||
if (audit_filter_user_rules(&e->rule, type, &state)) {
|
||||
if (state == AUDIT_DISABLED)
|
||||
rc = audit_filter_user_rules(&e->rule, type, &state);
|
||||
if (rc) {
|
||||
if (rc > 0 && state == AUDIT_DISABLED)
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return ret; /* Audit by default */
|
||||
return ret;
|
||||
}
|
||||
|
||||
int audit_filter_type(int type)
|
||||
|
||||
+25
-19
@@ -1969,18 +1969,24 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
|
||||
int rc)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
uid_t uid, ologinuid, nloginuid;
|
||||
uid_t uid, oldloginuid, loginuid;
|
||||
|
||||
if (!audit_enabled)
|
||||
return;
|
||||
|
||||
uid = from_kuid(&init_user_ns, task_uid(current));
|
||||
ologinuid = from_kuid(&init_user_ns, koldloginuid);
|
||||
nloginuid = from_kuid(&init_user_ns, kloginuid),
|
||||
oldloginuid = from_kuid(&init_user_ns, koldloginuid);
|
||||
loginuid = from_kuid(&init_user_ns, kloginuid),
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
|
||||
if (!ab)
|
||||
return;
|
||||
audit_log_format(ab, "pid=%d uid=%u old auid=%u new auid=%u old "
|
||||
"ses=%u new ses=%u res=%d", current->pid, uid, ologinuid,
|
||||
nloginuid, oldsessionid, sessionid, !rc);
|
||||
audit_log_format(ab, "pid=%d uid=%u"
|
||||
" old-auid=%u new-auid=%u old-ses=%u new-ses=%u"
|
||||
" res=%d",
|
||||
current->pid, uid,
|
||||
oldloginuid, loginuid, oldsessionid, sessionid,
|
||||
!rc);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
|
||||
@@ -2008,7 +2014,7 @@ int audit_set_loginuid(kuid_t loginuid)
|
||||
|
||||
/* are we setting or clearing? */
|
||||
if (uid_valid(loginuid))
|
||||
sessionid = atomic_inc_return(&session_id);
|
||||
sessionid = (unsigned int)atomic_inc_return(&session_id);
|
||||
|
||||
task->sessionid = sessionid;
|
||||
task->loginuid = loginuid;
|
||||
@@ -2321,18 +2327,16 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
|
||||
|
||||
/**
|
||||
* __audit_log_capset - store information about the arguments to the capset syscall
|
||||
* @pid: target pid of the capset call
|
||||
* @new: the new credentials
|
||||
* @old: the old (current) credentials
|
||||
*
|
||||
* Record the aguments userspace sent to sys_capset for later printing by the
|
||||
* audit system if applicable
|
||||
*/
|
||||
void __audit_log_capset(pid_t pid,
|
||||
const struct cred *new, const struct cred *old)
|
||||
void __audit_log_capset(const struct cred *new, const struct cred *old)
|
||||
{
|
||||
struct audit_context *context = current->audit_context;
|
||||
context->capset.pid = pid;
|
||||
context->capset.pid = task_pid_nr(current);
|
||||
context->capset.cap.effective = new->cap_effective;
|
||||
context->capset.cap.inheritable = new->cap_effective;
|
||||
context->capset.cap.permitted = new->cap_permitted;
|
||||
@@ -2352,6 +2356,7 @@ static void audit_log_task(struct audit_buffer *ab)
|
||||
kuid_t auid, uid;
|
||||
kgid_t gid;
|
||||
unsigned int sessionid;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
auid = audit_get_loginuid(current);
|
||||
sessionid = audit_get_sessionid(current);
|
||||
@@ -2365,15 +2370,15 @@ static void audit_log_task(struct audit_buffer *ab)
|
||||
audit_log_task_context(ab);
|
||||
audit_log_format(ab, " pid=%d comm=", current->pid);
|
||||
audit_log_untrustedstring(ab, current->comm);
|
||||
if (mm) {
|
||||
down_read(&mm->mmap_sem);
|
||||
if (mm->exe_file)
|
||||
audit_log_d_path(ab, " exe=", &mm->exe_file->f_path);
|
||||
up_read(&mm->mmap_sem);
|
||||
} else
|
||||
audit_log_format(ab, " exe=(null)");
|
||||
}
|
||||
|
||||
static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
|
||||
{
|
||||
audit_log_task(ab);
|
||||
audit_log_format(ab, " reason=");
|
||||
audit_log_string(ab, reason);
|
||||
audit_log_format(ab, " sig=%ld", signr);
|
||||
}
|
||||
/**
|
||||
* audit_core_dumps - record information about processes that end abnormally
|
||||
* @signr: signal value
|
||||
@@ -2394,7 +2399,8 @@ void audit_core_dumps(long signr)
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
|
||||
if (unlikely(!ab))
|
||||
return;
|
||||
audit_log_abend(ab, "memory violation", signr);
|
||||
audit_log_task(ab);
|
||||
audit_log_format(ab, " sig=%ld", signr);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -277,7 +277,7 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data)
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
audit_log_capset(pid, new, current_cred());
|
||||
audit_log_capset(new, current_cred());
|
||||
|
||||
return commit_creds(new);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user