[PATCH 1/2] fix audit skb leak on congested netlink socket
by Chris Wright
When auditd is congested the kernel's audit system leaks skb's. First,
it takes them off the audit_buffer sklist at which point they are lost,
second, it allocates a new skb with 0 length payload. Then (likely still
congested), it repeats this losing the new skb. Plug the leak by making
sure to requeue the skb, and avoid audit_log_move() on 0 len audit_buffer.
Signed-off-by: Chris Wright <chrisw(a)osdl.org>
===== kernel/audit.c 1.6 vs edited =====
--- 1.6/kernel/audit.c 2005-01-20 20:56:04 -08:00
+++ edited/kernel/audit.c 2005-01-25 14:34:32 -08:00
@@ -494,6 +494,10 @@ static void audit_log_move(struct audit_
char *start;
int extra = ab->nlh ? 0 : NLMSG_SPACE(0);
+ /* possible resubmission */
+ if (ab->len == 0)
+ return;
+
skb = skb_peek(&ab->sklist);
if (!skb || skb_tailroom(skb) <= ab->len + extra) {
skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
@@ -535,6 +539,7 @@ static inline int audit_log_drain(struct
}
if (retval == -EAGAIN && ab->count < 5) {
++ab->count;
+ skb_queue_tail(&ab->sklist, skb);
audit_log_end_irq(ab);
return 1;
}
19 years, 11 months
Re: [RFC][PATCH] (#2) Prelim in-kernel file system auditing support
by Timothy R. Chavez
On Tue, 25 Jan 2005 11:20:54 -0600, Serge E. Hallyn <serue(a)us.ibm.com> wrote:
> Tim,
>
> do you care about getting multiple entries in a single directory's
> watchlist for the same file?
I'v CCed the list so we don't get redundant comments :-) Yes, we do
care. This will leak memory. Here's why:
If we're in a race and we both get to the point of adding the watch to
the list because we've both seen that we're not in the list. Two
audit_struct watches have been created. If we remove a watch, one
will still exist. It might be odd, if say we were watching /tmp/foo,
said "stop watching /tmp/foo", deleted "/tmp/foo", recreated
"/tmp/foo" and started getting audit messages for "/tmp/foo" -- And at
least then we'll consume the memory. The alternative is that the
memory just gets forgotton.
So let me better protect the list. Should I simply include in the
critical section a test to make sure that I've not already been added?
>
> Ie two entries for /etc/shadow in /etc's watchlist?
>
--
- Timothy R. Chavez
19 years, 11 months
corrupted audit messages
by Chris Wright
Here's some example of what I'm seeing (from auditd):
type=KERNEL msg=audit(1106620862.749:4026): syscall=2 exit=3 a0=7ffffffffa44 a1=0 a2=7ffffffff7e8 a3=1 items=1 pid=4513 loginuid=-1 uid=23 gid=500 euid=23 suid=23 fsuid=23 egid=500 sgid=500 fsgid=500
type=KERNEL msg=audit(1106620862.749:4026): item=0 name=/dev/null inode=5457 dev=01:03 inode=8652144 dev=00:00d=4457 loginuid=-1 uid=23 gid=500 euid=23 suid=23 fsuid=23 egid=500 sgid=500 fsgid=50000
And here's from the kernel:
skb_data(183): audit(1106620862.749:4026): syscall=2 exit=3 a0=7ffffffffa44 a1=0 a2=7ffffffff7e8 a3=1 items=1 pid=4513 loginuid=-1 uid=23 gid=500 euid=23 suid=23 fsuid=23 egid=500 sgid=500 fsgid=500
skb_data(70): audit(1106620862.749:4026): item=0 name=/dev/null
inode=5457 dev=01:03
And here's from syslog:
audit(1106676503.481:3766769): syscall=2 exit=3 a0=3eac7f97a0 a1=0 a2=0 a3=7ffffffff22a items=1 pid=5300 loginuid=-1 uid=23 gid=500 euid=23 suid=23 fsuid=23 egid=500 sgid=500 fsgid=500
audit(1106676503.481:3766769): item=0 name=/usr/lib/locale/locale-archive inode=8652144 dev=00:00
It seems that auditd is the only one with the problem.
thanks,
-chris
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
19 years, 11 months
IPC auditing.
by David Woodhouse
There isn't a convenient place to add information about IPC objects in
the audit_context. I'm reluctant to add it -- should we just add a
freeform area for data instead?
I note that auditing of various IPC operations is already done by
avc_audit(). That lacks the actual uid/gid/permissions which the user
tried to set, but could easily have them added.
It also handles network syscalls, to a certain extent. I'm trying to
work out how best to use if for syscall auditing too...
--
dwmw2
19 years, 11 months
[RFC] linux-2.6.10-auditfs-tc1.patch
by Timothy R. Chavez
Hello,
Attached to this e-mail is my first iteration of the file system
auditing piece needed for CAPP EAL4. I appreciate all feedback, but
please read the TODO list prior to sending me feedback on something
I'm already aware of. I've not stressed tested this code nor have I
done any formal FVT. The testing I have done has been.. minimal.
I've mostly seen if given scenarios work (move one watched file to
another watched location, create a hardlink to /etc/passwd from
/home/me, etc).
At this time, I'm unable to provide you with the userspace patch I
wrote, but encourage someone on this list to add the functionality to
libaudit/auditctl and submit the patch (Steve :)?). If you'd like my
"guidance" please e-mail me privately.
ABOUT:
Thus far, the patch being submitted with this e-mail implements a
rudimentary file system auditing capability using the in-kernel audit
subsystem. From userspace, an administrator passes into the kernel a
pathname and filterkey pair. The terminating file or directory does
not have to exist at the time a watch point is created for it, but
it's parent does.
If at any point the parent is destroyed, auditing information for its
children is lost. Likewise, if we mount over watched paths, we lose
auditing information, until we unmount. Currently, there is no
decision on whether or not we ought to give the audit subsystem the
capability of dynamically remapping watch paths onto new mounts or
supporting theoretical watch paths where watch paths are arbitrary and
if they should come into existence within the filesystem, they become
watched and thus auditable. Also, if I remember my code correctly, if
you move out of a watch path into a path that is not being watched,
your watch field is still pointing in a watch list, and will be
audited. If you destroy this file or directory and recreate it in the
same (unwatched) path, it will no longer be audited. I think I need
to add a field to the watch where we can enable/disable this behavior
per watch entry.
Provided both syscall auditing and file system auditing are both
configured and enabled, when a syscall of interest accesses a file or
directory being watched, it collects information about that file or
directory (via it's inode and watch entry) and adds it to the
audit_context of that syscall. When the syscall exits, any files or
directory information collected is sent to userspace to be logged.
TODOs:
* Add RCU locking in the appropriate places to make SMP-safe
* Switch over to slab caches for struct audit_data, struct audit_file,
and struct audit_watch
* Think about how I can make it so an administrator can say, "Watch
this file only on the syscall open where uid=0" -- As of right now, if
filesystem auditing is on, every syscall (being audited) that accesses
a watched file or directory collects information about it and
generates a record. Is this sufficient?
* Make it so filesystem auditing can be dynamically enabled/disabled
from userspace, rather then being "enabled" if configured or
"disabled" if not configured at boot time.
* Add/remove unnecessary information about the file or directory being
collected in the audit context. Input on this?
--
- Timothy R. Chavez
19 years, 11 months
RHEL4 audit test kernels.
by David Woodhouse
Further to the discussion on Tuesday I've switched to RHEL4 as the
kernel on which I'm basing my packages. These kernels should work on FC3
systems too, though.
I've also moved them to a machine with better upload bandwidth from
North Carolina -- ftp://ftp.uk.linux.org/pub/people/dwmw2/audit/ has the
yum repository.
This contains Serge's reposted loginuid patches and capabilities patch,
and also Timothy's auditfs patch, amended slightly according to my
feedback. It also contains an entirely untested patch to provide a
correct return code to to audit_syscall_exit() on ppc64. And Peter's
patches which were already merged in later kernels but which aren't in
2.6.9.
--
dwmw2
19 years, 11 months
[patch 008/133] Fix audit control message checks
by akpm@osdl.org
From: "Serge E. Hallyn" <hallyn(a)CS.WM.EDU>
The audit control messages are sent over netlink. Permission checks are
done on the process receiving the message, which may not be the same as the
process sending the message. This patch switches the netlink_send security
hooks to calculate the effective capabilities based on the sender. Then
audit_receive_msg performs capability checks based on that.
It also introduces the CAP_AUDIT_WRITE and CAP_AUDIT_CONTROL capabilities,
and replaces the previous CAP_SYS_ADMIN checks in audit code with the
appropriate checks.
- Simplified dummy_netlink_send given that dummy now keeps track of
capabilities.
- Many fixes based on feedback from <linux-audit(a)redhat.com> list.
- Removed the netlink_msg_type helper function.
- Switch to using CAP_AUDIT_WRITE and CAP_AUDIT_CONTROL.
Signed-off-by: Serge Hallyn <serue(a)us.ibm.com>
Signed-off-by: Stephen Smalley <sds(a)epoch.ncsc.mil>
Signed-off-by: Chris Wright <chrisw(a)osdl.org>
Signed-off-by: Andrew Morton <akpm(a)osdl.org>
---
25-akpm/include/linux/capability.h | 4 ++
25-akpm/kernel/audit.c | 51 +++++++++++++++++++++++++++++++------
25-akpm/kernel/auditsc.c | 2 -
25-akpm/security/dummy.c | 5 ---
25-akpm/security/selinux/hooks.c | 18 +++++++++----
5 files changed, 62 insertions(+), 18 deletions(-)
diff -puN include/linux/capability.h~fix-audit-control-message-checks include/linux/capability.h
--- 25/include/linux/capability.h~fix-audit-control-message-checks 2005-01-20 20:55:57.000000000 -0800
+++ 25-akpm/include/linux/capability.h 2005-01-20 20:55:57.575163664 -0800
@@ -284,6 +284,10 @@ typedef __u32 kernel_cap_t;
#define CAP_LEASE 28
+#define CAP_AUDIT_WRITE 29
+
+#define CAP_AUDIT_CONTROL 30
+
#ifdef __KERNEL__
/*
* Bounding set
diff -puN kernel/audit.c~fix-audit-control-message-checks kernel/audit.c
--- 25/kernel/audit.c~fix-audit-control-message-checks 2005-01-20 20:55:57.000000000 -0800
+++ 25-akpm/kernel/audit.c 2005-01-20 20:56:04.000000000 -0800
@@ -300,21 +300,55 @@ nlmsg_failure: /* Used by NLMSG_PUT */
kfree_skb(skb);
}
+/*
+ * Check for appropriate CAP_AUDIT_ capabilities on incoming audit
+ * control messages.
+ */
+static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
+{
+ int err = 0;
+
+ switch (msg_type) {
+ 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))
+ err = -EPERM;
+ break;
+ case AUDIT_USER:
+ if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
+ err = -EPERM;
+ break;
+ default: /* bad msg */
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
u32 uid, pid, seq;
void *data;
struct audit_status *status_get, status_set;
struct audit_login *login;
- int err = 0;
+ int err;
struct audit_buffer *ab;
+ u16 msg_type = nlh->nlmsg_type;
+
+ err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
+ if (err)
+ return err;
pid = NETLINK_CREDS(skb)->pid;
uid = NETLINK_CREDS(skb)->uid;
seq = nlh->nlmsg_seq;
data = NLMSG_DATA(nlh);
- switch (nlh->nlmsg_type) {
+ switch (msg_type) {
case AUDIT_GET:
status_set.enabled = audit_enabled;
status_set.failure = audit_failure;
@@ -327,8 +361,8 @@ static int audit_receive_msg(struct sk_b
&status_set, sizeof(status_set));
break;
case AUDIT_SET:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ if (nlh->nlmsg_len < sizeof(struct audit_status))
+ return -EINVAL;
status_get = (struct audit_status *)data;
if (status_get->mask & AUDIT_STATUS_ENABLED) {
err = audit_set_enabled(status_get->enabled);
@@ -364,8 +398,8 @@ static int audit_receive_msg(struct sk_b
audit_log_end(ab);
break;
case AUDIT_LOGIN:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ if (nlh->nlmsg_len < sizeof(struct audit_login))
+ return -EINVAL;
login = (struct audit_login *)data;
ab = audit_log_start(NULL);
if (ab) {
@@ -384,9 +418,12 @@ static int audit_receive_msg(struct sk_b
login->loginuid);
#endif
break;
- case AUDIT_LIST:
case AUDIT_ADD:
case AUDIT_DEL:
+ if (nlh->nlmsg_len < sizeof(struct audit_rule))
+ return -EINVAL;
+ /* fallthrough */
+ case AUDIT_LIST:
#ifdef CONFIG_AUDITSYSCALL
err = audit_receive_filter(nlh->nlmsg_type, pid, uid, seq,
data);
diff -puN kernel/auditsc.c~fix-audit-control-message-checks kernel/auditsc.c
--- 25/kernel/auditsc.c~fix-audit-control-message-checks 2005-01-20 20:55:57.000000000 -0800
+++ 25-akpm/kernel/auditsc.c 2005-01-20 20:55:57.000000000 -0800
@@ -250,8 +250,6 @@ int audit_receive_filter(int type, int p
audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
break;
case AUDIT_ADD:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
return -ENOMEM;
if (audit_copy_rule(&entry->rule, data)) {
diff -puN security/dummy.c~fix-audit-control-message-checks security/dummy.c
--- 25/security/dummy.c~fix-audit-control-message-checks 2005-01-20 20:55:57.000000000 -0800
+++ 25-akpm/security/dummy.c 2005-01-20 20:55:57.000000000 -0800
@@ -685,10 +685,7 @@ static int dummy_sem_semop (struct sem_a
static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
{
- if (current->euid == 0)
- cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
- else
- NETLINK_CB (skb).eff_cap = 0;
+ NETLINK_CB(skb).eff_cap = current->cap_effective;
return 0;
}
diff -puN security/selinux/hooks.c~fix-audit-control-message-checks security/selinux/hooks.c
--- 25/security/selinux/hooks.c~fix-audit-control-message-checks 2005-01-20 20:55:57.000000000 -0800
+++ 25-akpm/security/selinux/hooks.c 2005-01-20 21:29:17.245167616 -0800
@@ -3502,12 +3502,20 @@ static inline int selinux_nlmsg_perm(str
static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
{
- int err = 0;
+ struct task_security_struct *tsec;
+ struct av_decision avd;
+ int err;
- if (capable(CAP_NET_ADMIN))
- cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
- else
- NETLINK_CB(skb).eff_cap = 0;
+ err = secondary_ops->netlink_send(sk, skb);
+ if (err)
+ return err;
+
+ tsec = current->security;
+
+ avd.allowed = 0;
+ avc_has_perm_noaudit(tsec->sid, tsec->sid,
+ SECCLASS_CAPABILITY, ~0, &avd);
+ cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed);
if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
err = selinux_nlmsg_perm(sk, skb);
_
19 years, 11 months
[RFC][PATCH] Prelim in-kernel file system auditing support (resent)
by Timothy R. Chavez
[note]
I'm impatient. The patch is ~25KB and did not seem to go through to
the list the first time, so I've resent the e-mail with a URL instead:
Download: http://www.busy-wait.com/linux-2.6.10-auditfs-tc1.patch
[/note]
Hello,
Attached to this e-mail is my first iteration of the file system
auditing piece needed for CAPP EAL4. I appreciate all feedback, but
please read the TODO list prior to sending me feedback on something
I'm already aware of. I've not stressed tested this code nor have I
done any formal FVT. The testing I have done has been.. minimal.
I've mostly seen if given scenarios work (move one watched file to
another watched location, create a hardlink to /etc/passwd from
/home/me, etc).
At this time, I'm unable to provide you with the userspace patch I
wrote, but encourage someone on this list to add the functionality to
libaudit/auditctl and submit the patch (Steve :)?). If you'd like my
"guidance" please e-mail me privately.
ABOUT:
Thus far, the patch being submitted with this e-mail implements a
rudimentary file system auditing capability using the in-kernel audit
subsystem. From userspace, an administrator passes into the kernel a
pathname and filterkey pair. The terminating file or directory does
not have to exist at the time a watch point is created for it, but
it's parent does.
If at any point the parent is destroyed, auditing information for its
children is lost. Likewise, if we mount over watched paths, we lose
auditing information, until we unmount. Currently, there is no
decision on whether or not we ought to give the audit subsystem the
capability of dynamically remapping watch paths onto new mounts or
supporting theoretical watch paths where watch paths are arbitrary and
if they should come into existence within the filesystem, they become
watched and thus auditable. Also, if I remember my code correctly, if
you move out of a watch path into a path that is not being watched,
your watch field is still pointing in a watch list, and will be
audited. If you destroy this file or directory and recreate it in the
same (unwatched) path, it will no longer be audited. I think I need
to add a field to the watch where we can enable/disable this behavior
per watch entry.
Provided both syscall auditing and file system auditing are both
configured and enabled, when a syscall of interest accesses a file or
directory being watched, it collects information about that file or
directory (via it's inode and watch entry) and adds it to the
audit_context of that syscall. When the syscall exits, any files or
directory information collected is sent to userspace to be logged.
TODOs:
* Add RCU locking in the appropriate places to make SMP-safe
* Switch over to slab caches for struct audit_data, struct audit_file,
and struct audit_watch
* Think about how I can make it so an administrator can say, "Watch
this file only on the syscall open where uid=0" -- As of right now, if
filesystem auditing is on, every syscall (being audited) that accesses
a watched file or directory collects information about it and
generates a record. Is this sufficient?
* Make it so filesystem auditing can be dynamically enabled/disabled
from userspace, rather then being "enabled" if configured or
"disabled" if not configured at boot time.
* Add/remove unnecessary information about the file or directory being
collected in the audit context. Input on this?
--
- Timothy R. Chavez
19 years, 11 months
[PATCH] enable /proc/$$/loginuid
by Serge Hallyn
Changelog:
1/14/2005: Added several checks for error values which were missing.
1/07/2005: First version.
Is this ready for lkml?
thanks,
-serge
--
Serge Hallyn <serue(a)us.ibm.com>
19 years, 11 months
FC3 kernel packages.
by David Woodhouse
I'm in the process of uploading a 'kernel-2.6.10-1.747_FC3.audit.1'
package (slowly) to ftp://ftp.infradead.org/pub/audit/
It's the current FC3 erratum kernel branch, with four patches added:
linux-2.6.10-audit-caps.patch
Serge's audit-caps patch from message
<20050114214353.GC3472(a)IBM-BWN8ZTBWA01.austin.ibm.com>
linux-2.6.10-audit-loginuid-into-taskstruct.patch
linux-2.6.10-audit-loginuid-proc.patch
linux-2.6.10-audit-netlink-loginuid.patch
Serge's three patches from last night, with my suggestion about
init_task.h implemented.
--
dwmw2
19 years, 11 months