* [PATCH v2 0/2] Fix auditsc DoS and mark it BROKEN @ 2014-05-29 1:43 Andy Lutomirski 2014-05-29 1:44 ` [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking Andy Lutomirski 2014-05-29 1:44 ` [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text Andy Lutomirski 0 siblings, 2 replies; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 1:43 UTC (permalink / raw) To: Andy Lutomirski, Philipp Kern, H. Peter Anvin, linux-kernel, H. J. Lu, Eric Paris, security, greg, linux-audit CONFIG_AUDITSYSCALL is awful. Patch 2 enumerates some reasons. Patch 1 fixes a nasty DoS and possible information leak. It should be applied and backported. Patch 2 is optional. I leave it to other peoples' judgment. Andy Lutomirski (2): auditsc: audit_krule mask accesses need bounds checking audit: Move CONFIG_AUDITSYSCALL into staging and update help text Andy Lutomirski (2): auditsc: audit_krule mask accesses need bounds checking audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text init/Kconfig | 13 ++++++++----- kernel/auditsc.c | 27 ++++++++++++++++++--------- 2 files changed, 26 insertions(+), 14 deletions(-) -- 1.9.3 ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking 2014-05-29 1:43 [PATCH v2 0/2] Fix auditsc DoS and mark it BROKEN Andy Lutomirski @ 2014-05-29 1:44 ` Andy Lutomirski 2014-05-29 2:23 ` Eric Paris 2014-05-29 1:44 ` [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text Andy Lutomirski 1 sibling, 1 reply; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 1:44 UTC (permalink / raw) To: Andy Lutomirski, Philipp Kern, H. Peter Anvin, linux-kernel, H. J. Lu, Eric Paris, security, greg, linux-audit Cc: stable Fixes an easy DoS and possible information disclosure. This does nothing about the broken state of x32 auditing. Cc: stable@vger.kernel.org Signed-off-by: Andy Lutomirski <luto@amacapital.net> --- kernel/auditsc.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index f251a5e..7ccd9db 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -728,6 +728,22 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) return AUDIT_BUILD_CONTEXT; } +static bool audit_in_mask(const struct audit_krule *rule, unsigned long val) +{ + int word, bit; + + if (val > 0xffffffff) + return false; + + word = AUDIT_WORD(val); + if (word >= AUDIT_BITMASK_SIZE) + return false; + + bit = AUDIT_BIT(val); + + return rule->mask[word] & bit; +} + /* At syscall entry and exit time, this filter is called if the * audit_state is not low enough that auditing cannot take place, but is * also not high enough that we already know we have to write an audit @@ -745,11 +761,8 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, rcu_read_lock(); if (!list_empty(list)) { - int word = AUDIT_WORD(ctx->major); - int bit = AUDIT_BIT(ctx->major); - list_for_each_entry_rcu(e, list, list) { - if ((e->rule.mask[word] & bit) == bit && + if (audit_in_mask(&e->rule, ctx->major) && audit_filter_rules(tsk, &e->rule, ctx, NULL, &state, false)) { rcu_read_unlock(); @@ -769,20 +782,16 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, static int audit_filter_inode_name(struct task_struct *tsk, struct audit_names *n, struct audit_context *ctx) { - int word, bit; int h = audit_hash_ino((u32)n->ino); struct list_head *list = &audit_inode_hash[h]; struct audit_entry *e; enum audit_state state; - word = AUDIT_WORD(ctx->major); - bit = AUDIT_BIT(ctx->major); - if (list_empty(list)) return 0; list_for_each_entry_rcu(e, list, list) { - if ((e->rule.mask[word] & bit) == bit && + if (audit_in_mask(&e->rule, ctx->major) && audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) { ctx->current_state = state; return 1; -- 1.9.3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking 2014-05-29 1:44 ` [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking Andy Lutomirski @ 2014-05-29 2:23 ` Eric Paris 2014-05-29 2:27 ` Andy Lutomirski 0 siblings, 1 reply; 15+ messages in thread From: Eric Paris @ 2014-05-29 2:23 UTC (permalink / raw) To: Andy Lutomirski Cc: Philipp Kern, H. Peter Anvin, linux-kernel, H. J. Lu, security, greg, linux-audit, stable On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: > Fixes an easy DoS and possible information disclosure. > > This does nothing about the broken state of x32 auditing. > > Cc: stable@vger.kernel.org > Signed-off-by: Andy Lutomirski <luto@amacapital.net> > --- > kernel/auditsc.c | 27 ++++++++++++++++++--------- > 1 file changed, 18 insertions(+), 9 deletions(-) > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > index f251a5e..7ccd9db 100644 > --- a/kernel/auditsc.c > +++ b/kernel/auditsc.c > @@ -728,6 +728,22 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) > return AUDIT_BUILD_CONTEXT; > } > > +static bool audit_in_mask(const struct audit_krule *rule, unsigned long val) > +{ > + int word, bit; > + > + if (val > 0xffffffff) > + return false; Why is this necessary? > + > + word = AUDIT_WORD(val); > + if (word >= AUDIT_BITMASK_SIZE) > + return false; Since this covers it and it extensible... > + > + bit = AUDIT_BIT(val); > + > + return rule->mask[word] & bit; Returning an int as a bool creates worse code than just returning the int. (although in this case if the compiler chooses to inline it might be smart enough not to actually convert this int to a bool and make worse assembly...) I'd suggest the function here return an int. bools usually make the assembly worse... Otherwise I'd give it an ACK... > +} > + > /* At syscall entry and exit time, this filter is called if the > * audit_state is not low enough that auditing cannot take place, but is > * also not high enough that we already know we have to write an audit > @@ -745,11 +761,8 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, > > rcu_read_lock(); > if (!list_empty(list)) { > - int word = AUDIT_WORD(ctx->major); > - int bit = AUDIT_BIT(ctx->major); > - > list_for_each_entry_rcu(e, list, list) { > - if ((e->rule.mask[word] & bit) == bit && > + if (audit_in_mask(&e->rule, ctx->major) && > audit_filter_rules(tsk, &e->rule, ctx, NULL, > &state, false)) { > rcu_read_unlock(); > @@ -769,20 +782,16 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, > static int audit_filter_inode_name(struct task_struct *tsk, > struct audit_names *n, > struct audit_context *ctx) { > - int word, bit; > int h = audit_hash_ino((u32)n->ino); > struct list_head *list = &audit_inode_hash[h]; > struct audit_entry *e; > enum audit_state state; > > - word = AUDIT_WORD(ctx->major); > - bit = AUDIT_BIT(ctx->major); > - > if (list_empty(list)) > return 0; > > list_for_each_entry_rcu(e, list, list) { > - if ((e->rule.mask[word] & bit) == bit && > + if (audit_in_mask(&e->rule, ctx->major) && > audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) { > ctx->current_state = state; > return 1; ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking 2014-05-29 2:23 ` Eric Paris @ 2014-05-29 2:27 ` Andy Lutomirski 2014-05-29 2:43 ` Eric Paris 0 siblings, 1 reply; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 2:27 UTC (permalink / raw) To: Eric Paris Cc: Philipp Kern, H. Peter Anvin, linux-kernel@vger.kernel.org, H. J. Lu, security@kernel.org, Greg Kroah-Hartman, linux-audit, stable On Wed, May 28, 2014 at 7:23 PM, Eric Paris <eparis@redhat.com> wrote: > On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: >> Fixes an easy DoS and possible information disclosure. >> >> This does nothing about the broken state of x32 auditing. >> >> Cc: stable@vger.kernel.org >> Signed-off-by: Andy Lutomirski <luto@amacapital.net> >> --- >> kernel/auditsc.c | 27 ++++++++++++++++++--------- >> 1 file changed, 18 insertions(+), 9 deletions(-) >> >> diff --git a/kernel/auditsc.c b/kernel/auditsc.c >> index f251a5e..7ccd9db 100644 >> --- a/kernel/auditsc.c >> +++ b/kernel/auditsc.c >> @@ -728,6 +728,22 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) >> return AUDIT_BUILD_CONTEXT; >> } >> >> +static bool audit_in_mask(const struct audit_krule *rule, unsigned long val) >> +{ >> + int word, bit; >> + >> + if (val > 0xffffffff) >> + return false; > > Why is this necessary? To avoid an integer overflow. Admittedly, this particular overflow won't cause a crash, but it will cause incorrect results. > >> + >> + word = AUDIT_WORD(val); >> + if (word >= AUDIT_BITMASK_SIZE) >> + return false; > > Since this covers it and it extensible... > >> + >> + bit = AUDIT_BIT(val); >> + >> + return rule->mask[word] & bit; > > Returning an int as a bool creates worse code than just returning the > int. (although in this case if the compiler chooses to inline it might > be smart enough not to actually convert this int to a bool and make > worse assembly...) I'd suggest the function here return an int. bools > usually make the assembly worse... I'm ambivalent. The right assembly would use flags on x86, not an int or a bool, and I don't know what the compiler will do. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking 2014-05-29 2:27 ` Andy Lutomirski @ 2014-05-29 2:43 ` Eric Paris 2014-05-29 2:46 ` Andy Lutomirski 0 siblings, 1 reply; 15+ messages in thread From: Eric Paris @ 2014-05-29 2:43 UTC (permalink / raw) To: Andy Lutomirski Cc: Philipp Kern, H. Peter Anvin, linux-kernel@vger.kernel.org, H. J. Lu, security@kernel.org, Greg Kroah-Hartman, linux-audit, stable On Wed, 2014-05-28 at 19:27 -0700, Andy Lutomirski wrote: > On Wed, May 28, 2014 at 7:23 PM, Eric Paris <eparis@redhat.com> wrote: > > On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: > >> Fixes an easy DoS and possible information disclosure. > >> > >> This does nothing about the broken state of x32 auditing. > >> > >> Cc: stable@vger.kernel.org > >> Signed-off-by: Andy Lutomirski <luto@amacapital.net> > >> --- > >> kernel/auditsc.c | 27 ++++++++++++++++++--------- > >> 1 file changed, 18 insertions(+), 9 deletions(-) > >> > >> diff --git a/kernel/auditsc.c b/kernel/auditsc.c > >> index f251a5e..7ccd9db 100644 > >> --- a/kernel/auditsc.c > >> +++ b/kernel/auditsc.c > >> @@ -728,6 +728,22 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) > >> return AUDIT_BUILD_CONTEXT; > >> } > >> > >> +static bool audit_in_mask(const struct audit_krule *rule, unsigned long val) > >> +{ > >> + int word, bit; > >> + > >> + if (val > 0xffffffff) > >> + return false; > > > > Why is this necessary? > > To avoid an integer overflow. Admittedly, this particular overflow > won't cause a crash, but it will cause incorrect results. You know this code pre-dates git? I admit, I'm shocked no one ever noticed it before! This is ANCIENT. And clearly broken. I'll likely ask Richard to add a WARN_ONCE() in both this place, and below in word > AUDIT_BITMASK_SIZE so we might know if we ever need a larger bitmask to store syscall numbers.... It'd be nice if lib had a efficient bitmask implementation... > > > >> + > >> + word = AUDIT_WORD(val); > >> + if (word >= AUDIT_BITMASK_SIZE) > >> + return false; > > > > Since this covers it and it extensible... > > > >> + > >> + bit = AUDIT_BIT(val); > >> + > >> + return rule->mask[word] & bit; > > > > Returning an int as a bool creates worse code than just returning the > > int. (although in this case if the compiler chooses to inline it might > > be smart enough not to actually convert this int to a bool and make > > worse assembly...) I'd suggest the function here return an int. bools > > usually make the assembly worse... > > I'm ambivalent. The right assembly would use flags on x86, not an int > or a bool, and I don't know what the compiler will do. Also, clearly X86_X32 was implemented without audit support, so we shouldn't config it in. What do you think of this? diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 25d2c6f..fa852e2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -129,7 +129,7 @@ config X86 select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 select HAVE_CC_STACKPROTECTOR select GENERIC_CPU_AUTOPROBE - select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_AUDITSYSCALL if !X86_X32 config INSTRUCTION_DECODER def_bool y ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking 2014-05-29 2:43 ` Eric Paris @ 2014-05-29 2:46 ` Andy Lutomirski 0 siblings, 0 replies; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 2:46 UTC (permalink / raw) To: Eric Paris Cc: Philipp Kern, H. Peter Anvin, linux-kernel@vger.kernel.org, H. J. Lu, security@kernel.org, Greg Kroah-Hartman, linux-audit, stable On Wed, May 28, 2014 at 7:43 PM, Eric Paris <eparis@redhat.com> wrote: > On Wed, 2014-05-28 at 19:27 -0700, Andy Lutomirski wrote: >> On Wed, May 28, 2014 at 7:23 PM, Eric Paris <eparis@redhat.com> wrote: >> > On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: >> >> Fixes an easy DoS and possible information disclosure. >> >> >> >> This does nothing about the broken state of x32 auditing. >> >> >> >> Cc: stable@vger.kernel.org >> >> Signed-off-by: Andy Lutomirski <luto@amacapital.net> >> >> --- >> >> kernel/auditsc.c | 27 ++++++++++++++++++--------- >> >> 1 file changed, 18 insertions(+), 9 deletions(-) >> >> >> >> diff --git a/kernel/auditsc.c b/kernel/auditsc.c >> >> index f251a5e..7ccd9db 100644 >> >> --- a/kernel/auditsc.c >> >> +++ b/kernel/auditsc.c >> >> @@ -728,6 +728,22 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) >> >> return AUDIT_BUILD_CONTEXT; >> >> } >> >> >> >> +static bool audit_in_mask(const struct audit_krule *rule, unsigned long val) >> >> +{ >> >> + int word, bit; >> >> + >> >> + if (val > 0xffffffff) >> >> + return false; >> > >> > Why is this necessary? >> >> To avoid an integer overflow. Admittedly, this particular overflow >> won't cause a crash, but it will cause incorrect results. > > You know this code pre-dates git? I admit, I'm shocked no one ever > noticed it before! This is ANCIENT. And clearly broken. > > I'll likely ask Richard to add a WARN_ONCE() in both this place, and > below in word > AUDIT_BITMASK_SIZE so we might know if we ever need a > larger bitmask to store syscall numbers.... > Not there, please! It would make sense to check when rules are *added*, but any user can trivially invoke the filter with pretty much any syscall nr. > It'd be nice if lib had a efficient bitmask implementation... > >> > >> >> + >> >> + word = AUDIT_WORD(val); >> >> + if (word >= AUDIT_BITMASK_SIZE) >> >> + return false; >> > >> > Since this covers it and it extensible... >> > >> >> + >> >> + bit = AUDIT_BIT(val); >> >> + >> >> + return rule->mask[word] & bit; >> > >> > Returning an int as a bool creates worse code than just returning the >> > int. (although in this case if the compiler chooses to inline it might >> > be smart enough not to actually convert this int to a bool and make >> > worse assembly...) I'd suggest the function here return an int. bools >> > usually make the assembly worse... >> >> I'm ambivalent. The right assembly would use flags on x86, not an int >> or a bool, and I don't know what the compiler will do. > > Also, clearly X86_X32 was implemented without audit support, so we > shouldn't config it in. What do you think of this? > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index 25d2c6f..fa852e2 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -129,7 +129,7 @@ config X86 > select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 > select HAVE_CC_STACKPROTECTOR > select GENERIC_CPU_AUTOPROBE > - select HAVE_ARCH_AUDITSYSCALL > + select HAVE_ARCH_AUDITSYSCALL if !X86_X32 I'm fine with that, but I hope that distros will choose x32 over auditsc, at least until someone makes enabling auditsc be less intrusive. Or someone could fix it, modulo the syscall nr 2048 thing. x32 syscall nrs are *huge*. So are lots of other architectures', a few of which probably claim to support auditsc. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 1:43 [PATCH v2 0/2] Fix auditsc DoS and mark it BROKEN Andy Lutomirski 2014-05-29 1:44 ` [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking Andy Lutomirski @ 2014-05-29 1:44 ` Andy Lutomirski 2014-05-29 2:09 ` Eric Paris 1 sibling, 1 reply; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 1:44 UTC (permalink / raw) To: Andy Lutomirski, Philipp Kern, H. Peter Anvin, linux-kernel, H. J. Lu, Eric Paris, security, greg, linux-audit Here are some issues with the code: - It thinks that syscalls have four arguments. - It's a performance disaster. - It assumes that syscall numbers are between 0 and 2048. - It's unclear whether it's supposed to be reliable. - It's broken on things like x32. - It can't support ARM OABI. - Its approach to freeing memory is terrifying. Signed-off-by: Andy Lutomirski <luto@amacapital.net> --- init/Kconfig | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index 9d3585b..24d4b53 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -296,13 +296,16 @@ config HAVE_ARCH_AUDITSYSCALL bool config AUDITSYSCALL - bool "Enable system-call auditing support" - depends on AUDIT && HAVE_ARCH_AUDITSYSCALL + bool "Enable system-call auditing support (not recommended)" + depends on AUDIT && HAVE_ARCH_AUDITSYSCALL && BROKEN default y if SECURITY_SELINUX help - Enable low-overhead system-call auditing infrastructure that - can be used independently or with another kernel subsystem, - such as SELinux. + Enable system-call auditing infrastructure that can be used + independently or with another kernel subsystem, such as + SELinux. + + AUDITSYSCALL has serious performance and correctness issues. + Use it with extreme caution. config AUDIT_WATCH def_bool y -- 1.9.3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 1:44 ` [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text Andy Lutomirski @ 2014-05-29 2:09 ` Eric Paris 2014-05-29 2:40 ` Andy Lutomirski 0 siblings, 1 reply; 15+ messages in thread From: Eric Paris @ 2014-05-29 2:09 UTC (permalink / raw) To: Andy Lutomirski Cc: Philipp Kern, H. Peter Anvin, linux-kernel, H. J. Lu, security, greg, linux-audit NAK On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: > Here are some issues with the code: > - It thinks that syscalls have four arguments. Not true at all. It records the registers that would hold the first 4 entries on syscall entry, for use later if needed, as getting those later on some arches is not feasible (see ia64). It makes no assumption about how many syscalls a function has. > - It's a performance disaster. Only if you enable it. If you don't use audit it is a single branch. Hardly a disaster. > - It assumes that syscall numbers are between 0 and 2048. There could well be a bug here. Not questioning that. Although that would be patch 1/2 > - It's unclear whether it's supposed to be reliable. Unclear to whom? > - It's broken on things like x32. > - It can't support ARM OABI. Some arches aren't supported? And that makes it BROKEN? > - Its approach to freeing memory is terrifying. What? None of your reasons hold water. Bugs need to be fixed. Try reporting them... This is just stupid. > Signed-off-by: Andy Lutomirski <luto@amacapital.net> > --- > init/Kconfig | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > > diff --git a/init/Kconfig b/init/Kconfig > index 9d3585b..24d4b53 100644 > --- a/init/Kconfig > +++ b/init/Kconfig > @@ -296,13 +296,16 @@ config HAVE_ARCH_AUDITSYSCALL > bool > > config AUDITSYSCALL > - bool "Enable system-call auditing support" > - depends on AUDIT && HAVE_ARCH_AUDITSYSCALL > + bool "Enable system-call auditing support (not recommended)" > + depends on AUDIT && HAVE_ARCH_AUDITSYSCALL && BROKEN > default y if SECURITY_SELINUX > help > - Enable low-overhead system-call auditing infrastructure that > - can be used independently or with another kernel subsystem, > - such as SELinux. > + Enable system-call auditing infrastructure that can be used > + independently or with another kernel subsystem, such as > + SELinux. > + > + AUDITSYSCALL has serious performance and correctness issues. > + Use it with extreme caution. > > config AUDIT_WATCH > def_bool y ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 2:09 ` Eric Paris @ 2014-05-29 2:40 ` Andy Lutomirski 2014-05-29 2:54 ` Eric Paris 2014-05-29 13:05 ` Steve Grubb 0 siblings, 2 replies; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 2:40 UTC (permalink / raw) To: Eric Paris Cc: Philipp Kern, H. Peter Anvin, linux-kernel@vger.kernel.org, H. J. Lu, security@kernel.org, Greg Kroah-Hartman, linux-audit On Wed, May 28, 2014 at 7:09 PM, Eric Paris <eparis@redhat.com> wrote: > NAK > > On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: >> Here are some issues with the code: >> - It thinks that syscalls have four arguments. > > Not true at all. It records the registers that would hold the first 4 > entries on syscall entry, for use later if needed, as getting those > later on some arches is not feasible (see ia64). It makes no assumption > about how many syscalls a function has. What about a5 and a6? > >> - It's a performance disaster. > > Only if you enable it. If you don't use audit it is a single branch. > Hardly a disaster. It forces all syscalls into the slow path and it can do crazy things like building audit contexts just in case actual handling of the syscall triggers an audit condition so that the exit path can log the syscall. That's way worse than a single branch. Try it: benchmark getpid on Fedora and then repeat the experiment with syscall auditing fully disabled. The difference is striking. > >> - It assumes that syscall numbers are between 0 and 2048. > > There could well be a bug here. Not questioning that. Although that > would be patch 1/2 Even with patch 1, it still doesn't handle large syscall numbers -- it just assumes they're not audited. > >> - It's unclear whether it's supposed to be reliable. > > Unclear to whom? To me. If some inode access or selinux rule triggers an audit, is the auditsc code guaranteed to write an exit record? And see below... > >> - It's broken on things like x32. >> - It can't support ARM OABI. > > Some arches aren't supported? And that makes it BROKEN? It acts like x32 is supported. OABI is fixable. Admittedly, OABI not being supported is fine, now that it's correctly disabled. > >> - Its approach to freeing memory is terrifying. > > What? > > None of your reasons hold water. Bugs need to be fixed. Try reporting > them... This is just stupid. ...for reference, I've *tried* to fix the performance issues. I've run into all kinds of problems. The actual context code is incredibly tangled. It's unclear whether it would be permissible for various rule combinations to suppress exit records triggered by selinux. Any effort to actually deal with this stuff will have to deal with the fact that the audit code builds up lots of state and frees it on syscall exit. That means that the exit hook needs to be actually invoked, otherwise we leak. I was never able to convince myself that the current code is correct wrt kernel threads. In summary, the code is a giant mess. The way it works is nearly incomprehensible. It contains at least one severe bug. I'd love to see it fixed, but for now, distributions seem to think that enabling CONFIG_AUDITSYSCALL is a reasonable thing to do, and I'd argue that it's actually a terrible choice for anyone who doesn't actually need syscall audit rules. And I don't know who needs these things. I've heard an argument that selinux benefits from this, since the syscall exit log helps with diagnosing denials. I think that's absurd. I've never found anything wrong with the denial record itself that would be helped by seeing the syscall log. (And there's always syscall_get_xyz, which would cover this case splendidly with about an order of magnitude less code.) As I said, I'm not going to push hard for this code to be marked BROKEN. But I think it's rather broken, and I'm definitely not volunteering to fix it. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 2:40 ` Andy Lutomirski @ 2014-05-29 2:54 ` Eric Paris 2014-05-29 3:01 ` Andy Lutomirski 2014-05-29 13:05 ` Steve Grubb 1 sibling, 1 reply; 15+ messages in thread From: Eric Paris @ 2014-05-29 2:54 UTC (permalink / raw) To: Andy Lutomirski Cc: Philipp Kern, H. Peter Anvin, linux-kernel@vger.kernel.org, H. J. Lu, security@kernel.org, Greg Kroah-Hartman, linux-audit On Wed, 2014-05-28 at 19:40 -0700, Andy Lutomirski wrote: > On Wed, May 28, 2014 at 7:09 PM, Eric Paris <eparis@redhat.com> wrote: > > NAK > > > > On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: > >> Here are some issues with the code: > >> - It thinks that syscalls have four arguments. > > > > Not true at all. It records the registers that would hold the first 4 > > entries on syscall entry, for use later if needed, as getting those > > later on some arches is not feasible (see ia64). It makes no assumption > > about how many syscalls a function has. > > What about a5 and a6? On the couple of syscalls where a5 and a6 had any state that was actually wanted by someone (mainly just the fd on mmap) audit collects it later in the actual syscall. > >> - It assumes that syscall numbers are between 0 and 2048. > > > > There could well be a bug here. Not questioning that. Although that > > would be patch 1/2 > > Even with patch 1, it still doesn't handle large syscall numbers -- it > just assumes they're not audited. That's because we haven't had large syscall numbers. That's the whole point of an arch doing select HAVE_ARCH_AUDITSYSCALL. If they don't meet the requirements, they shouldn't be selecting it.... > >> - It's unclear whether it's supposed to be reliable. > > > > Unclear to whom? > > To me. > > If some inode access or selinux rule triggers an audit, is the auditsc > code guaranteed to write an exit record? And see below... This is an honest question: Do you want to discuss these things, or would you be happier if I shut up, fix the bugs you found, and leave things be? I don't want to have an argument, I'm happy to have a discussion if you think that will be beneficial... ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 2:54 ` Eric Paris @ 2014-05-29 3:01 ` Andy Lutomirski 0 siblings, 0 replies; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 3:01 UTC (permalink / raw) To: Eric Paris Cc: Philipp Kern, H. Peter Anvin, linux-kernel@vger.kernel.org, H. J. Lu, security@kernel.org, Greg Kroah-Hartman, linux-audit On Wed, May 28, 2014 at 7:54 PM, Eric Paris <eparis@redhat.com> wrote: > On Wed, 2014-05-28 at 19:40 -0700, Andy Lutomirski wrote: >> On Wed, May 28, 2014 at 7:09 PM, Eric Paris <eparis@redhat.com> wrote: >> > NAK >> > >> > On Wed, 2014-05-28 at 18:44 -0700, Andy Lutomirski wrote: >> >> Here are some issues with the code: >> >> - It thinks that syscalls have four arguments. >> > >> > Not true at all. It records the registers that would hold the first 4 >> > entries on syscall entry, for use later if needed, as getting those >> > later on some arches is not feasible (see ia64). It makes no assumption >> > about how many syscalls a function has. >> >> What about a5 and a6? > > On the couple of syscalls where a5 and a6 had any state that was > actually wanted by someone (mainly just the fd on mmap) audit collects > it later in the actual syscall. > >> >> - It assumes that syscall numbers are between 0 and 2048. >> > >> > There could well be a bug here. Not questioning that. Although that >> > would be patch 1/2 >> >> Even with patch 1, it still doesn't handle large syscall numbers -- it >> just assumes they're not audited. > > That's because we haven't had large syscall numbers. That's the whole > point of an arch doing select HAVE_ARCH_AUDITSYSCALL. If they don't > meet the requirements, they shouldn't be selecting it.... > >> >> - It's unclear whether it's supposed to be reliable. >> > >> > Unclear to whom? >> >> To me. >> >> If some inode access or selinux rule triggers an audit, is the auditsc >> code guaranteed to write an exit record? And see below... > > This is an honest question: Do you want to discuss these things, or > would you be happier if I shut up, fix the bugs you found, and leave > things be? I don't want to have an argument, I'm happy to have a > discussion if you think that will be beneficial... > I'm happy to discuss these things. I'd be happy if you fix things. I think that there are two major issues affecting users of auditsc and that either those issues should be fixed or users of auditsc should understand and accept these issues. Issue 1: syscall numbering. The syscall filters are unlikely to work well on lots of architectures. Issue 2: performance. Until someone fixes it (which is probably hard), turning this thing on hurts a lot. Oleg added a hack awhile ago that lets you do 'auditctl -a task,never' to get rid of the performance hit for new tasks, but that rather defeats the point. The scariness of the code can be lived with, but holy cow it's scary. I'm just not going to fix the issues myself. I tried and gave up. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 2:40 ` Andy Lutomirski 2014-05-29 2:54 ` Eric Paris @ 2014-05-29 13:05 ` Steve Grubb 2014-05-29 16:04 ` Andy Lutomirski 1 sibling, 1 reply; 15+ messages in thread From: Steve Grubb @ 2014-05-29 13:05 UTC (permalink / raw) To: linux-audit Cc: Andy Lutomirski, Eric Paris, H. J. Lu, security@kernel.org, Philipp Kern, Greg Kroah-Hartman, linux-kernel@vger.kernel.org, H. Peter Anvin On Wednesday, May 28, 2014 07:40:57 PM Andy Lutomirski wrote: > >> - It assumes that syscall numbers are between 0 and 2048. > >> > > There could well be a bug here. Not questioning that. Although that > > would be patch 1/2 > > Even with patch 1, it still doesn't handle large syscall numbers -- it > just assumes they're not audited. All syscalls must be auditable. Meaning that if an arch goes above 2048, then we'll need to do some math to get it to fall back within the range. > >> - It's unclear whether it's supposed to be reliable. > >> > > Unclear to whom? > > To me. > > If some inode access or selinux rule triggers an audit, is the auditsc > code guaranteed to write an exit record? And see below... It should or indicate that it could not. -Steve ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 13:05 ` Steve Grubb @ 2014-05-29 16:04 ` Andy Lutomirski 2014-05-29 16:25 ` Steve Grubb 0 siblings, 1 reply; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 16:04 UTC (permalink / raw) To: Steve Grubb Cc: linux-audit, Eric Paris, H. J. Lu, security@kernel.org, Philipp Kern, Greg Kroah-Hartman, linux-kernel@vger.kernel.org, H. Peter Anvin On Thu, May 29, 2014 at 6:05 AM, Steve Grubb <sgrubb@redhat.com> wrote: > On Wednesday, May 28, 2014 07:40:57 PM Andy Lutomirski wrote: >> >> - It assumes that syscall numbers are between 0 and 2048. >> >> >> > There could well be a bug here. Not questioning that. Although that >> > would be patch 1/2 >> >> Even with patch 1, it still doesn't handle large syscall numbers -- it >> just assumes they're not audited. > > All syscalls must be auditable. Meaning that if an arch goes above 2048, then > we'll need to do some math to get it to fall back within the range. > Off the top of my head, x32, some ARM variants, and some MIPS variants have syscalls above 2048. auditsc has been disabled on the offending ARM variant (because I noticed that the same issue affects seccomp, and no one particularly wants to fix it), but I suspect that auditsc is enabled but completely broken on whichever MIPS ABI has the issue. I haven't checked. TBH, I think that it's silly to let the auditsc design be heavily constrained by ia64 considerations -- I still think that the syscall entry hooks could be removed completely with some effort on most architectures and that performance would improve considerably. For users who don't have syscall filter rules, performance might even improve on ia64 -- I don't care how expensive syscall_get_args is, the actual printk/auditd thing will dominate in cases where anything is written. I wonder whether the syscall restart mechanism can be used to thoroughly confused auditsc. I don't really know how syscall restarts work. My point is: I don't know what guarantees auditsc is supposed to provide, nor do I know how to evaluate whether the code is correct. For users who aren't bound by Common Criteria or related things, I suspect that syscall auditing (as opposed to, say, LSM-based auditing) will provide dubious value at best. Keep in mind that many syscalls take pointer arguments, and the auditsc code can't really do anything sensible with them. > >> >> - It's unclear whether it's supposed to be reliable. >> >> >> > Unclear to whom? >> >> To me. >> >> If some inode access or selinux rule triggers an audit, is the auditsc >> code guaranteed to write an exit record? And see below... > > It should or indicate that it could not. > --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 16:04 ` Andy Lutomirski @ 2014-05-29 16:25 ` Steve Grubb 2014-05-29 16:46 ` Andy Lutomirski 0 siblings, 1 reply; 15+ messages in thread From: Steve Grubb @ 2014-05-29 16:25 UTC (permalink / raw) To: Andy Lutomirski Cc: linux-audit, Eric Paris, H. J. Lu, security@kernel.org, Philipp Kern, Greg Kroah-Hartman, linux-kernel@vger.kernel.org, H. Peter Anvin On Thursday, May 29, 2014 09:04:10 AM Andy Lutomirski wrote: > On Thu, May 29, 2014 at 6:05 AM, Steve Grubb <sgrubb@redhat.com> wrote: > > On Wednesday, May 28, 2014 07:40:57 PM Andy Lutomirski wrote: > >> >> - It assumes that syscall numbers are between 0 and 2048. > >> >> > >> > There could well be a bug here. Not questioning that. Although that > >> > would be patch 1/2 > >> > >> Even with patch 1, it still doesn't handle large syscall numbers -- it > >> just assumes they're not audited. > > > > All syscalls must be auditable. Meaning that if an arch goes above 2048, > > then we'll need to do some math to get it to fall back within the range. > > Off the top of my head, x32, some ARM variants, and some MIPS variants > have syscalls above 2048. That could be fixed by putting a subtraction in place to get the bit mask to map correctly. User space audit rules would need to fix that also. > auditsc has been disabled on the offending > ARM variant (because I noticed that the same issue affects seccomp, > and no one particularly wants to fix it), but I suspect that auditsc > is enabled but completely broken on whichever MIPS ABI has the issue. > I haven't checked. > > TBH, I think that it's silly to let the auditsc design be heavily > constrained by ia64 considerations -- I still think that the syscall > entry hooks could be removed completely with some effort on most > architectures and that performance would improve considerably. For > users who don't have syscall filter rules, performance might even > improve on ia64 -- I don't care how expensive syscall_get_args is, the > actual printk/auditd thing will dominate in cases where anything is > written. The last time I heard of benchmarking being done, audit's performance hit was negligible. That was about 4 years ago and there has been a whole lot of code churn since then. But it should in general be the cost of an 'if' statement unless auditing is enabled. If it is enabled, then you necessarily get the full treatment in case you trigger an event. > I wonder whether the syscall restart mechanism can be used to > thoroughly confused auditsc. I don't really know how syscall restarts > work. > > My point is: I don't know what guarantees auditsc is supposed to > provide, nor do I know how to evaluate whether the code is correct. There is an audit test suite that is used to verify that its working. Its not an exhaustive test suite, but it provides good coverage. > For users who aren't bound by Common Criteria or related things, I > suspect that syscall auditing (as opposed to, say, LSM-based auditing) > will provide dubious value at best. No, it works pretty good. You can see who is accessing what files pretty clearly. > Keep in mind that many syscalls take pointer arguments, and the auditsc code > can't really do anything sensible with them. All security relevant information is collected in auxiliary records if they are not directly readable as a syscall argument. This is a basic requirement. We are not required to capture all possible arguments. If you know of any security relevant parameters not captured, please let us know. -Steve ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text 2014-05-29 16:25 ` Steve Grubb @ 2014-05-29 16:46 ` Andy Lutomirski 0 siblings, 0 replies; 15+ messages in thread From: Andy Lutomirski @ 2014-05-29 16:46 UTC (permalink / raw) To: Steve Grubb Cc: linux-audit, Eric Paris, H. J. Lu, security@kernel.org, Philipp Kern, Greg Kroah-Hartman, linux-kernel@vger.kernel.org, H. Peter Anvin On Thu, May 29, 2014 at 9:25 AM, Steve Grubb <sgrubb@redhat.com> wrote: > On Thursday, May 29, 2014 09:04:10 AM Andy Lutomirski wrote: >> On Thu, May 29, 2014 at 6:05 AM, Steve Grubb <sgrubb@redhat.com> wrote: >> > On Wednesday, May 28, 2014 07:40:57 PM Andy Lutomirski wrote: >> >> >> - It assumes that syscall numbers are between 0 and 2048. >> >> >> >> >> > There could well be a bug here. Not questioning that. Although that >> >> > would be patch 1/2 >> >> >> >> Even with patch 1, it still doesn't handle large syscall numbers -- it >> >> just assumes they're not audited. >> > >> > All syscalls must be auditable. Meaning that if an arch goes above 2048, >> > then we'll need to do some math to get it to fall back within the range. >> >> Off the top of my head, x32, some ARM variants, and some MIPS variants >> have syscalls above 2048. > > That could be fixed by putting a subtraction in place to get the bit mask to > map correctly. User space audit rules would need to fix that also. > > >> auditsc has been disabled on the offending >> ARM variant (because I noticed that the same issue affects seccomp, >> and no one particularly wants to fix it), but I suspect that auditsc >> is enabled but completely broken on whichever MIPS ABI has the issue. >> I haven't checked. >> >> TBH, I think that it's silly to let the auditsc design be heavily >> constrained by ia64 considerations -- I still think that the syscall >> entry hooks could be removed completely with some effort on most >> architectures and that performance would improve considerably. For >> users who don't have syscall filter rules, performance might even >> improve on ia64 -- I don't care how expensive syscall_get_args is, the >> actual printk/auditd thing will dominate in cases where anything is >> written. > > The last time I heard of benchmarking being done, audit's performance hit was > negligible. That was about 4 years ago and there has been a whole lot of code > churn since then. But it should in general be the cost of an 'if' statement > unless auditing is enabled. If it is enabled, then you necessarily get the > full treatment in case you trigger an event. > The actual rule matching is reasonably inexpensive, but the killer is the fact that every system call is forced into the slow path. Without audit, this cost is paid by seccomp users and tasks that are being ptraced. With audit, every single syscall for every single task pays the full cost of a slow path system call. This is extra sad because, AFAICS, most of the syscall entry audit code shouldn't be necessary even for audit users. >> For users who aren't bound by Common Criteria or related things, I >> suspect that syscall auditing (as opposed to, say, LSM-based auditing) >> will provide dubious value at best. > > No, it works pretty good. You can see who is accessing what files pretty > clearly. Right, but I don't think it's the *syscall* part that's really necessary here. The fact that someone opened /etc/passwd is interesting. The fact that someone sys_opened (const char *)0x123456 is not. > >> Keep in mind that many syscalls take pointer arguments, and the auditsc code >> can't really do anything sensible with them. > > All security relevant information is collected in auxiliary records if they > are not directly readable as a syscall argument. This is a basic requirement. > We are not required to capture all possible arguments. If you know of any > security relevant parameters not captured, please let us know. > a5 and a6. The cmsg data in sendmsg (which is very security-relevant -- think of SCM_RIGHTS and SCM_CREDENTIALS). The destination for sendto. The whole payload of netlink messages. I don't know how many of these are actually captures. Plus, except for things like setuid and sigreturn, capturing parameters on entry shouldn't be needed anyway. Capturing at log time should be fine. If this magic capturing only happened for users who need it for compliance reasons, that would be one thing. But it happens for every single system call on Fedora. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2014-05-29 16:47 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-05-29 1:43 [PATCH v2 0/2] Fix auditsc DoS and mark it BROKEN Andy Lutomirski 2014-05-29 1:44 ` [PATCH v2 1/2] auditsc: audit_krule mask accesses need bounds checking Andy Lutomirski 2014-05-29 2:23 ` Eric Paris 2014-05-29 2:27 ` Andy Lutomirski 2014-05-29 2:43 ` Eric Paris 2014-05-29 2:46 ` Andy Lutomirski 2014-05-29 1:44 ` [PATCH v2 2/2] audit: Mark CONFIG_AUDITSYSCALL BROKEN and update help text Andy Lutomirski 2014-05-29 2:09 ` Eric Paris 2014-05-29 2:40 ` Andy Lutomirski 2014-05-29 2:54 ` Eric Paris 2014-05-29 3:01 ` Andy Lutomirski 2014-05-29 13:05 ` Steve Grubb 2014-05-29 16:04 ` Andy Lutomirski 2014-05-29 16:25 ` Steve Grubb 2014-05-29 16:46 ` Andy Lutomirski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox