forked from Minki/linux
audit/stable-4.18 PR 20180814
-----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEEcQCq365ubpQNLgrWVeRaWujKfIoFAltzOI8UHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQVeRaWujKfIqvOw/9F48G0G87ETN2M1O3fFLpANd2GtPH cYtg6SG8b3nZzkllUBOVZjoj7y0OyTgi+ksm5XSmgcR4npELDHWRhXaCma1s8Hxw Zpk2SWrEmwdudec9zZ8sBtvd6t63P9TkVSk3S4z+1HgH6uzPg6lMes4w/cQIdn0e uEIiuNkOOHXxWLxgphxPJ/XffQCfV6ltm9j41Z2S6RZHe/0UsJSKCwD+LwW+jLe3 0e9oUPWVnxZlhpJoctWpgtaYmG8rtqxfXruFwg2mR5d2VBs966h3FCz9b9qhtA+R HPy/KagJuUFRL+6ZlpX1dtkkNi07LKjsx3OJYBNHNKmYDA5yJF3X/mMV4uMkroFz q8k88Wi1dYWKJvLhAGALRGSbiYljLgDFJH31tN2FWHb93+l3CXLhjmwIyUxrtiW1 DfUJYM8/ZzMjghpb6YoHi1Dq+Z1cG07S1Eo0pTmtxVT2g43eXSL4OvxFhJKkCFv9 n1J/fo6JVw9i+4DqWkk+8NFGXYYZFlfrGl14szTp+8Q9Gw6OlWWcnF/o3+KCtPez 5z5+E64pAHhLa9/gaHu62eK4lIpiXv3IE8fA7OvFxrUpSJbtYc0RnGv8eKhO8J6v Q9TQKJGbbOLwP+mF/8sPexsREDaU3fB68dTj/FF5AHLH8KFUgAQYcm0bIzpNDBSd w+REW+TTiht8W6E= =tnPz -----END PGP SIGNATURE----- Merge tag 'audit-pr-20180814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit Pull audit patches from Paul Moore: "Twelve audit patches for v4.19 and they run the full gamut from fixes to features. Notable changes include the ability to use the "exe" audit filter field in a wider variety of filter types, a fix for our comparison of GID/EGID in audit filter rules, better association of related audit records (connecting related audit records together into one audit event), and a fix for a potential use-after-free in audit_add_watch(). All the patches pass the audit-testsuite and merge cleanly on your current master branch" * tag 'audit-pr-20180814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: fix use-after-free in audit_add_watch audit: use ktime_get_coarse_real_ts64() for timestamps audit: use ktime_get_coarse_ts64() for time access audit: simplify audit_enabled check in audit_watch_log_rule_change() audit: check audit_enabled in audit_tree_log_remove_rule() cred: conditionally declare groups-related functions audit: eliminate audit_enabled magic number comparison audit: rename FILTER_TYPE to FILTER_EXCLUDE audit: Fix extended comparison of GID/EGID audit: tie ANOM_ABEND records to syscall audit: tie SECCOMP records to syscall audit: allow other filter list types for AUDIT_EXE
This commit is contained in:
commit
8c32685030
@ -92,7 +92,7 @@ static void tty_audit_buf_push(struct tty_audit_buf *buf)
|
||||
{
|
||||
if (buf->valid == 0)
|
||||
return;
|
||||
if (audit_enabled == 0) {
|
||||
if (audit_enabled == AUDIT_OFF) {
|
||||
buf->valid = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -117,6 +117,9 @@ struct filename;
|
||||
|
||||
extern void audit_log_session_info(struct audit_buffer *ab);
|
||||
|
||||
#define AUDIT_OFF 0
|
||||
#define AUDIT_ON 1
|
||||
#define AUDIT_LOCKED 2
|
||||
#ifdef CONFIG_AUDIT
|
||||
/* These are defined in audit.c */
|
||||
/* Public API */
|
||||
@ -202,7 +205,7 @@ static inline int audit_log_task_context(struct audit_buffer *ab)
|
||||
static inline void audit_log_task_info(struct audit_buffer *ab,
|
||||
struct task_struct *tsk)
|
||||
{ }
|
||||
#define audit_enabled 0
|
||||
#define audit_enabled AUDIT_OFF
|
||||
#endif /* CONFIG_AUDIT */
|
||||
|
||||
#ifdef CONFIG_AUDIT_COMPAT_GENERIC
|
||||
|
@ -65,6 +65,12 @@ extern void groups_free(struct group_info *);
|
||||
|
||||
extern int in_group_p(kgid_t);
|
||||
extern int in_egroup_p(kgid_t);
|
||||
extern int groups_search(const struct group_info *, kgid_t);
|
||||
|
||||
extern int set_current_groups(struct group_info *);
|
||||
extern void set_groups(struct cred *, struct group_info *);
|
||||
extern bool may_setgroups(void);
|
||||
extern void groups_sort(struct group_info *);
|
||||
#else
|
||||
static inline void groups_free(struct group_info *group_info)
|
||||
{
|
||||
@ -78,12 +84,11 @@ static inline int in_egroup_p(kgid_t grp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static inline int groups_search(const struct group_info *group_info, kgid_t grp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
extern int set_current_groups(struct group_info *);
|
||||
extern void set_groups(struct cred *, struct group_info *);
|
||||
extern int groups_search(const struct group_info *, kgid_t);
|
||||
extern bool may_setgroups(void);
|
||||
extern void groups_sort(struct group_info *);
|
||||
|
||||
/*
|
||||
* The security context of a task
|
||||
|
@ -735,7 +735,7 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op)
|
||||
{
|
||||
struct audit_buffer *audit_buf = NULL;
|
||||
|
||||
if (audit_enabled == 0)
|
||||
if (audit_enabled == AUDIT_OFF)
|
||||
return NULL;
|
||||
audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
|
||||
AUDIT_MAC_IPSEC_EVENT);
|
||||
|
@ -157,7 +157,8 @@
|
||||
#define AUDIT_FILTER_ENTRY 0x02 /* Apply rule at syscall entry */
|
||||
#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
|
||||
#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
|
||||
#define AUDIT_FILTER_TYPE 0x05 /* Apply rule at audit_log_start */
|
||||
#define AUDIT_FILTER_EXCLUDE 0x05 /* Apply rule before record creation */
|
||||
#define AUDIT_FILTER_TYPE AUDIT_FILTER_EXCLUDE /* obsolete misleading naming */
|
||||
#define AUDIT_FILTER_FS 0x06 /* Apply rule at __audit_inode_child */
|
||||
|
||||
#define AUDIT_NR_FILTERS 7
|
||||
|
@ -83,9 +83,6 @@
|
||||
#define AUDIT_INITIALIZED 1
|
||||
static int audit_initialized;
|
||||
|
||||
#define AUDIT_OFF 0
|
||||
#define AUDIT_ON 1
|
||||
#define AUDIT_LOCKED 2
|
||||
u32 audit_enabled = AUDIT_OFF;
|
||||
bool audit_ever_enabled = !!AUDIT_OFF;
|
||||
|
||||
@ -1724,7 +1721,7 @@ static inline void audit_get_stamp(struct audit_context *ctx,
|
||||
struct timespec64 *t, unsigned int *serial)
|
||||
{
|
||||
if (!ctx || !auditsc_get_stamp(ctx, t, serial)) {
|
||||
*t = current_kernel_time64();
|
||||
ktime_get_coarse_real_ts64(t);
|
||||
*serial = audit_serial();
|
||||
}
|
||||
}
|
||||
@ -1754,7 +1751,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
|
||||
if (audit_initialized != AUDIT_INITIALIZED)
|
||||
return NULL;
|
||||
|
||||
if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
|
||||
if (unlikely(!audit_filter(type, AUDIT_FILTER_EXCLUDE)))
|
||||
return NULL;
|
||||
|
||||
/* NOTE: don't ever fail/sleep on these two conditions:
|
||||
|
@ -497,6 +497,8 @@ static void audit_tree_log_remove_rule(struct audit_krule *rule)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
|
||||
if (!audit_enabled)
|
||||
return;
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||
if (unlikely(!ab))
|
||||
return;
|
||||
|
@ -238,20 +238,21 @@ out:
|
||||
|
||||
static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watch *w, char *op)
|
||||
{
|
||||
if (audit_enabled) {
|
||||
struct audit_buffer *ab;
|
||||
ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
|
||||
if (unlikely(!ab))
|
||||
return;
|
||||
audit_log_format(ab, "auid=%u ses=%u op=%s",
|
||||
from_kuid(&init_user_ns, audit_get_loginuid(current)),
|
||||
audit_get_sessionid(current), op);
|
||||
audit_log_format(ab, " path=");
|
||||
audit_log_untrustedstring(ab, w->path);
|
||||
audit_log_key(ab, r->filterkey);
|
||||
audit_log_format(ab, " list=%d res=1", r->listnr);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
struct audit_buffer *ab;
|
||||
|
||||
if (!audit_enabled)
|
||||
return;
|
||||
ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
|
||||
if (!ab)
|
||||
return;
|
||||
audit_log_format(ab, "auid=%u ses=%u op=%s",
|
||||
from_kuid(&init_user_ns, audit_get_loginuid(current)),
|
||||
audit_get_sessionid(current), op);
|
||||
audit_log_format(ab, " path=");
|
||||
audit_log_untrustedstring(ab, w->path);
|
||||
audit_log_key(ab, r->filterkey);
|
||||
audit_log_format(ab, " list=%d res=1", r->listnr);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
|
||||
/* Update inode info in audit rules based on filesystem event. */
|
||||
@ -419,6 +420,13 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list)
|
||||
struct path parent_path;
|
||||
int h, ret = 0;
|
||||
|
||||
/*
|
||||
* When we will be calling audit_add_to_parent, krule->watch might have
|
||||
* been updated and watch might have been freed.
|
||||
* So we need to keep a reference of watch.
|
||||
*/
|
||||
audit_get_watch(watch);
|
||||
|
||||
mutex_unlock(&audit_filter_mutex);
|
||||
|
||||
/* Avoid calling path_lookup under audit_filter_mutex. */
|
||||
@ -427,8 +435,10 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list)
|
||||
/* caller expects mutex locked */
|
||||
mutex_lock(&audit_filter_mutex);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
audit_put_watch(watch);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* either find an old parent or attach a new one */
|
||||
parent = audit_find_parent(d_backing_inode(parent_path.dentry));
|
||||
@ -446,6 +456,7 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list)
|
||||
*list = &audit_inode_hash[h];
|
||||
error:
|
||||
path_put(&parent_path);
|
||||
audit_put_watch(watch);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule_data *
|
||||
case AUDIT_FILTER_TASK:
|
||||
#endif
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
case AUDIT_FILTER_EXCLUDE:
|
||||
case AUDIT_FILTER_FS:
|
||||
;
|
||||
}
|
||||
@ -337,7 +337,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
|
||||
{
|
||||
switch(f->type) {
|
||||
case AUDIT_MSGTYPE:
|
||||
if (entry->rule.listnr != AUDIT_FILTER_TYPE &&
|
||||
if (entry->rule.listnr != AUDIT_FILTER_EXCLUDE &&
|
||||
entry->rule.listnr != AUDIT_FILTER_USER)
|
||||
return -EINVAL;
|
||||
break;
|
||||
@ -428,8 +428,6 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
|
||||
case AUDIT_EXE:
|
||||
if (f->op != Audit_not_equal && f->op != Audit_equal)
|
||||
return -EINVAL;
|
||||
if (entry->rule.listnr != AUDIT_FILTER_EXIT)
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -931,7 +929,7 @@ static inline int audit_add_rule(struct audit_entry *entry)
|
||||
/* If any of these, don't count towards total */
|
||||
switch(entry->rule.listnr) {
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
case AUDIT_FILTER_EXCLUDE:
|
||||
case AUDIT_FILTER_FS:
|
||||
dont_count = 1;
|
||||
}
|
||||
@ -1013,7 +1011,7 @@ int audit_del_rule(struct audit_entry *entry)
|
||||
/* If any of these, don't count towards total */
|
||||
switch(entry->rule.listnr) {
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
case AUDIT_FILTER_EXCLUDE:
|
||||
case AUDIT_FILTER_FS:
|
||||
dont_count = 1;
|
||||
}
|
||||
@ -1360,6 +1358,11 @@ int audit_filter(int msgtype, unsigned int listtype)
|
||||
f->type, f->op, f->lsm_rule, NULL);
|
||||
}
|
||||
break;
|
||||
case AUDIT_EXE:
|
||||
result = audit_exe_compare(current, e->rule.exe);
|
||||
if (f->op == Audit_not_equal)
|
||||
result = !result;
|
||||
break;
|
||||
default:
|
||||
goto unlock_and_return;
|
||||
}
|
||||
@ -1369,7 +1372,7 @@ int audit_filter(int msgtype, unsigned int listtype)
|
||||
break;
|
||||
}
|
||||
if (result > 0) {
|
||||
if (e->rule.action == AUDIT_NEVER || listtype == AUDIT_FILTER_TYPE)
|
||||
if (e->rule.action == AUDIT_NEVER || listtype == AUDIT_FILTER_EXCLUDE)
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -494,20 +494,20 @@ static int audit_filter_rules(struct task_struct *tsk,
|
||||
result = audit_gid_comparator(cred->gid, f->op, f->gid);
|
||||
if (f->op == Audit_equal) {
|
||||
if (!result)
|
||||
result = in_group_p(f->gid);
|
||||
result = groups_search(cred->group_info, f->gid);
|
||||
} else if (f->op == Audit_not_equal) {
|
||||
if (result)
|
||||
result = !in_group_p(f->gid);
|
||||
result = !groups_search(cred->group_info, f->gid);
|
||||
}
|
||||
break;
|
||||
case AUDIT_EGID:
|
||||
result = audit_gid_comparator(cred->egid, f->op, f->gid);
|
||||
if (f->op == Audit_equal) {
|
||||
if (!result)
|
||||
result = in_egroup_p(f->gid);
|
||||
result = groups_search(cred->group_info, f->gid);
|
||||
} else if (f->op == Audit_not_equal) {
|
||||
if (result)
|
||||
result = !in_egroup_p(f->gid);
|
||||
result = !groups_search(cred->group_info, f->gid);
|
||||
}
|
||||
break;
|
||||
case AUDIT_SGID:
|
||||
@ -1544,10 +1544,10 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
|
||||
context->argv[2] = a3;
|
||||
context->argv[3] = a4;
|
||||
context->serial = 0;
|
||||
context->ctime = current_kernel_time64();
|
||||
context->in_syscall = 1;
|
||||
context->current_state = state;
|
||||
context->ppid = 0;
|
||||
ktime_get_coarse_real_ts64(&context->ctime);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2466,7 +2466,7 @@ void audit_core_dumps(long signr)
|
||||
if (signr == SIGQUIT) /* don't care for those */
|
||||
return;
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
|
||||
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_ABEND);
|
||||
if (unlikely(!ab))
|
||||
return;
|
||||
audit_log_task(ab);
|
||||
@ -2490,7 +2490,7 @@ void audit_seccomp(unsigned long syscall, long signr, int code)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP);
|
||||
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_SECCOMP);
|
||||
if (unlikely(!ab))
|
||||
return;
|
||||
audit_log_task(ab);
|
||||
|
@ -72,7 +72,7 @@ audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
struct audit_buffer *ab;
|
||||
int fam = -1;
|
||||
|
||||
if (audit_enabled == 0)
|
||||
if (audit_enabled == AUDIT_OFF)
|
||||
goto errout;
|
||||
ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
|
||||
if (ab == NULL)
|
||||
|
@ -101,7 +101,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,
|
||||
char *secctx;
|
||||
u32 secctx_len;
|
||||
|
||||
if (audit_enabled == 0)
|
||||
if (audit_enabled == AUDIT_OFF)
|
||||
return NULL;
|
||||
|
||||
audit_buf = audit_log_start(audit_context(), GFP_ATOMIC, type);
|
||||
|
Loading…
Reference in New Issue
Block a user