Skip to content

Commit

Permalink
The attached patch addresses the problem with getting the audit daemon
Browse files Browse the repository at this point in the history
shutdown credential information. It creates a new message type 
AUDIT_TERM_INFO, which is used by the audit daemon to query who issued the 
shutdown. 

It requires the placement of a hook function that gathers the information. The 
hook is after the DAC & MAC checks and before the function returns. Racing 
threads could overwrite the uid & pid - but they would have to be root and 
have policy that allows signalling the audit daemon. That should be a 
manageable risk.

The userspace component will be released later in audit 0.7.2. When it 
receives the TERM signal, it queries the kernel for shutdown information. 
When it receives it, it writes the message and exits. The message looks 
like this:

type=DAEMON msg=auditd(1114551182.000) auditd normal halt, sending pid=2650 
uid=525, auditd pid=1685

Signed-off-by: Steve Grubb <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
  • Loading branch information
RH-steve-grubb authored and David Woodhouse committed May 6, 2005
1 parent 2512809 commit c2f0c7c
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 10 deletions.
25 changes: 17 additions & 8 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@
#include <linux/elf.h>

/* Request and reply types */
#define AUDIT_GET 1000 /* Get status */
#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
#define AUDIT_LIST 1002 /* List filtering rules */
#define AUDIT_ADD 1003 /* Add filtering rule */
#define AUDIT_DEL 1004 /* Delete filtering rule */
#define AUDIT_USER 1005 /* Send a message from user-space */
#define AUDIT_LOGIN 1006 /* Define the login id and informaiton */
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
#define AUDIT_GET 1000 /* Get status */
#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
#define AUDIT_LIST 1002 /* List filtering rules */
#define AUDIT_ADD 1003 /* Add filtering rule */
#define AUDIT_DEL 1004 /* Delete filtering rule */
#define AUDIT_USER 1005 /* Send a message from user-space */
#define AUDIT_LOGIN 1006 /* Define the login id and information */
#define AUDIT_SIGNAL_INFO 1010 /* Get information about sender of signal*/

#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */

/* Rule flags */
#define AUDIT_PER_TASK 0x01 /* Apply rule at task creation (not syscall) */
Expand Down Expand Up @@ -161,6 +163,11 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */

#ifdef __KERNEL__

struct audit_sig_info {
uid_t uid;
pid_t pid;
};

struct audit_buffer;
struct audit_context;
struct inode;
Expand Down Expand Up @@ -190,6 +197,7 @@ extern void audit_get_stamp(struct audit_context *ctx,
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
extern void audit_signal_info(int sig, struct task_struct *t);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
Expand All @@ -200,6 +208,7 @@ extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mo
#define audit_inode(n,i) do { ; } while (0)
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_perms(q,u,g,m) ({ 0; })
#define audit_signal_info(s,t) do { ; } while (0)
#endif

#ifdef CONFIG_AUDIT
Expand Down
14 changes: 13 additions & 1 deletion kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static int audit_failure = AUDIT_FAIL_PRINTK;

/* If audit records are to be written to the netlink socket, audit_pid
* contains the (non-zero) pid. */
static int audit_pid;
int audit_pid;

/* If audit_limit is non-zero, limit the rate of sending audit records
* to that number per second. This prevents DoS attacks, but results in
Expand All @@ -79,6 +79,10 @@ static int audit_rate_limit;
static int audit_backlog_limit = 64;
static atomic_t audit_backlog = ATOMIC_INIT(0);

/* The identity of the user shutting down the audit system. */
uid_t audit_sig_uid = -1;
pid_t audit_sig_pid = -1;

/* Records can be lost in several ways:
0) [suppressed in audit_alloc]
1) out of memory in audit_log_start [kmalloc of struct audit_buffer]
Expand Down Expand Up @@ -321,6 +325,7 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
case AUDIT_SET:
case AUDIT_ADD:
case AUDIT_DEL:
case AUDIT_SIGNAL_INFO:
if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
err = -EPERM;
break;
Expand All @@ -344,6 +349,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
uid_t loginuid; /* loginuid of sender */
struct audit_sig_info sig_data;

err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
if (err)
Expand Down Expand Up @@ -419,6 +425,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
err = -EOPNOTSUPP;
#endif
break;
case AUDIT_SIGNAL_INFO:
sig_data.uid = audit_sig_uid;
sig_data.pid = audit_sig_pid;
audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
0, 0, &sig_data, sizeof(sig_data));
break;
default:
err = -EINVAL;
break;
Expand Down
19 changes: 19 additions & 0 deletions kernel/auditsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,3 +1056,22 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
context->aux = (void *)ax;
return 0;
}

void audit_signal_info(int sig, struct task_struct *t)
{
extern pid_t audit_sig_pid;
extern uid_t audit_sig_uid;
extern int audit_pid;

if (unlikely(audit_pid && t->pid == audit_pid)) {
if (sig == SIGTERM || sig == SIGHUP) {
struct audit_context *ctx = current->audit_context;
audit_sig_pid = current->pid;
if (ctx)
audit_sig_uid = ctx->loginuid;
else
audit_sig_uid = current->uid;
}
}
}

7 changes: 6 additions & 1 deletion kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/ptrace.h>
#include <linux/posix-timers.h>
#include <linux/signal.h>
#include <linux/audit.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
Expand Down Expand Up @@ -658,7 +659,11 @@ static int check_kill_permission(int sig, struct siginfo *info,
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
return error;
return security_task_kill(t, info, sig);

error = security_task_kill(t, info, sig);
if (!error)
audit_signal_info(sig, t); /* Let audit system see the signal */
return error;
}

/* forward decl */
Expand Down
1 change: 1 addition & 0 deletions security/selinux/nlmsgtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
{ AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
{ AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
};


Expand Down

0 comments on commit c2f0c7c

Please sign in to comment.