audit-0.6.2 released
by Steve Grubb
Hi,
A new version of auditd has been released. You can download it from:
http://people.redhat.com/sgrubb/audit
Some of the changes:
- Add R option to auditctl to allow reading rules from file.
- Do not allow task creation list to have syscall auditing
- Add D option to allow deleting all rules with 1 command
- Added pam_audit man page & sample.rules
- Mod initscript to call auditctl to load rules at start-up
- Write message to log file for daemon start up
- Write message that daemon is shutting down
- Modify auditd shutdown to wait until logger thread is finished
- Fix bug where extra info was appended to some messages
This version now supports reading a set of rules when the daemon is started.
Edit the file: /etc/audit.rules and place the audit ctl commands. There is a
sample audit rules file included. Look for sample.rules.
Compiled versions will be available in rawhide tomorrow morning.
-Steve Grubb
19 years, 8 months
dev information for open, exec?
by Erich Schubert
Hi,
the dev= field of auditd information seems to be missing for open,
exec syscalls.
Is there a reason why this information is not available?
(I'd like to filter out all open calls on /proc...)
The log lines i get look like the following:
type=KERNEL msg=audit(1109035917.261:14548): item=0
name=/usr/share/locale/de/LC_MESSAGES/coreutils.mo inode=852010
dev=00:00
and the dev=00:00 value is bogus; I never get a different value.
I'm currently trying to use auditd to obtain an optimized "readahead"
file list for speeding up system boot. I had this idea some months
ago; maybe I should check recent boot speedup developments... ;-)
Greetings,
Erich Schubert
--
erich(a)(mucl.de|debian.org) -- GPG Key ID: 4B3A135C (o_
To understand recursion you first need to understand recursion. //\
Wo befreundete Wege zusammenlaufen, da sieht die ganze Welt für V_/_
eine Stunde wie eine Heimat aus. --- Herrmann Hesse
19 years, 9 months
Netlink Socket Problem
by Steve Grubb
Hi,
I'm still working on some bugs that I found over the weekend for libaudit. I
modified pam and passwd to log events to the audit netlink connection. As a
result, I ran into a problem. The problem is probably best illustrated by
showing in auditctl.c how to reproduce it.
If you open auditctl.c, look for reset_vars(). In that function is
audit_open(). Add a second call to audit_open so that it looks like this:
static int reset_vars(void)
{
list_requested = 0;
syscalladded = 0;
add = 0;
del = 0;
action = 0;
memset(&rule, 0, sizeof(rule));
audit_open(); // this is added. we don't care what the return is.
if ((fd = audit_open()) < 0) {
fprintf(stderr, "Cannot open netlink audit socket\n");
return 1;
}
return 0;
}
What this does is makes the application open 2 netlink connections to the
audit system. Compile it and try ./auditctl -s Using strace this is what I
get (with my annotations):
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 getrlimit(RLIMIT_STACK,
{rlim_cur=10240*1024, rlim_max=RLIM_INFINITY}) = 0
_sysctl({{CTL_KERN, KERN_VERSION}, 2, 0xbfec898c, 31, (nil), 0}) = 0
socket(PF_NETLINK, SOCK_RAW, 9) = 3
<- first open ->
bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
socket(PF_NETLINK, SOCK_RAW, 9) = 4
<- second open ->
bind(4, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
fcntl64(4, F_SETFD, FD_CLOEXEC) = 0
sendto(4, "\20\0\0\0\350\3\1\0gE\213k\0\0\0\0", 16, 0, {sa_family=AF_NETLINK,
pid=0, groups=00000000}, 12) = 16
<- send request , now get answer ->
recvfrom(4, 0xbfec7ed0, 1216, 64, 0xbfec7e60, 0xbfec7e5c) = -1 EAGAIN
(Resource temporarily unavailable) write(2, "Error receiving netlink packet
("..., 65Error receiving netlink packet (Resource temporarily unavailable)) =
65 write(2, "\n", 1
) = 1
<- error? ->
nanosleep({0, 100000000}, NULL) = 0
recvfrom(4, 0xbfec7ed0, 1216, 64, 0xbfec7e60, 0xbfec7e5c) = -1 EAGAIN
(Resource temporarily unavailable)
write(2, "Error receiving netlink packet ("..., 65Error receiving netlink
packet (Resource temporarily unavailable)) = 65
write(2, "\n", 1
<- error? ->
As you can see it scrolls messages because you get EAGAIN returned. This is a
real problem right now and I'm not sure how best to solve it short of making
a request, closing the descriptor, and re-open it for each communication to
the kernel.
What happens in real life is that passwd is going to log some data to the
audit system and opens a socket, then it collects the passwords, if
everything is OK, it passes the passwords to pam for authentication token
update. Pam decides that it needs to do some logging of its own and opens
descriptors to the audit system. They fail like above, EAGAIN.
Does any of you kernel hackers know why apps are limited to 1 netlink socket
connection? Can someone else verify the problem?
I think I can fix the problem by constantly closing and opening connections,
but that is ugly and not efficient. This "bug/feature" is holding up the
release of the next version of audit and patched trusted programs.
Thanks,
-Steve Grubb
19 years, 9 months
[PATCH] Audit permission changes on IPC objects.
by David Woodhouse
Capture the requested permissions on IPC_SET calls. We do this with a
hook in ipc/{sem,shm,msg}.c for two reasons. Firstly, it would require a
lot of arch-specific knowledge about syscall numbers and sys_ipc()
multiplexing to get at this information from syscall_trace_enter().
Secondly, if we did it there it could be changed by the time the IPC
code does copy_from_user() to fetch it again.
Signed-off-by: David Woodhouse <dwmw2(a)infradead.org>
===== include/linux/audit.h 1.2 vs edited =====
--- 1.2/include/linux/audit.h 2005-01-31 06:33:47 +00:00
+++ edited/include/linux/audit.h 2005-02-28 13:39:05 +00:00
@@ -150,6 +150,7 @@
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);
+extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
@@ -159,6 +160,7 @@
#define audit_putname(n) do { ; } while (0)
#define audit_inode(n,i,d) do { ; } while (0)
#define audit_get_loginuid(c) ({ -1; })
+#define audit_ipc_perms(q,u,g,m) ({ 0; })
#endif
#ifdef CONFIG_AUDIT
===== ipc/msg.c 1.24 vs edited =====
--- 1.24/ipc/msg.c 2004-10-28 08:39:57 +01:00
+++ edited/ipc/msg.c 2005-02-28 13:39:42 +00:00
@@ -25,6 +25,7 @@
#include <linux/security.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
+#include <linux/audit.h>
#include <asm/current.h>
#include <asm/uaccess.h>
#include "util.h"
@@ -425,6 +426,8 @@
return -EFAULT;
if (copy_msqid_from_user (&setbuf, buf, version))
return -EFAULT;
+ if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode)))
+ return err;
break;
case IPC_RMID:
break;
===== ipc/sem.c 1.36 vs edited =====
--- 1.36/ipc/sem.c 2005-01-05 02:48:17 +00:00
+++ edited/ipc/sem.c 2005-02-28 13:39:48 +00:00
@@ -72,6 +72,7 @@
#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/syscalls.h>
+#include <linux/audit.h>
#include <asm/uaccess.h>
#include "util.h"
@@ -803,6 +804,8 @@
if(cmd == IPC_SET) {
if(copy_semid_from_user (&setbuf, arg.buf, version))
return -EFAULT;
+ if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
+ return err;
}
sma = sem_lock(semid);
if(sma==NULL)
===== ipc/shm.c 1.43 vs edited =====
--- 1.43/ipc/shm.c 2004-12-13 10:47:27 +00:00
+++ edited/ipc/shm.c 2005-02-28 13:39:28 +00:00
@@ -27,6 +27,7 @@
#include <linux/shmem_fs.h>
#include <linux/security.h>
#include <linux/syscalls.h>
+#include <linux/audit.h>
#include <asm/uaccess.h>
#include "util.h"
@@ -600,6 +601,8 @@
err = -EFAULT;
goto out;
}
+ if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
+ return err;
down(&shm_ids.sem);
shp = shm_lock(shmid);
err=-EINVAL;
===== kernel/auditsc.c 1.6 vs edited =====
--- 1.6/kernel/auditsc.c 2005-01-31 06:33:47 +00:00
+++ edited/kernel/auditsc.c 2005-02-28 13:43:01 +00:00
@@ -92,6 +92,23 @@
dev_t rdev;
};
+struct audit_aux_data {
+ struct audit_aux_data *next;
+ int type;
+};
+
+#define AUDIT_AUX_IPCPERM 0
+
+struct audit_aux_data_ipcctl {
+ struct audit_aux_data d;
+ struct ipc_perm p;
+ unsigned long qbytes;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+};
+
+
/* The per-task audit context. */
struct audit_context {
int in_syscall; /* 1 if task is in a syscall */
@@ -107,6 +124,7 @@
int name_count;
struct audit_names names[AUDIT_NAMES];
struct audit_context *previous; /* For nested syscalls */
+ struct audit_aux_data *aux;
/* Save things to print about task_struct */
pid_t pid;
@@ -504,6 +522,16 @@
context->name_count = 0;
}
+static inline void audit_free_aux(struct audit_context *context)
+{
+ struct audit_aux_data *aux;
+
+ while ((aux = context->aux)) {
+ context->aux = aux->next;
+ kfree(aux);
+ }
+}
+
static inline void audit_zero_context(struct audit_context *context,
enum audit_state state)
{
@@ -570,6 +598,7 @@
context->name_count, count);
}
audit_free_names(context);
+ audit_free_aux(context);
kfree(context);
context = previous;
} while (context);
@@ -607,6 +636,29 @@
context->euid, context->suid, context->fsuid,
context->egid, context->sgid, context->fsgid);
audit_log_end(ab);
+ while (context->aux) {
+ struct audit_aux_data *aux;
+
+ ab = audit_log_start(context);
+ if (!ab)
+ continue; /* audit_panic has been called */
+
+ aux = context->aux;
+ context->aux = aux->next;
+
+ audit_log_format(ab, "auxitem=%d", aux->type);
+ switch (aux->type) {
+ case AUDIT_AUX_IPCPERM: {
+ struct audit_aux_data_ipcctl *axi = (void *)aux;
+ audit_log_format(ab,
+ " qbytes=%lx uid=%d gid=%d mode=%x",
+ axi->qbytes, axi->uid, axi->gid, axi->mode);
+ }
+ }
+ audit_log_end(ab);
+ kfree(aux);
+ }
+
for (i = 0; i < context->name_count; i++) {
ab = audit_log_start(context);
if (!ab)
@@ -789,6 +841,7 @@
tsk->audit_context = new_context;
} else {
audit_free_names(context);
+ audit_free_aux(context);
audit_zero_context(context, context->state);
tsk->audit_context = context;
}
@@ -926,4 +979,30 @@
uid_t audit_get_loginuid(struct audit_context *ctx)
{
return ctx ? ctx->loginuid : -1;
+}
+
+ return 0;
+ }
+
+int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
+{
+ struct audit_aux_data_ipcctl *ax;
+ struct audit_context *context = current->audit_context;
+
+ if (likely(!context))
+ return 0;
+
+ ax = kmalloc(sizeof(*ax), GFP_KERNEL);
+ if (!ax)
+ return -ENOMEM;
+
+ ax->qbytes = qbytes;
+ ax->uid = uid;
+ ax->gid = gid;
+ ax->mode = mode;
+
+ ax->d.type = AUDIT_AUX_IPCPERM;
+ ax->d.next = context->aux;
+ context->aux = (void *)ax;
+ return 0;
}
A
6 (
x 9
z
z
z
raph
z
z
z
5
n
6
y c li
!
50,
6
9
6
0)
z
ph
0,
6
6
6!
,
6
z
ph
9
z
y
A
y
ph
y c li
y
50y
y c link
h
y c link
x
!
0,
6
y
y
ph
ph
y
y
aph
y c link
ph
h
h
'
aph
y c link
t
h
h
y c link
W ÿ
)Y ¡
x
x
h
Òn A
6
6
pc/msg.
x c link
8
x
s
ne !
6
0,
6
05
6
8
05
50,
6
--
dwmw2
19 years, 9 months
[RFC][PATCH] (#5) prelim auditfs
by Timothy R. Chavez
Hello,
Before we get started I just have to tell the world: It's a beautiful
day here in Austin, TX.
There were enough changes for this patch that I felt it'd be OK and
simpler if I just called it patch #5. In this patch I fix the logic
which was pretty broken last time (man was it broken). I also cleaned
up the code: reduced more code redundancy, tightened up helper
functions, fixed minor and major bugs, and attempted to make the code
more readable.
Two improvements:
1.
I did something which might be kind of ballsy, but it seems to work just fine.
In a very tired state I tried explaining this one over the phone. My
guess is that it made little to no sense -- sorry :( perhaps I'll be a
little more eloquent via e-mail.
A file/directory that is already being watched gives that watch
precedence on that inode. This means that if we move a watched file,
/tmp/foo, to /tmp/bar and then watch /tmp/bar, /tmp/bar will still
report watch information for /tmp/foo (Likewise, if we moved /tmp/foo
to /tmp/bar and a watch already exists on /tmp/bar, the watch for
/tmp/foo would remain). This is only semi-cool. To become fully-cool
we'd also like to be able to adopt (automatically) the watch on
/tmp/bar if and when the watch on /tmp/foo is ever removed. Hooking
d_lookup seemed like the best place to do this.
2.
There are three kinds of inodes that make use of the audit_data inode
struct: watched, watching, both. When we watch an inode that is also
watching, it'd be a mistake to overwrite it with the preallocated
memory associated with that watch entry. There goes the watchlist,
doh! So, in this case, we simply transfer into the preallocated
memory the inode's current audit_data. This has a nifty side-effect.
Iff the inode is stationary in the filesystem (movement destroys
watchlists), then if we were to delete and recreate the directory, its
watches would still be intact. If we remove the acutally watch, the
watchlist will automatically be drained. To remove individual
watches, the directory would have to first be resurrected.
What is left?
- Feature: List all watches currently in the filesystem
- Comments: Add [better | more] comments
- Test, test, test
Testing:
Starting tomorrow, Loulwa S. will officially be joining this project,
and will be helping me with the functional test case development
needed for the auditfs piece.
Chris, I wasn't really able to find much on the umount() problem the
Inotify guys were having. I found a conversation / beat down which
alluded to it, but that's it. Still, I hadn't actually tested the
behavior when I umount a device that has watches on it, so I figured
I'd at least do this test:
I added watches to a mount, removed the mount, and saw all the watches
putting back all their references and being freed / put back into
their respective caches. This is the correct behavior in my book.
Was it something more / different?
Still unable to provide userspace piece for testing. I am going to
port it to audit-0.6.4
Please, please, please... look this over and give comments, feedback,
and suggestions. Don't hold back, let me have it.
--
- Timothy R. Chavez
19 years, 10 months
audit-0.6.4 released
by Steve Grubb
Hi,
I am releasing a new version of the audit daemon. You can get it from
http://people.redhat.com/sgrubb/audit This is a bug fix release and a pam
change.
pam_audit has been renamed. This is to reflect what it really does now that we
have a pam that is audit aware.
IF YOU HAVE PAM_AUDIT IN ANY PAM CONFIGURATION FILES - PLEASE REMOVE IT BEFORE
UPGRADING !! IF YOU FORGET, YOU MAY NEED A RESCUE DISK TO GET BACK INTO YOUR
SYSTEM.
Aside from the pam change, this release is being done because I have fixed 2-3
very important bugs. There were 2 mistakes in the way that out of disk space
was being calculated and handled. Also a bug in the handling of suspended
logging. These could lead to netlink socket busy conditions and ultimately an
unresponsive system.
Please take care to grep for pam_audit in /etc/pam.d before logging out.
-Steve Grubb
19 years, 10 months
[PATCH] fix audit inode filter
by Chris Wright
Audit inode filter drops high bits on inode number by cut 'n paste mistake.
Signed-off-by: Chris Wright <chrisw(a)osdl.org>
--- linus-2.6/kernel/auditsc.c~audit-inode-filter-fix 2005-02-24 16:55:32.000000000 -0800
+++ linus-2.6/kernel/auditsc.c 2005-02-25 18:23:15.000000000 -0800
@@ -358,7 +358,7 @@ static int audit_filter_rules(struct tas
case AUDIT_INODE:
if (ctx) {
for (j = 0; j < ctx->name_count; j++) {
- if (MINOR(ctx->names[j].ino)==value) {
+ if (ctx->names[j].ino == value) {
++result;
break;
}
19 years, 10 months
[PATCH] detangle audit.h from fs.h
by Chris Wright
Currently touching audit.h triggers a large rebuild because it's sucked
in via fs.h. It's there because of the getname()/putname() requirements
that come with CONFIG_AUDITSYSCALL. Remove header dependency by pushing
relevant putname() implementation into fs/namei.c. It adds function
call overhead for putname() callers when CONFIG_AUDITSYSCALL is set,
quite minor cost for detangled source. Any objections?
Signed-off-by: Chris Wright <chrisw(a)osdl.org>
===== include/linux/fs.h 1.378 vs edited =====
--- 1.378/include/linux/fs.h 2005-02-22 16:17:36 -08:00
+++ edited/include/linux/fs.h 2005-02-24 15:59:53 -08:00
@@ -210,7 +210,6 @@ extern int dir_notify_enable;
#include <linux/list.h>
#include <linux/radix-tree.h>
#include <linux/prio_tree.h>
-#include <linux/audit.h>
#include <linux/init.h>
#include <asm/atomic.h>
@@ -1268,13 +1267,7 @@ extern void __init vfs_caches_init(unsig
#ifndef CONFIG_AUDITSYSCALL
#define putname(name) __putname(name)
#else
-#define putname(name) \
- do { \
- if (unlikely(current->audit_context)) \
- audit_putname(name); \
- else \
- __putname(name); \
- } while (0)
+extern void putname(const char *name);
#endif
extern int register_blkdev(unsigned int, const char *);
===== fs/namei.c 1.118 vs edited =====
--- 1.118/fs/namei.c 2005-01-20 21:00:21 -08:00
+++ edited/fs/namei.c 2005-02-24 15:58:47 -08:00
@@ -148,10 +148,21 @@ char * getname(const char __user * filen
result = ERR_PTR(retval);
}
}
- if (unlikely(current->audit_context) && !IS_ERR(result) && result)
- audit_getname(result);
+ audit_getname(result);
return result;
}
+
+#ifdef CONFIG_AUDITSYSCALL
+void putname(const char *name)
+{
+ if (unlikely(current->audit_context))
+ audit_putname(name);
+ else
+ __putname(name);
+}
+EXPORT_SYMBOL(putname);
+#endif
+
/**
* generic_permission - check for access rights on a Posix-like filesystem
===== kernel/auditsc.c 1.6 vs edited =====
--- 1.6/kernel/auditsc.c 2005-01-30 22:33:47 -08:00
+++ edited/kernel/auditsc.c 2005-02-24 16:06:06 -08:00
@@ -800,7 +800,9 @@ void audit_getname(const char *name)
{
struct audit_context *context = current->audit_context;
- BUG_ON(!context);
+ if (!context || IS_ERR(name) || !name)
+ return;
+
if (!context->in_syscall) {
#if AUDIT_DEBUG == 2
printk(KERN_ERR "%s:%d(:%d): ignoring getname(%p)\n",
@@ -855,7 +857,6 @@ void audit_putname(const char *name)
}
#endif
}
-EXPORT_SYMBOL(audit_putname);
/* Store the inode and device from a lookup. Called from
* fs/namei.c:path_lookup(). */
===== fs/proc/base.c 1.88 vs edited =====
--- 1.88/fs/proc/base.c 2005-01-30 22:33:47 -08:00
+++ edited/fs/proc/base.c 2005-02-24 16:03:06 -08:00
@@ -32,6 +32,7 @@
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/ptrace.h>
+#include <linux/audit.h>
#include "internal.h"
/*
19 years, 10 months
Re: [PATCH] audit: handle loginuid through proc
by Chris Wright
* Albert Cahalan (albert(a)users.sourceforge.net) wrote:
> On Thu, 2005-02-24 at 22:49 -0800, Chris Wright wrote:
> > * Albert Cahalan (albert(a)users.sourceforge.net) wrote:
>
> > > Assuming you'd like ps to print the LUID, how about
> > > putting it with all the others? There are "Uid:"
> > > lines in the /proc/*/status files.
> >
> > It's also set (written) via /proc, so it should probably stay separate.
>
> Gross. Please rip this out before it hits the streets.
> (it's an interface change that might need eternal support)
It's already supported via the new pam_loginuid module. Also the
loginuid is not a part of the task proper, rather the audit context.
It's treated in a manner similar to security contexts which are handled
via /proc interfaces. Having said that, I wouldn't be opposed to a
patch that promotes it to compatible syscall as you mentioned below
(thanks for the details) if it turns out to be useful. Got a patch?
[details left for linux-audit folks]
> Consider that:
>
> 1. Every other UID is handled by system calls:
> getuid, setuid, geteuid, setreuid,
> setresuid, getresuid, setfsuid
>
> 2. HP's Tru64 has getluid() and setluid() system calls
> that Linux should be compatible with. SecureWare has a
> version too, which looks more-or-less compatible with
> what HP is offering. (the descriptions do not conflict,
> but one has more details) It looks like ssh, apache,
> and sendmail (huh?) already knows to use these system
> calls even.
>
> The <prot.h> header is used. Prototypes are the obvious.
> The setuid() call returns 0 on success.
>
> Tru64 notes that the login UID is sometimes called the
> audit UID (AUID) because it is recorded with most audit
> events.
>
> getluid() returns an error if the LUID (AUID) is unset.
>
> SecureWare additionally notes that setuid() and setgid() will
> also fail when the luid is unset, to ensure that the LUID
> is set before any other identity changes. (probably Linux
> should just disable setting LUID after that point)
>
> ------------
>
> Just to be complete, here's what Sun did:
>
> Sun has getauid() and setauid() syscalls which are
> somewhat similar. They take pointers to the ID, and they
> require privilege (PRIV_SYS_AUDIT and PRIV_PROC_AUDIT
> for setauid, or just PRIV_PROC_AUDIT for getauid)
> These calls have been superceded by getaudit_addr() and
> setaudit_addr(), which use structs containing:
>
> au_id_t ai_auid; // audit user ID
> au_mask_t ai_mask; // preselection mask
> au_tid_addr_t ai_termid; // terminal ID
> au_asid_t ai_asid; // audit session ID
>
> (the terminal ID is variable length, containing a
> network address and a length value for it)
19 years, 10 months
Re: [RFC][PATCH] (#4) auditfs
by Timothy R. Chavez
On Tue, 22 Feb 2005 13:24:34 -0500, Stephen Smalley <sds(a)tycho.nsa.gov> wrote:
> On Tue, 2005-02-22 at 10:42 -0600, Timothy R. Chavez wrote:
> > - Hooks in vfs_read/write/unlink (please look closely here). The rule
> > of thumb I went off of is: I can call my hook iff I have an inode and
> > I'm NOT hooking lookup_hash *nudge Stephen* :)
> <snip>
> > Three hooks for dynamically assigning watches:
> > d_splice_alias, d_move, d_instantiate
> >
> > Five hooks for dynamically adding watches to our context:
> > permission, exec_permission_lite, vfs_read, vfs_write, vfs_unlink
>
> Why do you hook vfs_read/vfs_write when you have a hook in permission?
> If you are trying to audit actual reads and writes, then there are other
> cases to consider, e.g. do_sendfile(), plus fun with AIO. Much easier
> if you can just stay with auditing open(2) calls via your permission(9)
> hook.
I've only done this because I was under the assumption that every
syscall that can access a watched file system object in some fashion
should be able to generate records. I see what you're saying though,
Stephen. And admitedly, I am also being a little redundant in that
the original code can already provide us with the read() and write()
exit code and the file/directory being read from/written to. However,
if we want to specifically monitor activity in the filesystem
surrounding watched objects, then wouldn't these hooks in read(),
write(), etc be vital? Klaus? How else will we know if a read() or
write() trully succeeded or failed on a watched filesystem object?
If we just rely on the open(), however, we cut out the read/write
hooks, plus whatever else would need be added.
Perhaps there's enough information in just an open(). The record will
give us the filesystem object information, plus it will tell us which
permission was used (READ/WRITE/EXEC/APPEND) provided it allows for
that permission in the mask and the exit code of the open(). However,
will the exit code necessarily be a reflection of a permission
failure?
>
> There is a known race with respect to d_instantiate and file creation,
> but it needs to be resolved anyway for SELinux, so I think you can
> proceed under the assumption that it will be fixed. Alternatively, you
> would need to move your hook call prior to the setting of d_inode in the
> dentry and pass in the inode separately to your hook.
>
Ah yes, I remembering you talking about this earlier. I'll keep this
in mind and work under the assumption that this will be fixed for the
time being.
> --
> Stephen Smalley <sds(a)tycho.nsa.gov>
> National Security Agency
>
>
--
- Timothy R. Chavez
19 years, 10 months