Bug 89225 - libaudit integration now duplicated between SELinux and AppArmor
Summary: libaudit integration now duplicated between SELinux and AppArmor
Status: RESOLVED FIXED
Alias: None
Product: dbus
Classification: Unclassified
Component: core (show other bugs)
Version: git master
Hardware: Other All
: medium normal
Assignee: Simon McVittie
QA Contact: D-Bus Maintainers
URL:
Whiteboard: review?
Keywords: patch
Depends on:
Blocks:
 
Reported: 2015-02-19 12:26 UTC by Simon McVittie
Modified: 2015-08-07 11:57 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:


Attachments
[1/2] bus: move shared libaudit code to a new audit.[ch] (17.41 KB, patch)
2015-02-19 12:27 UTC, Simon McVittie
Details | Splinter Review
[2/2] audit: use DBUS_SYSTEM_LOG_WARNING if we cannot open the audit fd (1.99 KB, patch)
2015-02-19 12:28 UTC, Simon McVittie
Details | Splinter Review
audit: only check for CAP_AUDIT_WRITE once, during initialization (1.04 KB, patch)
2015-07-03 16:35 UTC, Simon McVittie
Details | Splinter Review

Description Simon McVittie 2015-02-19 12:26:40 UTC
It's feasible to compile dbus with both SELinux and AppArmor enabled, and this configuration is sometimes even useful (on distributions that do not have a recommended/default-enabled LSM but have some level of non-default support for both, such as Debian).

The two LSM integration layers currently duplicate some code to hook up an audit fd, and will in fact open both fds for the system bus.
Comment 1 Simon McVittie 2015-02-19 12:27:46 UTC
Created attachment 113660 [details] [review]
[1/2] bus: move shared libaudit code to a new audit.[ch]

This fixes various duplicated libaudit interactions in both
SELinux and AppArmor code paths, including opening two audit sockets
if both SELinux and AppArmor were enabled at compile time.
In particular, audit.c is now the only user of libcap-ng.

This commit is not intended to introduce any functional changes,
except for the de-duplication.

The actual audit_log_user_avc_message() call is still duplicated,
because the SELinux and AppArmor code paths use different mechanisms
to compose the audit message: the SELinux path uses a statically-sized
buffer on the stack which might be subject to truncation, whereas
the AppArmor path uses malloc() (via DBusString) and falls back to
using syslog on a memory allocation failure.

---

"No functional changes" means that, in particular, I have not applied (the equivalent of) Laurent's proposed changes from Bug #83856.
Comment 2 Simon McVittie 2015-02-19 12:28:34 UTC
Created attachment 113661 [details] [review]
[2/2] audit: use DBUS_SYSTEM_LOG_WARNING if we cannot open the  audit fd
Comment 3 Simon McVittie 2015-02-19 12:34:30 UTC
Comment on attachment 113660 [details] [review]
[1/2] bus: move shared libaudit code to a new audit.[ch]

Review of attachment 113660 [details] [review]:
-----------------------------------------------------------------

::: bus/audit.c
@@ +60,5 @@
> +      if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)
> +        return;
> +      /* If user bus, bail out */
> +      if (errno == EPERM && getuid() != 0)
> +        return;

In fact getuid() is always nonzero here in practice, because we call this after dropping privileges. Out of scope for this particular bug, though.

Laurent says this doesn't actually fail with EPERM in practice but, again, out of scope for this particular bug.

::: bus/bus.c
@@ +972,4 @@
>  	  goto failed;
>  	}
>  
> +      bus_audit_init ();

I know this is still inside the "if (we just dropped privileges)" block, and I know Laurent wants to move it outside that block so that the session bus can write to the audit log if it happens to have CAP_AUDIT_WRITE, but that's out of scope for this particular bug.

