audit/stable-5.3 PR 20190702
-----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAl0bgNYUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXONcRAAqpeGVh3/eU5bmGeiOWZJ5TREx0Qf 4M8Z3CElxtbPF4nz1nARUbH424zF91AOa0B4JVO8BFCgxWN5M3dDOLjqLLfJkfbE mQMmiPoua1qXTMRi/9S+3kNFYO4IL/sFFiiqY6XVcW6xIUzp3rLwEjcHC/deszP7 /e8IqLUFAqj853W0k7qyLMRFEQVBzrABgtiSX+X06sCB8OmAVxhpevSRR1lmmfEu sjwuAvxexVlmojwI6HkoANyRzqJRX6y7sMGSbr10I/T9YJTk4VPfeFwSS3qBsf15 z9gTbvFrRcXKoA9U8iG45K0lUinka9OuGxJD/AxuJv+ncyJjWqX+aokvzeo7Wmv6 sbAyD+ikl9kxvE+sZ3l9yZEVHjFIbjmZY/gzG+ZZD2EEwKBuaQBN5mmSjrUkySJk sbF+oBABLptitJIa/cZJ5QHeAPR1NBqSXKhnhG26IR8iwQqpZhefa8yXpF/x3Tn8 FckvY+YpIakOAMQ/ezVvFaaEELieiRZqqI/ShrochJzwRXHnnbCTPRtNb9NyjOeU DZCBASPhrYfBJz3n0fZR2HCnpMZwCSGBgmVn3jmh3YyxKnILdQ4DxKgJCv730jwh 9T1+1g2/MW554Gted7KLlkE+aj+BzORx6XJ9H8SKmYB85NF5KnnJMiVktjfl4Jr4 A8meV9KGwAcyBOU= =8HBN -----END PGP SIGNATURE----- Merge tag 'audit-pr-20190702' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit Pull audit updates from Paul Moore: "This pull request is a bit early, but with some vacation time coming up I wanted to send this out now just in case the remote Internet Gods decide not to smile on me once the merge window opens. The patchset for v5.3 is pretty minor this time, the highlights include: - When the audit daemon is sent a signal, ensure we deliver information about the sender even when syscall auditing is not enabled/supported. - Add the ability to filter audit records based on network address family. - Tighten the audit field filtering restrictions on string based fields. - Cleanup the audit field filtering verification code. - Remove a few BUG() calls from the audit code" * tag 'audit-pr-20190702' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: remove the BUG() calls in the audit rule comparison functions audit: enforce op for string fields audit: add saddr_fam filter field audit: re-structure audit field valid checks audit: deliver signal_info regarless of syscall
This commit is contained in:
commit
61fc5771f5
|
@ -182,6 +182,9 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
|
|||
}
|
||||
|
||||
extern u32 audit_enabled;
|
||||
|
||||
extern int audit_signal_info(int sig, struct task_struct *t);
|
||||
|
||||
#else /* CONFIG_AUDIT */
|
||||
static inline __printf(4, 5)
|
||||
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
|
||||
|
@ -235,6 +238,12 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
|
|||
}
|
||||
|
||||
#define audit_enabled AUDIT_OFF
|
||||
|
||||
static inline int audit_signal_info(int sig, struct task_struct *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_AUDIT */
|
||||
|
||||
#ifdef CONFIG_AUDIT_COMPAT_GENERIC
|
||||
|
|
|
@ -281,6 +281,7 @@
|
|||
#define AUDIT_OBJ_GID 110
|
||||
#define AUDIT_FIELD_COMPARE 111
|
||||
#define AUDIT_EXE 112
|
||||
#define AUDIT_SADDR_FAM 113
|
||||
|
||||
#define AUDIT_ARG0 200
|
||||
#define AUDIT_ARG1 (AUDIT_ARG0+1)
|
||||
|
|
|
@ -2260,6 +2260,33 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* audit_signal_info - record signal info for shutting down audit subsystem
|
||||
* @sig: signal value
|
||||
* @t: task being signaled
|
||||
*
|
||||
* If the audit subsystem is being terminated, record the task (pid)
|
||||
* and uid that is doing that.
|
||||
*/
|
||||
int audit_signal_info(int sig, struct task_struct *t)
|
||||
{
|
||||
kuid_t uid = current_uid(), auid;
|
||||
|
||||
if (auditd_test_task(t) &&
|
||||
(sig == SIGTERM || sig == SIGHUP ||
|
||||
sig == SIGUSR1 || sig == SIGUSR2)) {
|
||||
audit_sig_pid = task_tgid_nr(current);
|
||||
auid = audit_get_loginuid(current);
|
||||
if (uid_valid(auid))
|
||||
audit_sig_uid = auid;
|
||||
else
|
||||
audit_sig_uid = uid;
|
||||
security_task_getsecid(current, &audit_sig_sid);
|
||||
}
|
||||
|
||||
return audit_signal_info_syscall(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* audit_log_end - end one audit record
|
||||
* @ab: the audit_buffer
|
||||
|
|
|
@ -286,7 +286,7 @@ extern const char *audit_tree_path(struct audit_tree *tree);
|
|||
extern void audit_put_tree(struct audit_tree *tree);
|
||||
extern void audit_kill_trees(struct audit_context *context);
|
||||
|
||||
extern int audit_signal_info(int sig, struct task_struct *t);
|
||||
extern int audit_signal_info_syscall(struct task_struct *t);
|
||||
extern void audit_filter_inodes(struct task_struct *tsk,
|
||||
struct audit_context *ctx);
|
||||
extern struct list_head *audit_killed_trees(void);
|
||||
|
@ -317,7 +317,11 @@ extern struct list_head *audit_killed_trees(void);
|
|||
#define audit_tree_path(rule) "" /* never called */
|
||||
#define audit_kill_trees(context) BUG()
|
||||
|
||||
#define audit_signal_info(s, t) AUDIT_DISABLED
|
||||
static inline int audit_signal_info_syscall(struct task_struct *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define audit_filter_inodes(t, c) AUDIT_DISABLED
|
||||
#endif /* CONFIG_AUDITSYSCALL */
|
||||
|
||||
|
|
|
@ -345,9 +345,16 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
|
|||
}
|
||||
}
|
||||
|
||||
/* Check for valid field type and op */
|
||||
switch (f->type) {
|
||||
default:
|
||||
return -EINVAL;
|
||||
case AUDIT_ARG0:
|
||||
case AUDIT_ARG1:
|
||||
case AUDIT_ARG2:
|
||||
case AUDIT_ARG3:
|
||||
case AUDIT_PERS: /* <uapi/linux/personality.h> */
|
||||
case AUDIT_DEVMINOR:
|
||||
/* all ops are valid */
|
||||
break;
|
||||
case AUDIT_UID:
|
||||
case AUDIT_EUID:
|
||||
case AUDIT_SUID:
|
||||
|
@ -360,46 +367,53 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
|
|||
case AUDIT_FSGID:
|
||||
case AUDIT_OBJ_GID:
|
||||
case AUDIT_PID:
|
||||
case AUDIT_PERS:
|
||||
case AUDIT_MSGTYPE:
|
||||
case AUDIT_PPID:
|
||||
case AUDIT_DEVMAJOR:
|
||||
case AUDIT_DEVMINOR:
|
||||
case AUDIT_EXIT:
|
||||
case AUDIT_SUCCESS:
|
||||
case AUDIT_INODE:
|
||||
case AUDIT_SESSIONID:
|
||||
case AUDIT_SUBJ_SEN:
|
||||
case AUDIT_SUBJ_CLR:
|
||||
case AUDIT_OBJ_LEV_LOW:
|
||||
case AUDIT_OBJ_LEV_HIGH:
|
||||
case AUDIT_SADDR_FAM:
|
||||
/* bit ops are only useful on syscall args */
|
||||
if (f->op == Audit_bitmask || f->op == Audit_bittest)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case AUDIT_ARG0:
|
||||
case AUDIT_ARG1:
|
||||
case AUDIT_ARG2:
|
||||
case AUDIT_ARG3:
|
||||
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:
|
||||
case AUDIT_WATCH:
|
||||
case AUDIT_DIR:
|
||||
case AUDIT_FILTERKEY:
|
||||
break;
|
||||
case AUDIT_LOGINUID_SET:
|
||||
if ((f->val != 0) && (f->val != 1))
|
||||
return -EINVAL;
|
||||
/* FALL THROUGH */
|
||||
case AUDIT_ARCH:
|
||||
case AUDIT_FSTYPE:
|
||||
case AUDIT_PERM:
|
||||
case AUDIT_FILETYPE:
|
||||
case AUDIT_FIELD_COMPARE:
|
||||
case AUDIT_EXE:
|
||||
/* only equal and not equal valid ops */
|
||||
if (f->op != Audit_not_equal && f->op != Audit_equal)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
/* field not recognized */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check for select valid field values */
|
||||
switch (f->type) {
|
||||
case AUDIT_LOGINUID_SET:
|
||||
if ((f->val != 0) && (f->val != 1))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case AUDIT_PERM:
|
||||
if (f->val & ~15)
|
||||
return -EINVAL;
|
||||
|
@ -412,11 +426,14 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
|
|||
if (f->val > AUDIT_MAX_FIELD_COMPARE)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case AUDIT_EXE:
|
||||
if (f->op != Audit_not_equal && f->op != Audit_equal)
|
||||
case AUDIT_SADDR_FAM:
|
||||
if (f->val >= AF_MAX)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1190,7 +1207,6 @@ int audit_comparator(u32 left, u32 op, u32 right)
|
|||
case Audit_bittest:
|
||||
return ((left & right) == right);
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1213,7 +1229,6 @@ int audit_uid_comparator(kuid_t left, u32 op, kuid_t right)
|
|||
case Audit_bitmask:
|
||||
case Audit_bittest:
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1236,7 +1251,6 @@ int audit_gid_comparator(kgid_t left, u32 op, kgid_t right)
|
|||
case Audit_bitmask:
|
||||
case Audit_bittest:
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -601,12 +601,20 @@ static int audit_filter_rules(struct task_struct *tsk,
|
|||
}
|
||||
break;
|
||||
case AUDIT_WATCH:
|
||||
if (name)
|
||||
result = audit_watch_compare(rule->watch, name->ino, name->dev);
|
||||
if (name) {
|
||||
result = audit_watch_compare(rule->watch,
|
||||
name->ino,
|
||||
name->dev);
|
||||
if (f->op == Audit_not_equal)
|
||||
result = !result;
|
||||
}
|
||||
break;
|
||||
case AUDIT_DIR:
|
||||
if (ctx)
|
||||
if (ctx) {
|
||||
result = match_tree_refs(ctx, rule->tree);
|
||||
if (f->op == Audit_not_equal)
|
||||
result = !result;
|
||||
}
|
||||
break;
|
||||
case AUDIT_LOGINUID:
|
||||
result = audit_uid_comparator(audit_get_loginuid(tsk),
|
||||
|
@ -615,6 +623,11 @@ static int audit_filter_rules(struct task_struct *tsk,
|
|||
case AUDIT_LOGINUID_SET:
|
||||
result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
|
||||
break;
|
||||
case AUDIT_SADDR_FAM:
|
||||
if (ctx->sockaddr)
|
||||
result = audit_comparator(ctx->sockaddr->ss_family,
|
||||
f->op, f->val);
|
||||
break;
|
||||
case AUDIT_SUBJ_USER:
|
||||
case AUDIT_SUBJ_ROLE:
|
||||
case AUDIT_SUBJ_TYPE:
|
||||
|
@ -684,9 +697,13 @@ static int audit_filter_rules(struct task_struct *tsk,
|
|||
break;
|
||||
case AUDIT_PERM:
|
||||
result = audit_match_perm(ctx, f->val);
|
||||
if (f->op == Audit_not_equal)
|
||||
result = !result;
|
||||
break;
|
||||
case AUDIT_FILETYPE:
|
||||
result = audit_match_filetype(ctx, f->val);
|
||||
if (f->op == Audit_not_equal)
|
||||
result = !result;
|
||||
break;
|
||||
case AUDIT_FIELD_COMPARE:
|
||||
result = audit_field_compare(tsk, cred, f, ctx, name);
|
||||
|
@ -2360,30 +2377,17 @@ void __audit_ptrace(struct task_struct *t)
|
|||
}
|
||||
|
||||
/**
|
||||
* audit_signal_info - record signal info for shutting down audit subsystem
|
||||
* @sig: signal value
|
||||
* audit_signal_info_syscall - record signal info for syscalls
|
||||
* @t: task being signaled
|
||||
*
|
||||
* If the audit subsystem is being terminated, record the task (pid)
|
||||
* and uid that is doing that.
|
||||
*/
|
||||
int audit_signal_info(int sig, struct task_struct *t)
|
||||
int audit_signal_info_syscall(struct task_struct *t)
|
||||
{
|
||||
struct audit_aux_data_pids *axp;
|
||||
struct audit_context *ctx = audit_context();
|
||||
kuid_t uid = current_uid(), auid, t_uid = task_uid(t);
|
||||
|
||||
if (auditd_test_task(t) &&
|
||||
(sig == SIGTERM || sig == SIGHUP ||
|
||||
sig == SIGUSR1 || sig == SIGUSR2)) {
|
||||
audit_sig_pid = task_tgid_nr(current);
|
||||
auid = audit_get_loginuid(current);
|
||||
if (uid_valid(auid))
|
||||
audit_sig_uid = auid;
|
||||
else
|
||||
audit_sig_uid = uid;
|
||||
security_task_getsecid(current, &audit_sig_sid);
|
||||
}
|
||||
kuid_t t_uid = task_uid(t);
|
||||
|
||||
if (!audit_signals || audit_dummy_context())
|
||||
return 0;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <linux/posix-timers.h>
|
||||
#include <linux/livepatch.h>
|
||||
#include <linux/cgroup.h>
|
||||
#include <linux/audit.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/signal.h>
|
||||
|
@ -54,7 +55,6 @@
|
|||
#include <asm/unistd.h>
|
||||
#include <asm/siginfo.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include "audit.h" /* audit_signal_info() */
|
||||
|
||||
/*
|
||||
* SLAB caches for signal bits.
|
||||
|
|
Loading…
Reference in New Issue