[PATCH v3] audit: log AUDIT_TIME_* records only from rules
by Richard Guy Briggs
AUDIT_TIME_* events are generated when there are syscall rules present that are
not related to time keeping. This will produce noisy log entries that could
flood the logs and hide events we really care about.
Rather than immediately produce the AUDIT_TIME_* records, store the data in the
context and log it at syscall exit time respecting the filter rules.
Please see https://bugzilla.redhat.com/show_bug.cgi?id=1991919
Fixes: 7e8eda734d30 ("ntp: Audit NTP parameters adjustment")
Fixes: 2d87a0674bd6 ("timekeeping: Audit clock adjustments")
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v2:
- rename __audit_ntp_log_ to audit_log_ntp
- pre-check ntp before storing
- move tk out of the context union and move ntp logging to the bottom of audit_show_special()
- restructure logging of ntp to use ab and allocate more only if more
- add Fixes lines
v3
- move tk into union
- rename audit_log_ntp() to audit_log_time() and add tk
- key off both AUDIT_TIME_* but favour NTP
kernel/audit.h | 4 +++
kernel/auditsc.c | 86 +++++++++++++++++++++++++++++++++++++-----------
2 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index c4498090a5bd..58b66543b4d5 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -201,6 +201,10 @@ struct audit_context {
struct {
char *name;
} module;
+ struct {
+ struct audit_ntp_data ntp_data;
+ struct timespec64 tk_injoffset;
+ } time;
};
int fds[2];
struct audit_proctitle proctitle;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index b517947bfa48..9c6c55a81fdb 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1331,6 +1331,55 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
from_kuid(&init_user_ns, name->fcap.rootid));
}
+void audit_log_time(struct audit_context *context, struct audit_buffer **ab)
+{
+ const struct audit_ntp_data *ntp = &context->time.ntp_data;
+ const struct timespec64 *tk = &context->time.tk_injoffset;
+ const char *ntp_name[] = {
+ "offset",
+ "freq",
+ "status",
+ "tai",
+ "tick",
+ "adjust",
+ };
+ int type, first = 1;
+
+ if (context->type == AUDIT_TIME_INJOFFSET)
+ goto tk;
+
+ /* use up allocated ab from show_special before new one */
+ for (type = 0; type < AUDIT_NTP_NVALS; type++) {
+ if (ntp->vals[type].newval != ntp->vals[type].oldval) {
+ if (first) {
+ first = 0;
+ } else {
+ audit_log_end(*ab);
+ *ab = audit_log_start(context, GFP_KERNEL,
+ AUDIT_TIME_ADJNTPVAL);
+ if (!*ab)
+ return;
+ }
+ audit_log_format(*ab, "op=%s old=%lli new=%lli",
+ ntp_name[type], ntp->vals[type].oldval,
+ ntp->vals[type].newval);
+ }
+ }
+
+tk:
+ if (tk->tv_sec != 0 || tk->tv_nsec != 0) {
+ if (!first) {
+ audit_log_end(*ab);
+ *ab = audit_log_start(context, GFP_KERNEL,
+ AUDIT_TIME_INJOFFSET);
+ if (!*ab)
+ return;
+ }
+ audit_log_format(*ab, "sec=%lli nsec=%li",
+ (long long)tk->tv_sec, tk->tv_nsec);
+ }
+}
+
static void show_special(struct audit_context *context, int *call_panic)
{
struct audit_buffer *ab;
@@ -1445,6 +1494,10 @@ static void show_special(struct audit_context *context, int *call_panic)
audit_log_format(ab, "(null)");
break;
+ case AUDIT_TIME_ADJNTPVAL:
+ case AUDIT_TIME_INJOFFSET:
+ audit_log_time(context, &ab);
+ break;
}
audit_log_end(ab);
}
@@ -2840,31 +2893,24 @@ void __audit_fanotify(unsigned int response)
void __audit_tk_injoffset(struct timespec64 offset)
{
- audit_log(audit_context(), GFP_KERNEL, AUDIT_TIME_INJOFFSET,
- "sec=%lli nsec=%li",
- (long long)offset.tv_sec, offset.tv_nsec);
-}
-
-static void audit_log_ntp_val(const struct audit_ntp_data *ad,
- const char *op, enum audit_ntp_type type)
-{
- const struct audit_ntp_val *val = &ad->vals[type];
-
- if (val->newval == val->oldval)
- return;
+ struct audit_context *context = audit_context();
- audit_log(audit_context(), GFP_KERNEL, AUDIT_TIME_ADJNTPVAL,
- "op=%s old=%lli new=%lli", op, val->oldval, val->newval);
+ if (!context->type)
+ context->type = AUDIT_TIME_INJOFFSET;
+ memcpy(&context->time.tk_injoffset, &offset, sizeof(offset));
}
void __audit_ntp_log(const struct audit_ntp_data *ad)
{
- audit_log_ntp_val(ad, "offset", AUDIT_NTP_OFFSET);
- audit_log_ntp_val(ad, "freq", AUDIT_NTP_FREQ);
- audit_log_ntp_val(ad, "status", AUDIT_NTP_STATUS);
- audit_log_ntp_val(ad, "tai", AUDIT_NTP_TAI);
- audit_log_ntp_val(ad, "tick", AUDIT_NTP_TICK);
- audit_log_ntp_val(ad, "adjust", AUDIT_NTP_ADJUST);
+ struct audit_context *context = audit_context();
+ int type;
+
+ for (type = 0; type < AUDIT_NTP_NVALS; type++)
+ if (ad->vals[type].newval != ad->vals[type].oldval) {
+ context->type = AUDIT_TIME_ADJNTPVAL;
+ memcpy(&context->time.ntp_data, ad, sizeof(*ad));
+ break;
+ }
}
void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
--
2.27.0
2 years, 8 months
[PATCH v4 0/3] audit: add support for openat2
by Richard Guy Briggs
The openat2(2) syscall was added in v5.6. Add support for openat2 to the
audit syscall classifier and for recording openat2 parameters that cannot
be captured in the syscall parameters of the SYSCALL record.
Supporting userspace code can be found in
https://github.com/rgbriggs/audit-userspace/tree/ghau-openat2
Supporting test case can be found in
https://github.com/linux-audit/audit-testsuite/pull/103
Changelog:
v4:
- change filename include/linux/auditscm.h to auditsc_classmacros.h to avoid socket association
v3:
- re-add commit descriptions that somehow got dropped
- add new file to MAINTAINERS
v2:
- add include/linux/auditscm.h for audit syscall class macros due to syscall redefinition warnings:
arch/x86/ia32/audit.c:3:
./include/linux/audit.h:12,
./include/linux/sched.h:22,
./include/linux/seccomp.h:21,
./arch/x86/include/asm/seccomp.h:5,
./arch/x86/include/asm/unistd.h:20,
./arch/x86/include/generated/uapi/asm/unistd_64.h:4: warning: "__NR_read" redefined #define __NR_read 0
...
./arch/x86/include/generated/uapi/asm/unistd_64.h:338: warning: "__NR_rseq" redefined #define __NR_rseq 334
previous:
arch/x86/ia32/audit.c:2:
./arch/x86/include/generated/uapi/asm/unistd_32.h:7: note: this is the location of the previous definition #define __NR_read 3
...
./arch/x86/include/generated/uapi/asm/unistd_32.h:386: note: this is the location of the previous definition #define __NR_rseq 386
Richard Guy Briggs (3):
audit: replace magic audit syscall class numbers with macros
audit: add support for the openat2 syscall
audit: add OPENAT2 record to list how
MAINTAINERS | 1 +
arch/alpha/kernel/audit.c | 10 ++++++----
arch/ia64/kernel/audit.c | 10 ++++++----
arch/parisc/kernel/audit.c | 10 ++++++----
arch/parisc/kernel/compat_audit.c | 11 ++++++----
arch/powerpc/kernel/audit.c | 12 ++++++-----
arch/powerpc/kernel/compat_audit.c | 13 +++++++-----
arch/s390/kernel/audit.c | 12 ++++++-----
arch/s390/kernel/compat_audit.c | 13 +++++++-----
arch/sparc/kernel/audit.c | 12 ++++++-----
arch/sparc/kernel/compat_audit.c | 13 +++++++-----
arch/x86/ia32/audit.c | 13 +++++++-----
arch/x86/kernel/audit_64.c | 10 ++++++----
fs/open.c | 2 ++
include/linux/audit.h | 11 ++++++++++
include/linux/auditsc_classmacros.h | 24 ++++++++++++++++++++++
include/uapi/linux/audit.h | 1 +
kernel/audit.h | 2 ++
kernel/auditsc.c | 31 +++++++++++++++++++++++------
lib/audit.c | 14 ++++++++-----
lib/compat_audit.c | 15 +++++++++-----
21 files changed, 169 insertions(+), 71 deletions(-)
create mode 100644 include/linux/auditsc_classmacros.h
--
2.27.0
2 years, 8 months
Re: [PATCH 1/1] Smack:- Fix the issue of wrong info printed in ptrace error logs
by Casey Schaufler
On 12/20/2021 2:13 AM, Vishal Goel wrote:
> Currently tracer process info is printed in object field in
> smack error log for ptrace check which is wrong.
> Object process should print the tracee process info.
> Tracee info is not printed in the smack error logs.
> So it is not possible to debug the ptrace smack issues.
>
> Now changes has been done to print both tracer and tracee
> process info in smack error logs for ptrace scenarios
>
> Old logs:-
> [ 378.098330] audit: type=1400 audit(1637212273.300:2): lsm=SMACK fn=smack_ptrace_access_check action=denied subject="Tracer_lbl" object="Tracee_lbl" requested= pid=9397 comm="tst_pt" opid=9397 ocomm="tst_pt"
> [ 520.261605] audit: type=1400 audit(1637212415.464:3): lsm=SMACK fn=smack_ptrace_traceme action=denied subject="Tracer_lbl" object="Tracee_lbl" requested= pid=12685 comm="tst_pt_me" opid=12563 ocomm="bash"
> [ 1445.259319] audit: type=1400 audit(1637213340.460:5): lsm=SMACK fn=smack_bprm_set_creds action=denied subject="Tracer_lbl" object="Tracee_lbl" requested= pid=1778 comm="tst_bprm" opid=1776 ocomm="tst_bprm"
>
> New logs:-
> [ 378.098330] audit: type=1400 audit(1637212273.300:2): lsm=SMACK fn=smack_ptrace_access_check action=denied subject="Tracer_lbl" object="Tracee_lbl" requested= tracer-pid=5189 tracer-comm="tst_pt" pid=5189 comm="tst_pt" tracee-pid=962 tracee-comm="test_tracee"
> [ 520.261605] audit: type=1400 audit(1637212415.464:3): lsm=SMACK fn=smack_ptrace_traceme action=denied subject="Tracer_lbl" object="Tracee_lbl" requested= tracer-pid=6161 tracer-comm="bash" pid=6310 comm="tst_pt_me" tracee-pid=6310 tracee-comm="tst_pt_me"
> [ 1445.259319] audit: type=1400 audit(1637213340.460:5): lsm=SMACK fn=smack_bprm_set_creds action=denied subject="Tracer_lbl" object="Tracee_lbl" requested= tracer-pid=6435 tracer-comm="tst_bprm" pid=6436 comm="tst_bprm" tracee-pid=6436 tracee-comm="tst_bprm"
>
> Signed-off-by: Vishal Goel <vishal.goel(a)samsung.com>
Does anyone from the audit side object to my taking this
in the Smack tree?
> ---
> include/linux/lsm_audit.h | 1 +
> security/lsm_audit.c | 15 +++++++++++++++
> security/smack/smack.h | 19 +++++++++++++++++++
> security/smack/smack_access.c | 16 ++++++++++++++++
> security/smack/smack_lsm.c | 33 ++++++++++++++++++++++-----------
> 5 files changed, 73 insertions(+), 11 deletions(-)
>
> diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
> index 17d02eda9..6d752ea16 100644
> --- a/include/linux/lsm_audit.h
> +++ b/include/linux/lsm_audit.h
> @@ -76,6 +76,7 @@ struct common_audit_data {
> #define LSM_AUDIT_DATA_IBENDPORT 14
> #define LSM_AUDIT_DATA_LOCKDOWN 15
> #define LSM_AUDIT_DATA_NOTIFICATION 16
> +#define LSM_AUDIT_DATA_PTRACE 17
> union {
> struct path path;
> struct dentry *dentry;
> diff --git a/security/lsm_audit.c b/security/lsm_audit.c
> index 1897cbf6f..069e0282c 100644
> --- a/security/lsm_audit.c
> +++ b/security/lsm_audit.c
> @@ -318,6 +318,21 @@ static void dump_common_audit_data(struct audit_buffer *ab,
> }
> break;
> }
> + case LSM_AUDIT_DATA_PTRACE: {
> + struct task_struct *tsk = a->u.tsk;
> + if (tsk) {
> + pid_t pid = task_tgid_nr(tsk);
> +
> + if (pid) {
> + char comm[sizeof(tsk->comm)];
> +
> + audit_log_format(ab, " tracee-pid=%d tracee-comm=", pid);
> + audit_log_untrustedstring(ab,
> + memcpy(comm, tsk->comm, sizeof(comm)));
> + }
> + }
> + break;
> + }
> case LSM_AUDIT_DATA_NET:
> if (a->u.net->sk) {
> const struct sock *sk = a->u.net->sk;
> diff --git a/security/smack/smack.h b/security/smack/smack.h
> index 99c342259..901228205 100644
> --- a/security/smack/smack.h
> +++ b/security/smack/smack.h
> @@ -266,6 +266,7 @@ struct smack_audit_data {
> char *object;
> char *request;
> int result;
> + struct task_struct *tracer_tsk;
> };
>
> /*
> @@ -497,6 +498,16 @@ static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
> {
> a->a.u.net->sk = sk;
> }
> +static inline void smk_ad_setfield_u_tracer(struct smk_audit_info *a,
> + struct task_struct *t)
> +{
> + a->a.smack_audit_data->tracer_tsk = t;
> +}
> +static inline void smk_ad_setfield_u_tracee(struct smk_audit_info *a,
> + struct task_struct *t)
> +{
> + a->a.u.tsk = t;
> +}
>
> #else /* no AUDIT */
>
> @@ -524,6 +535,14 @@ static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
> struct sock *sk)
> {
> }
> +static inline void smk_ad_setfield_u_tracer(struct smk_audit_info *a,
> + struct task_struct *t)
> +{
> +}
> +static inline void smk_ad_setfield_u_tracee(struct smk_audit_info *a,
> + struct task_struct *t)
> +{
> +}
> #endif
>
> #endif /* _SECURITY_SMACK_H */
> diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
> index d2186e275..f39e3ac92 100644
> --- a/security/smack/smack_access.c
> +++ b/security/smack/smack_access.c
> @@ -323,6 +323,22 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
> audit_log_format(ab, " labels_differ");
> else
> audit_log_format(ab, " requested=%s", sad->request);
> +
> + if (ad->type == LSM_AUDIT_DATA_PTRACE) {
> + struct task_struct *tsk = sad->tracer_tsk;
> +
> + if (tsk) {
> + pid_t pid = task_tgid_nr(tsk);
> +
> + if (pid) {
> + char comm[sizeof(tsk->comm)];
> +
> + audit_log_format(ab, " tracer-pid=%d tracer-comm=", pid);
> + audit_log_untrustedstring(ab,
> + memcpy(comm, tsk->comm, sizeof(comm)));
> + }
> + }
> + }
> }
>
> /**
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index efd35b07c..47e8a9461 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -416,20 +416,13 @@ static inline unsigned int smk_ptrace_mode(unsigned int mode)
> */
> static int smk_ptrace_rule_check(struct task_struct *tracer,
> struct smack_known *tracee_known,
> - unsigned int mode, const char *func)
> + unsigned int mode, struct smk_audit_info *saip)
> {
> int rc;
> - struct smk_audit_info ad, *saip = NULL;
> struct task_smack *tsp;
> struct smack_known *tracer_known;
> const struct cred *tracercred;
>
> - if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
> - smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
> - smk_ad_setfield_u_tsk(&ad, tracer);
> - saip = &ad;
> - }
> -
> rcu_read_lock();
> tracercred = __task_cred(tracer);
> tsp = smack_cred(tracercred);
> @@ -480,10 +473,17 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
> static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
> {
> struct smack_known *skp;
> + struct smk_audit_info ad, *saip = NULL;
>
> skp = smk_of_task_struct_obj(ctp);
> + if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
> + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PTRACE);
> + smk_ad_setfield_u_tracer(&ad, current);
> + smk_ad_setfield_u_tracee(&ad, ctp);
> + saip = &ad;
> + }
>
> - return smk_ptrace_rule_check(current, skp, mode, __func__);
> + return smk_ptrace_rule_check(current, skp, mode, saip);
> }
>
> /**
> @@ -498,10 +498,15 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
> {
> int rc;
> struct smack_known *skp;
> + struct smk_audit_info ad, *saip = NULL;
>
> skp = smk_of_task(smack_cred(current_cred()));
> + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PTRACE);
> + smk_ad_setfield_u_tracer(&ad, ptp);
> + smk_ad_setfield_u_tracee(&ad, current);
> + saip = &ad;
>
> - rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__);
> + rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, saip);
> return rc;
> }
>
> @@ -897,15 +902,21 @@ static int smack_bprm_creds_for_exec(struct linux_binprm *bprm)
>
> if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
> struct task_struct *tracer;
> + struct smk_audit_info ad, *saip = NULL;
> rc = 0;
>
> + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PTRACE);
> + smk_ad_setfield_u_tracee(&ad, current);
> + saip = &ad;
> +
> rcu_read_lock();
> tracer = ptrace_parent(current);
> + smk_ad_setfield_u_tracer(&ad, tracer);
> if (likely(tracer != NULL))
> rc = smk_ptrace_rule_check(tracer,
> isp->smk_task,
> PTRACE_MODE_ATTACH,
> - __func__);
> + saip);
> rcu_read_unlock();
>
> if (rc != 0)
2 years, 9 months
[GIT PULL] Audit fixes for v5.17 (#1)
by Paul Moore
Linus,
A single audit patch to fix problems relating to audit queuing and
system responsiveness when "audit=1" is specified on the kernel
command line and the audit daemon is SIGSTOP'd for an extended period
of time. Please merge for v5.17-rcX.
Thanks,
-Paul
--
The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:
Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
tags/audit-pr-20220131
for you to fetch changes up to f26d04331360d42dbd6b58448bd98e4edbfbe1c5:
audit: improve audit queue handling when "audit=1" on cmdline
(2022-01-25 13:22:51 -0500)
----------------------------------------------------------------
audit/stable-5.17 PR 20220131
----------------------------------------------------------------
Paul Moore (1):
audit: improve audit queue handling when "audit=1" on cmdline
kernel/audit.c | 62 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 43 insertions(+), 19 deletions(-)
--
paul-moore.com
2 years, 9 months
[PATCH v2] audit: log AUDIT_TIME_* records only from rules
by Richard Guy Briggs
AUDIT_TIME_* events are generated when there are syscall rules present that are
not related to time keeping. This will produce noisy log entries that could
flood the logs and hide events we really care about.
Rather than immediately produce the AUDIT_TIME_* records, store the data in the
context and log it at syscall exit time respecting the filter rules.
Please see https://bugzilla.redhat.com/show_bug.cgi?id=1991919
Fixes: 7e8eda734d30 ("ntp: Audit NTP parameters adjustment")
Fixes: 2d87a0674bd6 ("timekeeping: Audit clock adjustments")
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v2:
- rename __audit_ntp_log_ to audit_log_ntp
- pre-check ntp before storing
- move tk out of the context union and move ntp logging to the bottom of audit_show_special()
- restructure logging of ntp to use ab and allocate more only if more
- add Fixes lines
kernel/audit.h | 2 ++
kernel/auditsc.c | 77 +++++++++++++++++++++++++++++++++++-------------
2 files changed, 59 insertions(+), 20 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index c4498090a5bd..11789249d838 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -201,8 +201,10 @@ struct audit_context {
struct {
char *name;
} module;
+ struct audit_ntp_data ntp_data;
};
int fds[2];
+ struct timespec64 tk_injoffset;
struct audit_proctitle proctitle;
};
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index b517947bfa48..1838a2b3ab10 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1331,6 +1331,38 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
from_kuid(&init_user_ns, name->fcap.rootid));
}
+void audit_log_ntp(struct audit_context *context, struct audit_buffer **ab,
+ const struct audit_ntp_data *ad)
+{
+ const char *ntp_name[] = {
+ "offset",
+ "freq",
+ "status",
+ "tai",
+ "tick",
+ "adjust",
+ };
+ int type, first = 1;
+
+ /* use up allocated ab from show_special before new one */
+ for (type = 0; type < AUDIT_NTP_NVALS; type++) {
+ if (ad->vals[type].newval != ad->vals[type].oldval) {
+ if (first) {
+ first = 0;
+ } else {
+ audit_log_end(*ab);
+ *ab = audit_log_start(context, GFP_KERNEL,
+ AUDIT_TIME_ADJNTPVAL);
+ if (!*ab)
+ return;
+ }
+ audit_log_format(*ab, "op=%s old=%lli new=%lli",
+ ntp_name[type], ad->vals[type].oldval,
+ ad->vals[type].newval);
+ }
+ }
+}
+
static void show_special(struct audit_context *context, int *call_panic)
{
struct audit_buffer *ab;
@@ -1445,6 +1477,9 @@ static void show_special(struct audit_context *context, int *call_panic)
audit_log_format(ab, "(null)");
break;
+ case AUDIT_TIME_ADJNTPVAL:
+ audit_log_ntp(context, &ab, &context->ntp_data);
+ break;
}
audit_log_end(ab);
}
@@ -1767,6 +1802,17 @@ static void audit_log_exit(void)
audit_log_name(context, n, NULL, i++, &call_panic);
}
+ if (context->tk_injoffset.tv_sec != 0 ||
+ context->tk_injoffset.tv_nsec != 0) {
+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_TIME_INJOFFSET);
+ if (ab) {
+ audit_log_format(ab, "sec=%lli nsec=%li",
+ (long long)context->tk_injoffset.tv_sec,
+ context->tk_injoffset.tv_nsec);
+ audit_log_end(ab);
+ }
+ }
+
if (context->context == AUDIT_CTX_SYSCALL)
audit_log_proctitle();
@@ -2840,31 +2886,22 @@ void __audit_fanotify(unsigned int response)
void __audit_tk_injoffset(struct timespec64 offset)
{
- audit_log(audit_context(), GFP_KERNEL, AUDIT_TIME_INJOFFSET,
- "sec=%lli nsec=%li",
- (long long)offset.tv_sec, offset.tv_nsec);
-}
-
-static void audit_log_ntp_val(const struct audit_ntp_data *ad,
- const char *op, enum audit_ntp_type type)
-{
- const struct audit_ntp_val *val = &ad->vals[type];
-
- if (val->newval == val->oldval)
- return;
+ struct audit_context *context = audit_context();
- audit_log(audit_context(), GFP_KERNEL, AUDIT_TIME_ADJNTPVAL,
- "op=%s old=%lli new=%lli", op, val->oldval, val->newval);
+ memcpy(&context->tk_injoffset, &offset, sizeof(offset));
}
void __audit_ntp_log(const struct audit_ntp_data *ad)
{
- audit_log_ntp_val(ad, "offset", AUDIT_NTP_OFFSET);
- audit_log_ntp_val(ad, "freq", AUDIT_NTP_FREQ);
- audit_log_ntp_val(ad, "status", AUDIT_NTP_STATUS);
- audit_log_ntp_val(ad, "tai", AUDIT_NTP_TAI);
- audit_log_ntp_val(ad, "tick", AUDIT_NTP_TICK);
- audit_log_ntp_val(ad, "adjust", AUDIT_NTP_ADJUST);
+ struct audit_context *context = audit_context();
+ int type;
+
+ for (type = 0; type < AUDIT_NTP_NVALS; type++)
+ if (ad->vals[type].newval != ad->vals[type].oldval) {
+ context->type = AUDIT_TIME_ADJNTPVAL;
+ memcpy(&context->ntp_data, ad, sizeof(*ad));
+ break;
+ }
}
void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
--
2.27.0
2 years, 9 months
Re: Maximum Value for q_depth
by Amjad Gabbar
Got it. Makes sense to me. Thanks for the explanation Steve.
One last thing though based on the discussion we had, if the kernel is able
to offload events even during bursts, wouldn’t setting q_depth
=backlog_limit be enough?
The reason being if there was an overflow on the kernel side, a different
message would be printed in the logs but because it is all dispatch errors,
I assume the kernel is able to handle the burst which is why the reasoning
of increasing q_depth to backlog_limit.
Thanks
Amjad
On Wed, Dec 8, 2021 at 4:38 PM Steve Grubb <sgrubb(a)redhat.com> wrote:
> On Wednesday, December 8, 2021 4:54:18 PM EST Amjad Gabbar wrote:
> > 1. The version of auditd is 1:2.8.4-3 and the plugins are af_unix.conf
> and
> > syslog.conf for audisp. The q_depth is currently set to 80 and I think it
> > calls for an increase but not sure if there is a way to figure out what
> the
> > proper number would be?
>
> There is no good calculation that I can give you. It depends on the
> average
> rate of incoming events and the rate that they can be offloaded to the
> plugins
> + some margin in case there is a burst. Looking at the 2.8.5 code, the
> default is 250.
>
> https://github.com/linux-audit/audit-userspace/blob/2.8_maintenance/init.d/
> audispd.conf
>
> So, you should at least set it that high. Maybe a bit higher.
>
>
> > 2. Another thing I would like to follow up on is the difference between
> > q_depth and backlog_limit. My assumption was if there is any drop due to
> a
> > burst of events it would be addressed by the backlog limit. Just would
> like
> > some clarification on this and how this is an event dispatcher issue?
>
> The backlog limit is inside the kernel. This is the buffer that holds
> events
> that are waiting for the audit daemon to offload them. Once the audit
> daemon
> has them, it sends it to the dispatcher which also buffers events because
> not
> all plugins are able to receive the events as soon as they arrive at the
> dispatcher.
>
> So, for brief bursts, the kernel backlog will handle the load. But once
> they
> are pulled out of the kernel, the q_depth controls how much to hold
> waiting
> for plugins. If this number needs to increase much, then the plugins are
> having problems. The syslog plugin should be fine. I'd look more at the
> af_unix plugin. The client that attaches to it needs to unload events
> quickly. I'd investigate the af_unix client to see if it's the problem.
>
> Cheers,
> -Steve
>
>
>
2 years, 9 months
[PATCH v2] audit: improve audit queue handling when "audit=1" on cmdline
by Paul Moore
When an admin enables audit at early boot via the "audit=1" kernel
command line the audit queue behavior is slightly different; the
audit subsystem goes to greater lengths to avoid dropping records,
which unfortunately can result in problems when the audit daemon is
forcibly stopped for an extended period of time.
This patch makes a number of changes designed to improve the audit
queuing behavior so that leaving the audit daemon in a stopped state
for an extended period does not cause a significant impact to the
system.
- kauditd_send_queue() is now limited to looping through the
passed queue only once per call. This not only prevents the
function from looping indefinitely when records are returned
to the current queue, it also allows any recovery handling in
kauditd_thread() to take place when kauditd_send_queue()
returns.
- Transient netlink send errors seen as -EAGAIN now cause the
record to be returned to the retry queue instead of going to
the hold queue. The intention of the hold queue is to store,
perhaps for an extended period of time, the events which led
up to the audit daemon going offline. The retry queue remains
a temporary queue intended to protect against transient issues
between the kernel and the audit daemon.
- The retry queue is now limited by the audit_backlog_limit
setting, the same as the other queues. This allows admins
to bound the size of all of the audit queues on the system.
- kauditd_rehold_skb() now returns records to the end of the
hold queue to ensure ordering is preserved in the face of
recent changes to kauditd_send_queue().
Cc: stable(a)vger.kernel.org
Fixes: 5b52330bbfe63 ("audit: fix auditd/kernel connection state tracking")
Fixes: f4b3ee3c85551 ("audit: improve robustness of the audit queue handling")
Reported-by: Gaosheng Cui <cuigaosheng1(a)huawei.com>
Signed-off-by: Paul Moore <paul(a)paul-moore.com>
--
v2:
- incorporated feedback from Gaosheng Cui
- promoted to proper patch
v1:
- initial RFC
---
kernel/audit.c | 62 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 43 insertions(+), 19 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 4cebadb5f30d..60f8a77a6c83 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -541,20 +541,22 @@ static void kauditd_printk_skb(struct sk_buff *skb)
/**
* kauditd_rehold_skb - Handle a audit record send failure in the hold queue
* @skb: audit record
+ * @error: error code (unused)
*
* Description:
* This should only be used by the kauditd_thread when it fails to flush the
* hold queue.
*/
-static void kauditd_rehold_skb(struct sk_buff *skb)
+static void kauditd_rehold_skb(struct sk_buff *skb, __always_unused int error)
{
- /* put the record back in the queue at the same place */
- skb_queue_head(&audit_hold_queue, skb);
+ /* put the record back in the queue */
+ skb_queue_tail(&audit_hold_queue, skb);
}
/**
* kauditd_hold_skb - Queue an audit record, waiting for auditd
* @skb: audit record
+ * @error: error code
*
* Description:
* Queue the audit record, waiting for an instance of auditd. When this
@@ -564,19 +566,31 @@ static void kauditd_rehold_skb(struct sk_buff *skb)
* and queue it, if we have room. If we want to hold on to the record, but we
* don't have room, record a record lost message.
*/
-static void kauditd_hold_skb(struct sk_buff *skb)
+static void kauditd_hold_skb(struct sk_buff *skb, int error)
{
/* at this point it is uncertain if we will ever send this to auditd so
* try to send the message via printk before we go any further */
kauditd_printk_skb(skb);
/* can we just silently drop the message? */
- if (!audit_default) {
- kfree_skb(skb);
- return;
+ if (!audit_default)
+ goto drop;
+
+ /* the hold queue is only for when the daemon goes away completely,
+ * not -EAGAIN failures; if we are in a -EAGAIN state requeue the
+ * record on the retry queue unless it's full, in which case drop it
+ */
+ if (error == -EAGAIN) {
+ if (!audit_backlog_limit ||
+ skb_queue_len(&audit_retry_queue) < audit_backlog_limit) {
+ skb_queue_tail(&audit_retry_queue, skb);
+ return;
+ }
+ audit_log_lost("kauditd retry queue overflow");
+ goto drop;
}
- /* if we have room, queue the message */
+ /* if we have room in the hold queue, queue the message */
if (!audit_backlog_limit ||
skb_queue_len(&audit_hold_queue) < audit_backlog_limit) {
skb_queue_tail(&audit_hold_queue, skb);
@@ -585,24 +599,32 @@ static void kauditd_hold_skb(struct sk_buff *skb)
/* we have no other options - drop the message */
audit_log_lost("kauditd hold queue overflow");
+drop:
kfree_skb(skb);
}
/**
* kauditd_retry_skb - Queue an audit record, attempt to send again to auditd
* @skb: audit record
+ * @error: error code (unused)
*
* Description:
* Not as serious as kauditd_hold_skb() as we still have a connected auditd,
* but for some reason we are having problems sending it audit records so
* queue the given record and attempt to resend.
*/
-static void kauditd_retry_skb(struct sk_buff *skb)
+static void kauditd_retry_skb(struct sk_buff *skb, __always_unused int error)
{
- /* NOTE: because records should only live in the retry queue for a
- * short period of time, before either being sent or moved to the hold
- * queue, we don't currently enforce a limit on this queue */
- skb_queue_tail(&audit_retry_queue, skb);
+ if (!audit_backlog_limit ||
+ skb_queue_len(&audit_retry_queue) < audit_backlog_limit) {
+ skb_queue_tail(&audit_retry_queue, skb);
+ return;
+ }
+
+ /* we have to drop the record, send it via printk as a last effort */
+ kauditd_printk_skb(skb);
+ audit_log_lost("kauditd retry queue overflow");
+ kfree_skb(skb);
}
/**
@@ -640,7 +662,7 @@ static void auditd_reset(const struct auditd_connection *ac)
/* flush the retry queue to the hold queue, but don't touch the main
* queue since we need to process that normally for multicast */
while ((skb = skb_dequeue(&audit_retry_queue)))
- kauditd_hold_skb(skb);
+ kauditd_hold_skb(skb, -ECONNREFUSED);
}
/**
@@ -714,16 +736,18 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
struct sk_buff_head *queue,
unsigned int retry_limit,
void (*skb_hook)(struct sk_buff *skb),
- void (*err_hook)(struct sk_buff *skb))
+ void (*err_hook)(struct sk_buff *skb, int error))
{
int rc = 0;
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
+ struct sk_buff *skb_tail;
unsigned int failed = 0;
/* NOTE: kauditd_thread takes care of all our locking, we just use
* the netlink info passed to us (e.g. sk and portid) */
- while ((skb = skb_dequeue(queue))) {
+ skb_tail = skb_peek_tail(queue);
+ while ((skb != skb_tail) && (skb = skb_dequeue(queue))) {
/* call the skb_hook for each skb we touch */
if (skb_hook)
(*skb_hook)(skb);
@@ -731,7 +755,7 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
/* can we send to anyone via unicast? */
if (!sk) {
if (err_hook)
- (*err_hook)(skb);
+ (*err_hook)(skb, -ECONNREFUSED);
continue;
}
@@ -745,7 +769,7 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
rc == -ECONNREFUSED || rc == -EPERM) {
sk = NULL;
if (err_hook)
- (*err_hook)(skb);
+ (*err_hook)(skb, rc);
if (rc == -EAGAIN)
rc = 0;
/* continue to drain the queue */
2 years, 9 months
[PATCH v2 0/7] pid: Introduce helper task_is_in_root_ns()
by Leo Yan
The kernel uses open code to check if a process is in root PID namespace
or not in several places.
Suggested by Suzuki, this patch set is to create a helper function
task_is_in_init_pid_ns() to replace open code.
This patch set has been applied on the mainline kernel and built for
Arm64 kernel with enabling all relevant modules.
Changes from v1:
* Renamed helper function from task_is_in_root_ns() to
task_is_in_init_pid_ns(). (Leon Romanovsky)
* Improved patches' commit logs for more neat.
Leo Yan (7):
pid: Introduce helper task_is_in_init_pid_ns()
coresight: etm3x: Use task_is_in_init_pid_ns()
coresight: etm4x: Use task_is_in_init_pid_ns()
connector/cn_proc: Use task_is_in_init_pid_ns()
coda: Use task_is_in_init_pid_ns()
audit: Use task_is_in_init_pid_ns()
taskstats: Use task_is_in_init_pid_ns()
drivers/connector/cn_proc.c | 2 +-
drivers/hwtracing/coresight/coresight-etm3x-sysfs.c | 8 ++++----
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 8 ++++----
fs/coda/inode.c | 2 +-
fs/coda/psdev.c | 2 +-
include/linux/pid_namespace.h | 5 +++++
kernel/audit.c | 2 +-
kernel/taskstats.c | 2 +-
8 files changed, 18 insertions(+), 13 deletions(-)
--
2.25.1
2 years, 9 months
audit-3.0.7 released
by Steve Grubb
Hello,
I've just released a new version of the audit daemon. It can be
downloaded from http://people.redhat.com/sgrubb/audit. It will also be
in rawhide soon. The ChangeLog is:
- Add support for the OPENAT2 record type (Richard Guy Briggs)
- In auditd, close the logging file descriptor when logging is suspended
- Update the capabilities lookup table to match 5.16 kernel
- Improve interpretation of renamat & faccessat family of syscalls
- Update syscall table for the 5.16 kernel
- Reduce dependency from initscripts to initscripts-service
The main driver for this release is simply getting something out that matches
the recently released 5.16 kernel.
SHA256: 8b4c78632a9301a1c7f859b0e38fc0b9c260b8214d6b7c771bf28b3d73a62597
Please let me know if you run across any problems with this release.
-Steve
2 years, 9 months
[RFC PATCH v1] audit: log AUDIT_TIME_* records only from rules
by Richard Guy Briggs
AUDIT_TIME_* events are generated when there are syscall rules present that are
not related to time keeping. This will produce noisy log entries that could
flood the logs and hide events we really care about.
Rather than immediately produce the AUDIT_TIME_* records, store the data and
log it at syscall exit time respecting the filter rules.
Please see https://bugzilla.redhat.com/show_bug.cgi?id=1991919
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Note: This is a quick and dirty proof-of-concept. If this approach of
storing the values in the audit_context for later filtering is
acceptable I'll clean up the patch (re-name functions) and re-submit.
kernel/audit.h | 6 ++++++
kernel/auditsc.c | 29 +++++++++++++++++++++++++----
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/kernel/audit.h b/kernel/audit.h
index 3b64a97f6091..25d63731b0e0 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -196,6 +196,12 @@ struct audit_context {
struct {
char *name;
} module;
+ struct {
+ struct audit_ntp_data data;
+ } ntp;
+ struct {
+ struct timespec64 injoffset;
+ } tk;
};
int fds[2];
struct audit_proctitle proctitle;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 6efb0bb909d0..8983790ad86a 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1210,11 +1210,18 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
from_kuid(&init_user_ns, name->fcap.rootid));
}
+void __audit_ntp_log_(const struct audit_ntp_data *ad);
+
static void show_special(struct audit_context *context, int *call_panic)
{
struct audit_buffer *ab;
int i;
+ if (context->type == AUDIT_TIME_ADJNTPVAL) {
+ __audit_ntp_log_(&context->ntp.data);
+ return;
+ }
+
ab = audit_log_start(context, GFP_KERNEL, context->type);
if (!ab)
return;
@@ -1324,6 +1331,11 @@ static void show_special(struct audit_context *context, int *call_panic)
audit_log_format(ab, "(null)");
break;
+ case AUDIT_TIME_INJOFFSET:
+ audit_log_format(ab, "sec=%lli nsec=%li",
+ (long long)context->tk.injoffset.tv_sec,
+ context->tk.injoffset.tv_nsec);
+ break;
}
audit_log_end(ab);
}
@@ -2571,9 +2583,18 @@ void __audit_fanotify(unsigned int response)
void __audit_tk_injoffset(struct timespec64 offset)
{
- audit_log(audit_context(), GFP_KERNEL, AUDIT_TIME_INJOFFSET,
- "sec=%lli nsec=%li",
- (long long)offset.tv_sec, offset.tv_nsec);
+ struct audit_context *context = audit_context();
+
+ context->type = AUDIT_TIME_INJOFFSET;
+ memcpy(&context->tk.injoffset, &offset, sizeof(offset));
+}
+
+void __audit_ntp_log(const struct audit_ntp_data *ad)
+{
+ struct audit_context *context = audit_context();
+
+ context->type = AUDIT_TIME_ADJNTPVAL;
+ memcpy(&context->ntp.data, ad, sizeof(*ad));
}
static void audit_log_ntp_val(const struct audit_ntp_data *ad,
@@ -2588,7 +2609,7 @@ static void audit_log_ntp_val(const struct audit_ntp_data *ad,
"op=%s old=%lli new=%lli", op, val->oldval, val->newval);
}
-void __audit_ntp_log(const struct audit_ntp_data *ad)
+void __audit_ntp_log_(const struct audit_ntp_data *ad)
{
audit_log_ntp_val(ad, "offset", AUDIT_NTP_OFFSET);
audit_log_ntp_val(ad, "freq", AUDIT_NTP_FREQ);
--
2.27.0
2 years, 9 months