::: bus/selinux.c
@@ +132,5 @@
>    {
> +    /* This should really be a DBusString, but DBusString allocates
> +     * memory dynamically; before switching it, we need to check with
> +     * SELinux people that it would be OK for this to fall back to
> +     * syslog if OOM, like the equivalent AppArmor code does. */

Fixing this is out of scope for this particular bug, but I did add a comment.

@@ +135,5 @@
> +     * SELinux people that it would be OK for this to fall back to
> +     * syslog if OOM, like the equivalent AppArmor code does. */
> +    char buf[PATH_MAX*2];
> +
> +    /* FIXME: need to change this to show real user */

This is a pre-existing FIXME in both SELinux and AppArmor. If someone tells us what "real user" means, we might even be able to fix it. As far as I can see it's been here ever since Havoc imported libaudit patches from Fedora in 2007.
Comment 4 Simon McVittie 2015-02-19 12:35:08 UTC
Comment on attachment 113661 [details] [review]
[2/2] audit: use DBUS_SYSTEM_LOG_WARNING if we cannot open the  audit fd

Review of attachment 113661 [details] [review]:
-----------------------------------------------------------------

::: bus/audit.c
@@ +55,5 @@
>    audit_fd = audit_open ();
>  
>    if (audit_fd < 0)
>      {
> +      int e = errno;

Saved because getuid() could conceivably clobber errno.
Comment 5 Simon McVittie 2015-02-19 12:36:43 UTC
I think these are ready for review, but I also need to test them on a system that actively uses audit (Ubuntu with AppArmor seems to be suitable).
Comment 6 Colin Walters 2015-06-19 13:20:53 UTC
Comment on attachment 113660 [details] [review]
[1/2] bus: move shared libaudit code to a new audit.[ch]

Review of attachment 113660 [details] [review]:
-----------------------------------------------------------------

Ignore the second comment, obviated by the first.

Looks like a straightforward code cleanup to me, I don't see
any issues.

::: bus/audit.c
@@ +80,5 @@
> +    capng_get_caps_process ();
> +
> +    if (!capng_have_capability (CAPNG_EFFECTIVE, CAP_AUDIT_WRITE))
> +      return -1;
> +

The effective caps aren't going to change after process start, so rechecking
them here seems odd, I'd have expected it in bus_audit_init().

Anyways I think this was there originally, and not a big deal.

::: bus/selinux.c
@@ +125,5 @@
>  
>    va_start(ap, fmt);
>  
>  #ifdef HAVE_LIBAUDIT
> +  audit_fd = bus_audit_get_fd ();

This is relatively minor and can be done later, but I'd like to see this fd cached somewhere.
Comment 7 Simon McVittie 2015-07-03 15:50:02 UTC
Any thoughts on patch 2/2?

(In reply to Colin Walters from comment #6)
> The effective caps aren't going to change after process start, so rechecking
> them here seems odd, I'd have expected it in bus_audit_init().

This isn't a regression: caps were previously checked in SELinux's log_callback() and AppArmor's log_message(), so, just as expensive (or not) as the current implementation.

Would you like me to move it to bus_audit_init(), a behaviour change relative to the previous code, as well as doing the refactoring that I've already done here?

> >  #ifdef HAVE_LIBAUDIT
> > +  audit_fd = bus_audit_get_fd ();
> 
> This is relatively minor and can be done later, but I'd like to see this fd
> cached somewhere.

If I move the caps check into bus_audit_init(), there's nothing to cache, because the function would become a trivial accessor for a static global; so there would be little point in having a cache for the fd in each LSM's module. Is that what you meant by ignoring your second comment?
Comment 8 Simon McVittie 2015-07-03 16:35:18 UTC
Created attachment 116931 [details] [review]
audit: only check for CAP_AUDIT_WRITE once, during  initialization

---

Colin, is this what you wanted?

(This *is* a behaviour change; it makes sense to me, but again, I haven't yet tested it on a properly audit-enabled system.)
Comment 9 Colin Walters 2015-07-04 14:50:38 UTC
Comment on attachment 116931 [details] [review]
audit: only check for CAP_AUDIT_WRITE once, during  initialization

Review of attachment 116931 [details] [review]:
-----------------------------------------------------------------

Looks reasonable to me, yes.
Comment 10 Simon McVittie 2015-08-07 11:57:28 UTC
Fixed in 1.9.20.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.