Initialization

Initialization of the audit subsystem is performed by audit_init. In addition to setting up data structures, the function creates a netlink socket used for communication with the userland as follows:

kernel/audit.c static int _init audit_init(void)

audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, audit_receive, NULL, THIS_MODULE);

The code snippet reveals that audit_receive is responsible for processing any received packets. It implements a dispatcher that is discussed later.

Note that there is a kernel command line parameter (audit) that can be set to either 0 or 1. The value is stored in the global variable enable_audit during initialization. If it is set to 0, auditing is completely disabled. When it is set to 1, auditing is enabled, but since no rules are supplied by default, no audit events will be generated unless appropriate rules are given to the kernel.

There is also a kernel thread for the audit mechanism. Instead of starting the thread during subsystem initialization, a slightly unconventional way has been chosen: As soon as the userspace daemon auditd sends the first message, the kernel thread kaudit_task is started. The function executed by the thread is kauditd_thread, which is responsible for sending already prepared messages from the kernel to the userspace daemon. Note that this daemon is necessary because an audit event may end within an interrupt handler, and since the netlink functions cannot be called from here, the finished audit records are put on a queue and processed later by the kernel daemon that sends them back to userspace. Sending and receiving is performed with a simple netlink operation and standard queue processing, as discussed in Chapter 12.

Continue reading here: Processing Requests

Was this article helpful?

0 0