On Tue, 2005-04-05 at 17:54 -0400, Steve Grubb wrote:
This is the discussion about meeting the CAPP requirement to log the
real
user's ID that initiated a shutdown. The core issue is that shutdown sequence
is started by a SIGTERM. I can use sigaction to get some additional
information delivered to the signal handler. All you get is pid. It would be
racy to trace that back to the caller and see what their loginuid is.
Klaus proposed the following patch. Its an OK solution, but I was wanting to
see if there are alternatives.
How about this? You can replace (or augment) the audit_log() with a
printk() if you need to, but if you're shutting down gracefully due to
SIGTERM you'll catch the message anyway, right?
--- linux-2.6.9/kernel/audit.c.p20019 2005-04-06 13:06:39.000000000 +0100
+++ linux-2.6.9/kernel/audit.c 2005-04-06 13:06:39.000000000 +0100
@@ -68,7 +68,7 @@ static int audit_failure = AUDIT_FAIL_PR
/* 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
--- linux-2.6.9/kernel/signal.c.p20019 2005-04-06 13:06:39.000000000 +0100
+++ linux-2.6.9/kernel/signal.c 2005-04-06 13:07:29.000000000 +0100
@@ -21,6 +21,7 @@
#include <linux/binfmts.h>
#include <linux/security.h>
#include <linux/ptrace.h>
+#include <linux/audit.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -623,7 +624,7 @@ static int check_kill_permission(int sig
int error = -EINVAL;
if (sig < 0 || sig > _NSIG)
return error;
- error = -EPERM;
+
if ((!info || ((unsigned long)info != 1 &&
(unsigned long)info != 2 && SI_FROMUSER(info)))
&& ((sig != SIGCONT) ||
@@ -631,8 +632,12 @@ static int check_kill_permission(int sig
&& (current->euid ^ t->suid) && (current->euid ^
t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
- return error;
- return security_task_kill(t, info, sig);
+ error = -EPERM;
+ else
+ error = security_task_kill(t, info, sig);
+
+ audit_kill_permission(sig, info, t, error);
+ return error;
}
/* forward decl */
--- linux-2.6.9/include/linux/audit.h.p20019 2005-04-06 13:06:39.000000000 +0100
+++ linux-2.6.9/include/linux/audit.h 2005-04-06 13:06:39.000000000 +0100
@@ -234,6 +234,15 @@ extern void audit_send_reply(int pi
int done, int multi,
void *payload, int size);
extern void audit_log_lost(const char *message);
+static inline void audit_kill_permission(int sig, struct siginfo *info,
+ struct task_struct *t, int err)
+{
+ extern int audit_pid; /* Nothing external _except_ for this should use it */
+
+ if (unlikely(t->pid == audit_pid))
+ audit_log(NULL, "attempt to signal audit daemon: error=%d signal=%d pid=%d
auid=%d",
+ err, sig, current->pid, audit_get_loginuid(current->audit_context));
+}
#else
#define audit_log(t,f,...) do { ; } while (0)
#define audit_log_start(t) ({ NULL; })
@@ -249,6 +258,7 @@ extern void audit_log_lost(const ch
#define audit_set_backlog_limit(l) do { ; } while (0)
#define audit_set_enabled(s) do { ; } while (0)
#define audit_set_failure(s) do { ; } while (0)
+#define audit_kill_permission(s,i,t,e) do { ; } while (0)
#endif
#endif
#endif
--
dwmw2