[PATCH] audit: log module name on delete_module
by Richard Guy Briggs
Record the module name of a delete_module call.
See: https://github.com/linux-audit/audit-kernel/issues/37
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/module.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c
index 5432dbe..633f6da 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -943,6 +943,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
return -EFAULT;
name[MODULE_NAME_LEN-1] = '\0';
+ audit_log_kern_module(name);
+
if (mutex_lock_interruptible(&module_mutex) != 0)
return -EINTR;
--
1.7.1
7 years, 7 months
Hundreds of null PATH records for *init_module syscall audit logs
by Richard Guy Briggs
The background to this is:
https://github.com/linux-audit/audit-kernel/issues/8
In short, audit SYSCALL records for *init_module were occasionally
accompanied by hundreds to thousands of null PATH records.
I chatted with Al Viro and Eric Paris about this Friday afternoon and
they seemed to vaguely recall this issue and didn't have any solid
recommendations as to what was the right thing to do (other than the
same suggestion from both that I won't print here).
It was reproducible on a number of vintages of distributions with
default kernels, but triggering on very few of the many modules loaded
at boot time. It was reproduced with fs-nfs4 and nfsv4 modules on
tracefs, but there are reports of it also happening with debugfs. It
was triggering only in __audit_inode_child with a parent that was not
found in the task context's audit names_list.
I have four potential solutions listed in my order of preference and I'd
like to get some feedback about which one would be the most acceptable.
1 - In __audit_inode_child, return immedialy upon detecting TRACEFS and
DEBUGFS (and potentially other filesystems identified, via s_magic).
2 - In __audit_inode_child, return after not finding the parent in that
task context's audit names_list.
3 - In __audit_inode_child, mark the parent and its child as "hidden"
when the parent isn't found in that task context's audit names_list.
This will still result in an "items=" count that does not match the
number of accompanying PATH records for that SYSCALL record, which
may upset userspace tools but would still indicate suppressed
records.
4 - In __audit_inode_child, when the parent isn't found, store the
child's dentry in the child's (new or not) audit_names structure
(properly refcounted with dget) and store the parent's dentry in its
newly created audit_names structure (via dget_parent), then if the
name isn't available at PATH record generation time, use that stored
value (with dentry_path_raw and released with dput)
Is there another more elegant solution that I've missed that catches
things before they get anywhere near audit_inode_child (called from
tracefs' notifiers)?
I'll thread onto this message tested patches for all four solutions.
- RGB
--
Richard Guy Briggs <rgb(a)redhat.com>
Kernel Security Engineering, Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635
7 years, 7 months
Re: netlink: GPF in netlink_unicast
by Richard Guy Briggs
On 2017-03-06 10:10, Cong Wang wrote:
> On Mon, Mar 6, 2017 at 2:54 AM, Dmitry Vyukov <dvyukov(a)google.com> wrote:
> > Hello,
> >
> > I've got the following crash while running syzkaller fuzzer on
> > net-next/8d70eeb84ab277377c017af6a21d0a337025dede:
> >
> > kasan: GPF could be caused by NULL-ptr deref or user memory access
> > general protection fault: 0000 [#1] SMP KASAN
> > Dumping ftrace buffer:
> > (ftrace buffer empty)
> > Modules linked in:
> > CPU: 0 PID: 883 Comm: kauditd Not tainted 4.10.0+ #6
> > Hardware name: Google Google Compute Engine/Google Compute Engine,
> > BIOS Google 01/01/2011
> > task: ffff8801d79f0240 task.stack: ffff8801d7a20000
> > RIP: 0010:sock_sndtimeo include/net/sock.h:2162 [inline]
> > RIP: 0010:netlink_unicast+0xdd/0x730 net/netlink/af_netlink.c:1249
> > RSP: 0018:ffff8801d7a27c38 EFLAGS: 00010206
> > RAX: 0000000000000056 RBX: ffff8801d7a27cd0 RCX: 0000000000000000
> > RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000000002b0
> > RBP: ffff8801d7a27cf8 R08: ffffed00385cf286 R09: ffffed00385cf286
> > R10: 0000000000000006 R11: ffffed00385cf285 R12: 0000000000000000
> > R13: dffffc0000000000 R14: ffff8801c2fc3c80 R15: 00000000014000c0
> > FS: 0000000000000000(0000) GS:ffff8801dbe00000(0000) knlGS:0000000000000000
> > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > CR2: 0000000020cfd000 CR3: 00000001c758f000 CR4: 00000000001406f0
> > Call Trace:
> > kauditd_send_unicast_skb+0x3c/0x70 kernel/audit.c:482
> > kauditd_thread+0x174/0xb00 kernel/audit.c:599
> > kthread+0x326/0x3f0 kernel/kthread.c:229
> > ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430
> > Code: 44 89 fe e8 56 15 ff ff 8b 8d 70 ff ff ff 49 89 c6 31 c0 85 c9
> > 75 27 e8 b2 b2 f4 fd 49 8d bc 24 b0 02 00 00 48 89 f8 48 c1 e8 03 <42>
> > 80 3c 28 00 0f 85 37 06 00 00 49 8b 84 24 b0 02 00 00 4c 8d
> > RIP: sock_sndtimeo include/net/sock.h:2162 [inline] RSP: ffff8801d7a27c38
> > RIP: netlink_unicast+0xdd/0x730 net/netlink/af_netlink.c:1249 RSP:
> > ffff8801d7a27c38
> > ---[ end trace ad1bba9d457430b6 ]---
> > Kernel panic - not syncing: Fatal exception
> >
> >
> > This is not reproducible and seems to be caused by an elusive race.
> > However, looking at the code I don't see any proper protection of
> > audit_sock (other than the if (!audit_pid) which is obviously not
> > enough to protect against races).
>
> audit_cmd_mutex is supposed to protect it, I think.
> But kauditd_send_unicast_skb() seems not holding this mutex.
Hmmmm, I wonder if it makes sense to wrap most of the contents of the
outer while loop in kauditd_thread in the audit_cmd_mutex, or around the
first two innter while loops and the "if (auditd)" condition after the
"quick_loop:" label. The condition on auditd is supposed to catch that
case. We don't want it locked while playing with the scheduler at the
bottom of that function.
> Richard?
- RGB
--
Richard Guy Briggs <rgb(a)redhat.com>
Kernel Security Engineering, Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635
7 years, 7 months
"write_logs = no" not working
by Ian Pilcher
I have a Banana Pi-based firewall system, which runs off a micro-SD
card and sends all of its logs (including audit events) to a syslog
server.
I have set "write_logs = no" in /etc/audit/auditd.conf, but the local
log file is still being written. (Commenting out the log_file line
causes auditd to abort.)
What do I need to do to disable writing the local file?
(This is audit 2.6.5 on CentOS 7.)
--
========================================================================
Ian Pilcher arequipeno(a)gmail.com
-------- "I grew up before Mark Zuckerberg invented friendship" --------
========================================================================
7 years, 8 months
"write_logs = no" not working
by Ian Pilcher
(Apologies if this is a duplicate. gmane doesn't seem to be working.)
I have a Banana Pi-based firewall system, which runs off a micro-SD
card and sends all of its logs (including audit events) to a syslog
server.
I have set "write_logs = no" in /etc/audit/auditd.conf, but the local
log file is still being written. (Commenting out the log_file line
causes auditd to abort.)
What do I need to do to disable writing the local file?
(This is audit 2.6.5 on CentOS 7.)
--
========================================================================
Ian Pilcher arequipeno(a)gmail.com
-------- "I grew up before Mark Zuckerberg invented friendship" --------
========================================================================
7 years, 8 months
[PATCH V3] audit: normalize NETFILTER_PKT
by Richard Guy Briggs
Eliminate flipping in and out of message fields, dropping fields in the process.
Sample raw message format IPv4 UDP:
type=NETFILTER_PKT msg=audit(1487874761.386:228): mark=0xae8a2732 saddr=127.0.0.1 daddr=127.0.0.1 proto=17^]
Sample raw message format IPv6 ICMP6:
type=NETFILTER_PKT msg=audit(1487874761.381:227): mark=0x223894b7 saddr=::1 daddr=::1 proto=58^]
Issue: https://github.com/linux-audit/audit-kernel/issues/11
Test case: https://github.com/linux-audit/audit-testsuite/issues/43
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
net/netfilter/xt_AUDIT.c | 122 ++++++++++-----------------------------------
1 files changed, 27 insertions(+), 95 deletions(-)
diff --git a/net/netfilter/xt_AUDIT.c b/net/netfilter/xt_AUDIT.c
index 4973cbd..945fa29 100644
--- a/net/netfilter/xt_AUDIT.c
+++ b/net/netfilter/xt_AUDIT.c
@@ -31,146 +31,78 @@ MODULE_ALIAS("ip6t_AUDIT");
MODULE_ALIAS("ebt_AUDIT");
MODULE_ALIAS("arpt_AUDIT");
-static void audit_proto(struct audit_buffer *ab, struct sk_buff *skb,
- unsigned int proto, unsigned int offset)
-{
- switch (proto) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE: {
- const __be16 *pptr;
- __be16 _ports[2];
-
- pptr = skb_header_pointer(skb, offset, sizeof(_ports), _ports);
- if (pptr == NULL) {
- audit_log_format(ab, " truncated=1");
- return;
- }
-
- audit_log_format(ab, " sport=%hu dport=%hu",
- ntohs(pptr[0]), ntohs(pptr[1]));
- }
- break;
-
- case IPPROTO_ICMP:
- case IPPROTO_ICMPV6: {
- const u8 *iptr;
- u8 _ih[2];
-
- iptr = skb_header_pointer(skb, offset, sizeof(_ih), &_ih);
- if (iptr == NULL) {
- audit_log_format(ab, " truncated=1");
- return;
- }
-
- audit_log_format(ab, " icmptype=%hhu icmpcode=%hhu",
- iptr[0], iptr[1]);
-
- }
- break;
- }
-}
-
-static void audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
+static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb)
{
struct iphdr _iph;
const struct iphdr *ih;
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
- if (!ih) {
- audit_log_format(ab, " truncated=1");
- return;
- }
+ if (!ih)
+ return false;
- audit_log_format(ab, " saddr=%pI4 daddr=%pI4 ipid=%hu proto=%hhu",
- &ih->saddr, &ih->daddr, ntohs(ih->id), ih->protocol);
+ audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
+ &ih->saddr, &ih->daddr, ih->protocol);
- if (ntohs(ih->frag_off) & IP_OFFSET) {
- audit_log_format(ab, " frag=1");
- return;
- }
-
- audit_proto(ab, skb, ih->protocol, ih->ihl * 4);
+ return true;
}
-static void audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
+static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb)
{
struct ipv6hdr _ip6h;
const struct ipv6hdr *ih;
u8 nexthdr;
__be16 frag_off;
- int offset;
ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
- if (!ih) {
- audit_log_format(ab, " truncated=1");
- return;
- }
+ if (!ih)
+ return false;
nexthdr = ih->nexthdr;
- offset = ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h),
- &nexthdr, &frag_off);
+ ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
&ih->saddr, &ih->daddr, nexthdr);
- if (offset)
- audit_proto(ab, skb, nexthdr, offset);
+ return true;
}
static unsigned int
audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
- const struct xt_audit_info *info = par->targinfo;
struct audit_buffer *ab;
+ int fam = -1;
if (audit_enabled == 0)
goto errout;
-
ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
if (ab == NULL)
goto errout;
- audit_log_format(ab, "action=%hhu hook=%u len=%u inif=%s outif=%s",
- info->type, par->hooknum, skb->len,
- par->in ? par->in->name : "?",
- par->out ? par->out->name : "?");
-
- if (skb->mark)
- audit_log_format(ab, " mark=%#x", skb->mark);
-
- if (skb->dev && skb->dev->type == ARPHRD_ETHER) {
- audit_log_format(ab, " smac=%pM dmac=%pM macproto=0x%04x",
- eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
- ntohs(eth_hdr(skb)->h_proto));
+ audit_log_format(ab, "mark=%#x", skb->mark ?: -1);
- if (par->family == NFPROTO_BRIDGE) {
+ switch (par->family) {
+ case NFPROTO_BRIDGE: {
switch (eth_hdr(skb)->h_proto) {
case htons(ETH_P_IP):
- audit_ip4(ab, skb);
+ fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
break;
-
case htons(ETH_P_IPV6):
- audit_ip6(ab, skb);
+ fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
break;
}
+ break;
}
+ case NFPROTO_IPV4:
+ fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
+ break;
+
+ case NFPROTO_IPV6:
+ fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
+ break;
}
- switch (par->family) {
- case NFPROTO_IPV4:
- audit_ip4(ab, skb);
- break;
-
- case NFPROTO_IPV6:
- audit_ip6(ab, skb);
- break;
- }
-
-#ifdef CONFIG_NETWORK_SECMARK
- if (skb->secmark)
- audit_log_secctx(ab, skb->secmark);
-#endif
+ if (fam == -1)
+ audit_log_format(ab, " saddr=? daddr=? proto=-1");
audit_log_end(ab);
--
1.7.1
7 years, 8 months