lkml.org 
[lkml]   [2016]   [Apr]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC] Create an audit record of USB specific details
    Date
    From: Wade Mealing <wmealing@redhat.com>

    Gday,

    I'm looking to create an audit trail for when devices are added or removed
    from the system.

    The audit subsystem is a logging subsystem in kernel space that can be
    used to create advanced filters on generated events. It has partnered userspace
    utilities ausearch, auditd, aureport, auditctl which work exclusively on audit
    records.

    These tools are able to set filters to "trigger" on specific in-kernel events
    specified by privileged users. While the userspace tools can create audit
    events these are not able to be handled intelligently (decoded,filtered or
    ignored) as kernel generated audit events are.

    I have this working at the moment with the USB subsystem (as an example).
    Its been suggested that I use systemd-udev however this means that the audit
    tools (ausearch) will not be able to index these records.

    Here is an example of picking out the AUDIT_DEVICE record type for example.

    > # ausearch -l -i -ts today -m AUDIT_DEVICE
    > ----
    > type=AUDIT_DEVICE msg=audit(31/03/16 16:37:15.642:2) : action=add
    > manufacturer=Linux 4.4.0-ktest ehci_hcd product=EHCI Host Controller
    > serial=0000:00:06.7 major=189 minor=0 bus="usb"

    Admittedly this is only the USB device type at the moment, but I'd like to break
    this
    out into other bus types at some time in the future, gotta start somewhere.

    Thanks,

    Wade Mealing

    ---
    include/uapi/linux/audit.h | 1 +
    init/Kconfig | 10 ++++++
    kernel/Makefile | 1 +
    kernel/audit_device.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++
    4 files changed, 102 insertions(+)
    create mode 100644 kernel/audit_device.c

    diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
    index 843540c..344c97b 100644
    --- a/include/uapi/linux/audit.h
    +++ b/include/uapi/linux/audit.h
    @@ -110,6 +110,7 @@
    #define AUDIT_SECCOMP 1326 /* Secure Computing event */
    #define AUDIT_PROCTITLE 1327 /* Proctitle emit event */
    #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */
    +#define AUDIT_DEVICE_CHANGE 1330 /* Device added/removed to the system */

    #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
    #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
    diff --git a/init/Kconfig b/init/Kconfig
    index 2232080..e171f74 100644
    --- a/init/Kconfig
    +++ b/init/Kconfig
    @@ -309,6 +309,16 @@ config AUDITSYSCALL
    def_bool y
    depends on AUDIT && HAVE_ARCH_AUDITSYSCALL

    +config DEVICE_AUDIT
    + bool "Create audit records for devices added to the systems"
    + depends on AUDIT && USB
    + default y
    + help
    + Generate audit events in the system for USB devices that
    + are added or removed from the system from boot time onwards.
    + Records the manufacturer, product serial number, device major
    + and minor number and bus which the device was added to.
    +
    config AUDIT_WATCH
    def_bool y
    depends on AUDITSYSCALL
    diff --git a/kernel/Makefile b/kernel/Makefile
    index 53abf00..909c869 100644
    --- a/kernel/Makefile
    +++ b/kernel/Makefile
    @@ -68,6 +68,7 @@ obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
    obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
    obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o audit_fsnotify.o
    obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
    +obj-$(CONFIG_DEVICE_AUDIT) += audit_device.o
    obj-$(CONFIG_GCOV_KERNEL) += gcov/
    obj-$(CONFIG_KPROBES) += kprobes.o
    obj-$(CONFIG_KGDB) += debug/
    diff --git a/kernel/audit_device.c b/kernel/audit_device.c
    new file mode 100644
    index 0000000..8dfdf04
    --- /dev/null
    +++ b/kernel/audit_device.c
    @@ -0,0 +1,90 @@
    +#include <linux/kernel.h>
    +#include <linux/module.h>
    +#include <linux/usb.h>
    +#include <linux/usb/hcd.h>
    +#include <linux/slab.h>
    +#include <linux/notifier.h>
    +#include <linux/mutex.h>
    +#include <linux/device.h>
    +#include <linux/usb.h>
    +#include <linux/audit.h>
    +#include <linux/kdev_t.h>
    +
    +static void log_string(struct audit_buffer *ab, char *key, char *val)
    +{
    + if (val) {
    + audit_log_format(ab, " %s=", key);
    + audit_log_untrustedstring(ab, val);
    + }
    + else {
    + audit_log_format(ab, " %s=%s", key, "?");
    + }
    +
    +}
    +
    +static void log_major_minor(struct audit_buffer *ab, struct device *dev)
    +{
    + if (dev && dev->devt) {
    + audit_log_format(ab, " major=%d", MAJOR(dev->devt));
    + audit_log_format(ab, " minor=%d", MINOR(dev->devt));
    + }
    +}
    +
    +/* Blocking call when device has reference and will keep reference until
    + * all notifiers are done, no usb_dev_get/ usb_dev_put required.
    + */
    +static int audit_notify(struct notifier_block *self,
    + unsigned long action, void *d)
    +{
    + struct usb_device *usbdev = (struct usb_device *)d;
    + char *op;
    + struct audit_buffer *ab;
    +
    + switch (action) {
    + case USB_DEVICE_ADD:
    + op = "add";
    + break;
    + case USB_DEVICE_REMOVE:
    + op = "remove";
    + break;
    + default: /* ignore any other USB events */
    + return NOTIFY_DONE;
    + }
    +
    + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_DEVICE_CHANGE);
    +
    + if (ab) {
    + audit_log_format(ab, "action=%s", op);
    + log_string(ab, "manufacturer", usbdev->manufacturer);
    + log_string(ab, "product", usbdev->product);
    + log_string(ab, "serial", usbdev->serial);
    + log_major_minor(ab, &usbdev->dev);
    + log_string(ab, "bus", "usb");
    + audit_log_end(ab);
    + }
    +
    + return NOTIFY_DONE;
    +}
    +
    +static struct notifier_block audit_nb = {
    + .notifier_call = audit_notify,
    + .priority = INT_MIN
    +};
    +
    +static int __init audit_device_init(void)
    +{
    + pr_info("Registering usb audit notification callback\n");
    + usb_register_notify(&audit_nb);
    + return 0;
    +}
    +
    +static void __exit audit_device_exit(void)
    +{
    + pr_info("Unregistering usb audit notification callback\n");
    + usb_unregister_notify(&audit_nb);
    +}
    +
    +module_init(audit_device_init);
    +module_exit(audit_device_exit);
    +
    +MODULE_LICENSE("GPL");
    --
    1.8.3.1
    \
     
     \ /
      Last update: 2016-04-04 06:42    [W:5.357 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site