Updated test kernels available.
by David Woodhouse
I've just put kernel-2.6.9-5.EL.audit.3 into the yum repository at
ftp://ftp.uk.linux.org/pub/people/dwmw2/audit/
I've also created metadata for the new versions of yum this time, in
addition to the old version. It contains version two of the auditfs
patch, and a small fix for the ppc64 syscall auditing.
I don't like the fact that audit_syscall_exit() takes a single int as a
return value. Surely it should take a 'long' and _also_ a boolean status
value, since some architectures signal errors by some means other than
just a small negative number in the return value.
--
dwmw2
19 years, 11 months
[PATCH] Auditd string termination bug fix
by Junji Kanemaru
Hi,
Attached is simple fix for auditd that it assumed incoming msg
is c string(null terminated) but they are not sometimes.
I briefly looked into kernel audit code, it looks like it is sending out
exact length of string, no '\0' at the end of message string so
auditd's log sometimes corrupted.
It's a small patch from my plugin support auditd.
-- Junji Kaneamru
Linuon Inc.
Tokyo Japan
19 years, 11 months
[RFC][PATCH] (#2) Prelim in-kernel file system auditing support
by Timothy R. Chavez
Alright,
Once again, thank you to Serge, Chris, and David for all the insight.
Here's the latest patch incorporating many of the changes you all
suggested. There are still some things missing and not fully tested
(for instance, the locking).
TODO:
* Make filesystem auditing enabled/disabled at runtime
* Re-add comments with proper DocBook formatting
* Remove Makefile changes
* Move struct audit_file to a slab cache
Am I forgetting something? (Soooo tired ;-))
I'd appreciate any and all comments / feedback. Thank you.
--
- Timothy R. Chavez
19 years, 11 months
Suggestions based on my experiences so far
by Avishay Traeger
I'd first like to say that I am a big fan of this auditing software, and
it has made life good for me (I am currently working on a project where
we are investigating system call behavior to see if any optimizations
are possible). I know this project is still in its early stages, but I
do have some suggestions:
1. I tried to do 'kill -HUP auditd' to get the daemon to re-read the
configuration file (in order to make it write to a new log file in case
the original got too big), but this did not work. As I understand it,
this is should be the expected behavior for daemons.
2. The name of the process (or command) which invoked the system call is
not logged (tsk->comm). I think it would not only be good to know
exactly what invoked it, but to know if the process associated with a
particular PID changes (if process P1 has PID N, invokes some system
calls, exits, and then process P2 gets PID N, invokes other system
calls, then P1 and P2 will be indistinguishable).
3. Maybe a way to set the log format would be helpful, so that you could
include only the information you need and keep log sizes to a minimum.
4. Since we can trace both entries and exits, there should be a way to
know what is an entry and what is an exit (I'm pretty sure you can't do
this right now). Also, it would be good if you could somehow correlate
entries and exits.
Avishay Traeger
19 years, 11 months
Plugin support for user space auditd daemon
by Linux
Hi,
I did some work on plugin support for user land audit daemon, auditd.
It is kinda early release but I'd like to hear comments and feedbacks
from people on this list. I talked with Steve(Grubb) last a couple of
weeks about this effort. He agreed the design and suggested post
a patch here. But it is not a small patch, I put it on my server.
Please download it and take a look source code and run it on your
machine to see if it works correctly. Any feedbacks, comments and
requests(and complains?) are welcome.
http://download.linuon.com/audit/audit.html
Thank you,
-- Junji Kanemaru
Linuon Inc.
Tokyo Japan
19 years, 11 months
[RFC][PATCH] loginuid through procfs (+ a question)
by Serge Hallyn
Attached is a first stab at setting loginuid through /proc/$$/loginuid.
Compiled and tested here.
A related question: On receipt of a AUDIT_USER message, we log the pid
and uid, but not the loginuid. Is it ok to force the user-space code to
search through previous log entries to determine the correct loginuid,
or would we prefer to send the loginuid in the log entry?
Note: this is on top of Stephen's loginuid inheritence fix, and my
previous CAP_AUDIT_* patch on 2.6.10-bk9.
thanks,
-serge
--
Serge Hallyn <serue(a)us.ibm.com>
19 years, 11 months
[PATCH] [audit] handle loginuid through proc
by Serge E. Hallyn
The audit subsystem uses netlink messages to request loginuid
changes. Due to the sensitivity of loginuid, netlink appears to
be insufficient. For instance, it is not easy to guarantee that
the loginuid message will be handled before any other auditable
actions, and there is even the remote possibility of the process
terminating and another process with the same pid being created
before the message is handled. Finally, other kernel code, in
particular selinux, is interested in easily querying the loginuid
for inclusion in its own messages.
The following patch moves loginuid handling from netlink to the
/proc/$$/loginuid file, and adds a audit_get_loginuid() function.
It also includes Stephen Smalley's patch to correctly inherit the
loginuid on fork. It has been actively discussed on the
linux-audit mailing list.
Please apply.
thanks,
-serge
Signed-off-by: Serge Hallyn <serue(a)us.ibm.com>
Index: linux-2.6.10/fs/proc/base.c
===================================================================
--- linux-2.6.10.orig/fs/proc/base.c 2005-01-27 10:25:39.585367912 -0600
+++ linux-2.6.10/fs/proc/base.c 2005-01-27 10:51:02.915786488 -0600
@@ -71,6 +71,9 @@ enum pid_directory_inos {
PROC_TGID_ATTR_EXEC,
PROC_TGID_ATTR_FSCREATE,
#endif
+#ifdef CONFIG_AUDITSYSCALL
+ PROC_TGID_LOGINUID,
+#endif
PROC_TGID_FD_DIR,
PROC_TID_INO,
PROC_TID_STATUS,
@@ -97,6 +100,9 @@ enum pid_directory_inos {
PROC_TID_ATTR_EXEC,
PROC_TID_ATTR_FSCREATE,
#endif
+#ifdef CONFIG_AUDITSYSCALL
+ PROC_TID_LOGINUID,
+#endif
PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */
};
@@ -133,6 +139,9 @@ static struct pid_entry tgid_base_stuff[
#ifdef CONFIG_SCHEDSTATS
E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
#endif
+#ifdef CONFIG_AUDITSYSCALL
+ E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
+#endif
{0,0,NULL,0}
};
static struct pid_entry tid_base_stuff[] = {
@@ -158,6 +167,9 @@ static struct pid_entry tid_base_stuff[]
#ifdef CONFIG_SCHEDSTATS
E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
#endif
+#ifdef CONFIG_AUDITSYSCALL
+ E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
+#endif
{0,0,NULL,0}
};
@@ -661,6 +673,71 @@ static struct inode_operations proc_mem_
.permission = proc_permission,
};
+#ifdef CONFIG_AUDITSYSCALL
+#define TMPBUFLEN 21
+static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode * inode = file->f_dentry->d_inode;
+ struct task_struct *task = proc_task(inode);
+ ssize_t length;
+ char tmpbuf[TMPBUFLEN];
+
+ length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
+ audit_get_loginuid(task->audit_context));
+ return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode * inode = file->f_dentry->d_inode;
+ char *page, *tmp;
+ ssize_t length;
+ struct task_struct *task = proc_task(inode);
+ uid_t loginuid;
+
+ if (!capable(CAP_AUDIT_CONTROL))
+ return -EPERM;
+
+ if (current != task)
+ return -EPERM;
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+
+ if (*ppos != 0) {
+ /* No partial writes. */
+ return -EINVAL;
+ }
+ page = (char*)__get_free_page(GFP_USER);
+ if (!page)
+ return -ENOMEM;
+ length = -EFAULT;
+ if (copy_from_user(page, buf, count))
+ goto out_free_page;
+
+ loginuid = simple_strtoul(page, &tmp, 10);
+ if (tmp == page) {
+ length = -EINVAL;
+ goto out_free_page;
+
+ }
+ length = audit_set_loginuid(task->audit_context, loginuid);
+ if (likely(length == 0))
+ length = count;
+
+out_free_page:
+ free_page((unsigned long) page);
+ return length;
+}
+
+static struct file_operations proc_loginuid_operations = {
+ .read = proc_loginuid_read,
+ .write = proc_loginuid_write,
+};
+#endif
+
static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
@@ -1336,6 +1413,12 @@ static struct dentry *proc_pident_lookup
ei->op.proc_read = proc_pid_schedstat;
break;
#endif
+#ifdef CONFIG_AUDITSYSCALL
+ case PROC_TID_LOGINUID:
+ case PROC_TGID_LOGINUID:
+ inode->i_fop = &proc_loginuid_operations;
+ break;
+#endif
default:
printk("procfs: impossible type (%d)",p->type);
iput(inode);
Index: linux-2.6.10/include/linux/audit.h
===================================================================
--- linux-2.6.10.orig/include/linux/audit.h 2004-12-24 15:34:57.000000000 -0600
+++ linux-2.6.10/include/linux/audit.h 2005-01-27 10:46:57.887036520 -0600
@@ -114,12 +114,6 @@ struct audit_status {
__u32 backlog; /* messages waiting in queue */
};
-struct audit_login {
- __u32 loginuid;
- int msglen;
- char msg[1024];
-};
-
struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
__u32 flags; /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
__u32 action; /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
@@ -155,6 +149,7 @@ extern int audit_receive_filter(int typ
extern void audit_get_stamp(struct audit_context *ctx,
struct timespec *t, int *serial);
extern int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
+extern uid_t audit_get_loginuid(struct audit_context *ctx);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
@@ -163,6 +158,7 @@ extern int audit_set_loginuid(struct au
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
#define audit_inode(n,i,d) do { ; } while (0)
+#define audit_get_loginuid(c) ({ -1; })
#endif
#ifdef CONFIG_AUDIT
Index: linux-2.6.10/kernel/audit.c
===================================================================
--- linux-2.6.10.orig/kernel/audit.c 2005-01-27 10:25:43.529768272 -0600
+++ linux-2.6.10/kernel/audit.c 2005-01-27 10:46:57.888036368 -0600
@@ -145,6 +145,11 @@ struct audit_buffer {
int count; /* Times requeued */
};
+void audit_set_type(struct audit_buffer *ab, int type)
+{
+ ab->type = type;
+}
+
struct audit_entry {
struct list_head list;
struct audit_rule rule;
@@ -312,7 +317,6 @@ static int audit_netlink_ok(kernel_cap_t
case AUDIT_GET:
case AUDIT_LIST:
case AUDIT_SET:
- case AUDIT_LOGIN:
case AUDIT_ADD:
case AUDIT_DEL:
if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
@@ -334,7 +338,6 @@ static int audit_receive_msg(struct sk_b
u32 uid, pid, seq;
void *data;
struct audit_status *status_get, status_set;
- struct audit_login *login;
int err;
struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
@@ -397,27 +400,6 @@ static int audit_receive_msg(struct sk_b
ab->pid = pid;
audit_log_end(ab);
break;
- case AUDIT_LOGIN:
- if (nlh->nlmsg_len < sizeof(struct audit_login))
- return -EINVAL;
- login = (struct audit_login *)data;
- ab = audit_log_start(NULL);
- if (ab) {
- audit_log_format(ab, "login pid=%d uid=%d loginuid=%d"
- " length=%d msg='%.1024s'",
- pid, uid,
- login->loginuid,
- login->msglen,
- login->msg);
- ab->type = AUDIT_LOGIN;
- ab->pid = pid;
- audit_log_end(ab);
- }
-#ifdef CONFIG_AUDITSYSCALL
- err = audit_set_loginuid(current->audit_context,
- login->loginuid);
-#endif
- break;
case AUDIT_ADD:
case AUDIT_DEL:
if (nlh->nlmsg_len < sizeof(struct audit_rule))
Index: linux-2.6.10/kernel/auditsc.c
===================================================================
--- linux-2.6.10.orig/kernel/auditsc.c 2005-01-27 10:25:43.655749120 -0600
+++ linux-2.6.10/kernel/auditsc.c 2005-01-27 10:46:57.890036064 -0600
@@ -547,8 +547,8 @@ int audit_alloc(struct task_struct *tsk)
/* Preserve login uid */
context->loginuid = -1;
- if (tsk->audit_context)
- context->loginuid = tsk->audit_context->loginuid;
+ if (current->audit_context)
+ context->loginuid = current->audit_context->loginuid;
tsk->audit_context = context;
set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
@@ -903,12 +903,27 @@ void audit_get_stamp(struct audit_contex
}
}
+extern int audit_set_type(struct audit_buffer *ab, int type);
+
int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid)
{
if (ctx) {
- if (loginuid < 0)
- return -EINVAL;
+ struct audit_buffer *ab;
+
+ ab = audit_log_start(NULL);
+ if (ab) {
+ audit_log_format(ab, "login pid=%d uid=%u "
+ "old loginuid=%u new loginuid=%u",
+ ctx->pid, ctx->uid, ctx->loginuid, loginuid);
+ audit_set_type(ab, AUDIT_LOGIN);
+ audit_log_end(ab);
+ }
ctx->loginuid = loginuid;
}
return 0;
}
+
+uid_t audit_get_loginuid(struct audit_context *ctx)
+{
+ return ctx ? ctx->loginuid : -1;
+}
19 years, 11 months
repost of loginuid patches
by Serge Hallyn
Attached are the two loginuid patches which I believe we need. They are
to be applied on top of the audit-caps patch which I posted to lkml last
week.
loginuid-proc.patch incorporates Stephen's loginuid inheritence fix,
removes the AUDIT_LOGINUID netlink message, and creates /proc/$
$/loginuid when CONFIG_AUDITSYSCALL is defined.
netlink-loginuid.patch adds the loginuid to the netlink credentials. It
uses this to log the sender's loginuid on receipt of a audit control
message. It also causes the audit control log entries to be created
using audit_log_start(NULL, instead of audit_log_start(current-
>audit_context, since current->audit_context can be unrelated to the
process which sent the message.
thanks,
-serge
--
Serge Hallyn <serue(a)us.ibm.com>
19 years, 11 months
Question: netlink_unicast and thread
by Linux
Hi,
I have a quick question. Could be showing my ignorance though...
I'm working on plugin interface for auditd now. It is almost done
but I have some problem with netlink.
Actually I moved almost all current auditd into plugin which is
loaded boot time. Then auditd main process creates threads
for receiver, interpreter and consumer. It seems working fine
with my test program but when I tried to read from netlink
to receive audit messages from receiver thread it fails.
The error is:
"Error receiving netlink packet (Resource temporarily unavailable)"
It seems that netlink is only accessible from main process context.
Since getpid() returns main process ID there's no way to let
netlink know it is being called from thread(s) of the process.
I tried thread ID by calling pthread_self(), didn't work either.
To repro same problem with original code(no threads), I moved
audit_get_reply() stuff in auditd.c to thread loop in auditd-event.c.
It was same. Same error.
Could anyone out there enlighten me how to get threads working
with netlink?
Thanks,
-- Junji Kanemaru
Linuon Inc,
Tokyo Japan
19 years, 11 months
Syscall auditing on ppc64 lacks correct return codes.
by David Woodhouse
We were pretending that every syscall returned zero. Don't do that.
===== arch/ppc64/kernel/entry.S 1.51 vs edited =====
--- 1.51/arch/ppc64/kernel/entry.S Thu Jan 13 09:48:36 2005
+++ edited/arch/ppc64/kernel/entry.S Thu Jan 20 16:14:50 2005
@@ -231,6 +231,7 @@
syscall_exit_trace:
std r3,GPR3(r1)
bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
bl .do_syscall_trace_leave
REST_NVGPRS(r1)
ld r3,GPR3(r1)
@@ -324,6 +325,7 @@
ld r4,TI_FLAGS(r4)
andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
beq+ 81f
+ addi r3,r1,STACK_FRAME_OVERHEAD
bl .do_syscall_trace_leave
81: b .ret_from_except
===== arch/ppc64/kernel/ptrace.c 1.13 vs edited =====
--- 1.13/arch/ppc64/kernel/ptrace.c Fri Dec 17 08:09:09 2004
+++ edited/arch/ppc64/kernel/ptrace.c Thu Jan 20 16:24:12 2005
@@ -313,10 +313,10 @@
do_syscall_trace();
}
-void do_syscall_trace_leave(void)
+void do_syscall_trace_leave(struct pt_regs *regs)
{
if (unlikely(current->audit_context))
- audit_syscall_exit(current, 0); /* FIXME: pass pt_regs */
+ audit_syscall_exit(current, regs->result);
if ((test_thread_flag(TIF_SYSCALL_TRACE)
|| test_thread_flag(TIF_SINGLESTEP))
--
dwmw2
19 years, 11 months