Commit 46f0537b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'stable-4.12' of git://git.infradead.org/users/pcmoore/audit

Pull audit updates from Paul Moore:
 "Fourteen audit patches for v4.12 that span the full range of fixes,
  new features, and internal cleanups.

  We have a patches to move to 64-bit timestamps, convert refcounts from
  atomic_t to refcount_t, track PIDs using the pid struct instead of
  pid_t, convert our own private audit buffer cache to a standard
  kmem_cache, log kernel module names when they are unloaded, and
  normalize the NETFILTER_PKT to make the userspace folks happier.

  From a fixes perspective, the most important is likely the auditd
  connection tracking RCU fix; it was a rather brain dead bug that I'll
  take the blame for, but thankfully it didn't seem to affect many
  people (only one report).

  I think the patch subject lines and commit descriptions do a pretty
  good job of explaining the details and why the changes are important
  so I'll point you there instead of duplicating it here; as usual, if
  you have any questions you know where to find us.

  We also manage to take out more code than we put in this time, that
  always makes me happy :)"

* 'stable-4.12' of git://git.infradead.org/users/pcmoore/audit:
  audit: fix the RCU locking for the auditd_connection structure
  audit: use kmem_cache to manage the audit_buffer cache
  audit: Use timespec64 to represent audit timestamps
  audit: store the auditd PID as a pid struct instead of pid_t
  audit: kernel generated netlink traffic should have a portid of 0
  audit: combine audit_receive() and audit_receive_skb()
  audit: convert audit_watch.count from atomic_t to refcount_t
  audit: convert audit_tree.count from atomic_t to refcount_t
  audit: normalize NETFILTER_PKT
  netfilter: use consistent ipv4 network offset in xt_AUDIT
  audit: log module name on delete_module
  audit: remove unnecessary semicolon in audit_watch_handle_event()
  audit: remove unnecessary semicolon in audit_mark_handle_event()
  audit: remove unnecessary semicolon in audit_field_valid()
parents 0302e28d 48d0e023
...@@ -163,8 +163,7 @@ extern void audit_log_task_info(struct audit_buffer *ab, ...@@ -163,8 +163,7 @@ extern void audit_log_task_info(struct audit_buffer *ab,
extern int audit_update_lsm_rules(void); extern int audit_update_lsm_rules(void);
/* Private API (for audit.c only) */ /* Private API (for audit.c only) */
extern int audit_rule_change(int type, __u32 portid, int seq, extern int audit_rule_change(int type, int seq, void *data, size_t datasz);
void *data, size_t datasz);
extern int audit_list_rules_send(struct sk_buff *request_skb, int seq); extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
extern u32 audit_enabled; extern u32 audit_enabled;
...@@ -332,7 +331,7 @@ static inline void audit_ptrace(struct task_struct *t) ...@@ -332,7 +331,7 @@ static inline void audit_ptrace(struct task_struct *t)
/* Private API (for audit.c only) */ /* Private API (for audit.c only) */
extern unsigned int audit_serial(void); extern unsigned int audit_serial(void);
extern int auditsc_get_stamp(struct audit_context *ctx, extern int auditsc_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial); struct timespec64 *t, unsigned int *serial);
extern int audit_set_loginuid(kuid_t loginuid); extern int audit_set_loginuid(kuid_t loginuid);
static inline kuid_t audit_get_loginuid(struct task_struct *tsk) static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
...@@ -511,7 +510,7 @@ static inline void __audit_seccomp(unsigned long syscall, long signr, int code) ...@@ -511,7 +510,7 @@ static inline void __audit_seccomp(unsigned long syscall, long signr, int code)
static inline void audit_seccomp(unsigned long syscall, long signr, int code) static inline void audit_seccomp(unsigned long syscall, long signr, int code)
{ } { }
static inline int auditsc_get_stamp(struct audit_context *ctx, static inline int auditsc_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial) struct timespec64 *t, unsigned int *serial)
{ {
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -112,7 +112,7 @@ struct audit_context { ...@@ -112,7 +112,7 @@ struct audit_context {
enum audit_state state, current_state; enum audit_state state, current_state;
unsigned int serial; /* serial number for record */ unsigned int serial; /* serial number for record */
int major; /* syscall number */ int major; /* syscall number */
struct timespec ctime; /* time of syscall entry */ struct timespec64 ctime; /* time of syscall entry */
unsigned long argv[4]; /* syscall arguments */ unsigned long argv[4]; /* syscall arguments */
long return_code;/* syscall return code */ long return_code;/* syscall return code */
u64 prio; u64 prio;
...@@ -218,7 +218,7 @@ extern void audit_log_name(struct audit_context *context, ...@@ -218,7 +218,7 @@ extern void audit_log_name(struct audit_context *context,
struct audit_names *n, const struct path *path, struct audit_names *n, const struct path *path,
int record_num, int *call_panic); int record_num, int *call_panic);
extern int auditd_test_task(const struct task_struct *task); extern int auditd_test_task(struct task_struct *task);
#define AUDIT_INODE_BUCKETS 32 #define AUDIT_INODE_BUCKETS 32
extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
...@@ -237,8 +237,7 @@ extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right); ...@@ -237,8 +237,7 @@ extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
extern int parent_len(const char *path); extern int parent_len(const char *path);
extern int audit_compare_dname_path(const char *dname, const char *path, int plen); extern int audit_compare_dname_path(const char *dname, const char *path, int plen);
extern struct sk_buff *audit_make_reply(__u32 portid, int seq, int type, extern struct sk_buff *audit_make_reply(int seq, int type, int done, int multi,
int done, int multi,
const void *payload, int size); const void *payload, int size);
extern void audit_panic(const char *message); extern void audit_panic(const char *message);
......
...@@ -187,7 +187,7 @@ static int audit_mark_handle_event(struct fsnotify_group *group, ...@@ -187,7 +187,7 @@ static int audit_mark_handle_event(struct fsnotify_group *group,
default: default:
BUG(); BUG();
return 0; return 0;
}; }
if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) { if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) {
if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL)) if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL))
......
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/refcount.h>
#include <linux/slab.h> #include <linux/slab.h>
struct audit_tree; struct audit_tree;
struct audit_chunk; struct audit_chunk;
struct audit_tree { struct audit_tree {
atomic_t count; refcount_t count;
int goner; int goner;
struct audit_chunk *root; struct audit_chunk *root;
struct list_head chunks; struct list_head chunks;
...@@ -77,7 +78,7 @@ static struct audit_tree *alloc_tree(const char *s) ...@@ -77,7 +78,7 @@ static struct audit_tree *alloc_tree(const char *s)
tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL); tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
if (tree) { if (tree) {
atomic_set(&tree->count, 1); refcount_set(&tree->count, 1);
tree->goner = 0; tree->goner = 0;
INIT_LIST_HEAD(&tree->chunks); INIT_LIST_HEAD(&tree->chunks);
INIT_LIST_HEAD(&tree->rules); INIT_LIST_HEAD(&tree->rules);
...@@ -91,12 +92,12 @@ static struct audit_tree *alloc_tree(const char *s) ...@@ -91,12 +92,12 @@ static struct audit_tree *alloc_tree(const char *s)
static inline void get_tree(struct audit_tree *tree) static inline void get_tree(struct audit_tree *tree)
{ {
atomic_inc(&tree->count); refcount_inc(&tree->count);
} }
static inline void put_tree(struct audit_tree *tree) static inline void put_tree(struct audit_tree *tree)
{ {
if (atomic_dec_and_test(&tree->count)) if (refcount_dec_and_test(&tree->count))
kfree_rcu(tree, head); kfree_rcu(tree, head);
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/fsnotify_backend.h> #include <linux/fsnotify_backend.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/refcount.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/security.h> #include <linux/security.h>
...@@ -46,7 +47,7 @@ ...@@ -46,7 +47,7 @@
*/ */
struct audit_watch { struct audit_watch {
atomic_t count; /* reference count */ refcount_t count; /* reference count */
dev_t dev; /* associated superblock device */ dev_t dev; /* associated superblock device */
char *path; /* insertion path */ char *path; /* insertion path */
unsigned long ino; /* associated inode number */ unsigned long ino; /* associated inode number */
...@@ -111,12 +112,12 @@ static inline struct audit_parent *audit_find_parent(struct inode *inode) ...@@ -111,12 +112,12 @@ static inline struct audit_parent *audit_find_parent(struct inode *inode)
void audit_get_watch(struct audit_watch *watch) void audit_get_watch(struct audit_watch *watch)
{ {
atomic_inc(&watch->count); refcount_inc(&watch->count);
} }
void audit_put_watch(struct audit_watch *watch) void audit_put_watch(struct audit_watch *watch)
{ {
if (atomic_dec_and_test(&watch->count)) { if (refcount_dec_and_test(&watch->count)) {
WARN_ON(watch->parent); WARN_ON(watch->parent);
WARN_ON(!list_empty(&watch->rules)); WARN_ON(!list_empty(&watch->rules));
kfree(watch->path); kfree(watch->path);
...@@ -178,7 +179,7 @@ static struct audit_watch *audit_init_watch(char *path) ...@@ -178,7 +179,7 @@ static struct audit_watch *audit_init_watch(char *path)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&watch->rules); INIT_LIST_HEAD(&watch->rules);
atomic_set(&watch->count, 1); refcount_set(&watch->count, 1);
watch->path = path; watch->path = path;
watch->dev = AUDIT_DEV_UNSET; watch->dev = AUDIT_DEV_UNSET;
watch->ino = AUDIT_INO_UNSET; watch->ino = AUDIT_INO_UNSET;
...@@ -492,7 +493,7 @@ static int audit_watch_handle_event(struct fsnotify_group *group, ...@@ -492,7 +493,7 @@ static int audit_watch_handle_event(struct fsnotify_group *group,
BUG(); BUG();
inode = NULL; inode = NULL;
break; break;
}; }
if (mask & (FS_CREATE|FS_MOVED_TO) && inode) if (mask & (FS_CREATE|FS_MOVED_TO) && inode)
audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0); audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0);
......
...@@ -338,7 +338,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) ...@@ -338,7 +338,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
entry->rule.listnr != AUDIT_FILTER_USER) entry->rule.listnr != AUDIT_FILTER_USER)
return -EINVAL; return -EINVAL;
break; break;
}; }
switch(f->type) { switch(f->type) {
default: default:
...@@ -412,7 +412,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) ...@@ -412,7 +412,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (entry->rule.listnr != AUDIT_FILTER_EXIT) if (entry->rule.listnr != AUDIT_FILTER_EXIT)
return -EINVAL; return -EINVAL;
break; break;
}; }
return 0; return 0;
} }
...@@ -1033,7 +1033,7 @@ int audit_del_rule(struct audit_entry *entry) ...@@ -1033,7 +1033,7 @@ int audit_del_rule(struct audit_entry *entry)
} }
/* List rules using struct audit_rule_data. */ /* List rules using struct audit_rule_data. */
static void audit_list_rules(__u32 portid, int seq, struct sk_buff_head *q) static void audit_list_rules(int seq, struct sk_buff_head *q)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct audit_krule *r; struct audit_krule *r;
...@@ -1048,15 +1048,15 @@ static void audit_list_rules(__u32 portid, int seq, struct sk_buff_head *q) ...@@ -1048,15 +1048,15 @@ static void audit_list_rules(__u32 portid, int seq, struct sk_buff_head *q)
data = audit_krule_to_data(r); data = audit_krule_to_data(r);
if (unlikely(!data)) if (unlikely(!data))
break; break;
skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES, skb = audit_make_reply(seq, AUDIT_LIST_RULES, 0, 1,
0, 1, data, data,
sizeof(*data) + data->buflen); sizeof(*data) + data->buflen);
if (skb) if (skb)
skb_queue_tail(q, skb); skb_queue_tail(q, skb);
kfree(data); kfree(data);
} }
} }
skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0); skb = audit_make_reply(seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
if (skb) if (skb)
skb_queue_tail(q, skb); skb_queue_tail(q, skb);
} }
...@@ -1085,13 +1085,11 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re ...@@ -1085,13 +1085,11 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
/** /**
* audit_rule_change - apply all rules to the specified message type * audit_rule_change - apply all rules to the specified message type
* @type: audit message type * @type: audit message type
* @portid: target port id for netlink audit messages
* @seq: netlink audit message sequence (serial) number * @seq: netlink audit message sequence (serial) number
* @data: payload data * @data: payload data
* @datasz: size of payload data * @datasz: size of payload data
*/ */
int audit_rule_change(int type, __u32 portid, int seq, void *data, int audit_rule_change(int type, int seq, void *data, size_t datasz)
size_t datasz)
{ {
int err = 0; int err = 0;
struct audit_entry *entry; struct audit_entry *entry;
...@@ -1150,7 +1148,7 @@ int audit_list_rules_send(struct sk_buff *request_skb, int seq) ...@@ -1150,7 +1148,7 @@ int audit_list_rules_send(struct sk_buff *request_skb, int seq)
skb_queue_head_init(&dest->q); skb_queue_head_init(&dest->q);
mutex_lock(&audit_filter_mutex); mutex_lock(&audit_filter_mutex);
audit_list_rules(portid, seq, &dest->q); audit_list_rules(seq, &dest->q);
mutex_unlock(&audit_filter_mutex); mutex_unlock(&audit_filter_mutex);
tsk = kthread_run(audit_send_list, dest, "audit_send_list"); tsk = kthread_run(audit_send_list, dest, "audit_send_list");
......
...@@ -1532,7 +1532,7 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2, ...@@ -1532,7 +1532,7 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
return; return;
context->serial = 0; context->serial = 0;
context->ctime = CURRENT_TIME; ktime_get_real_ts64(&context->ctime);
context->in_syscall = 1; context->in_syscall = 1;
context->current_state = state; context->current_state = state;
context->ppid = 0; context->ppid = 0;
...@@ -1941,13 +1941,13 @@ EXPORT_SYMBOL_GPL(__audit_inode_child); ...@@ -1941,13 +1941,13 @@ EXPORT_SYMBOL_GPL(__audit_inode_child);
/** /**
* auditsc_get_stamp - get local copies of audit_context values * auditsc_get_stamp - get local copies of audit_context values
* @ctx: audit_context for the task * @ctx: audit_context for the task
* @t: timespec to store time recorded in the audit_context * @t: timespec64 to store time recorded in the audit_context
* @serial: serial value that is recorded in the audit_context * @serial: serial value that is recorded in the audit_context
* *
* Also sets the context as auditable. * Also sets the context as auditable.
*/ */
int auditsc_get_stamp(struct audit_context *ctx, int auditsc_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial) struct timespec64 *t, unsigned int *serial)
{ {
if (!ctx->in_syscall) if (!ctx->in_syscall)
return 0; return 0;
......
...@@ -963,6 +963,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, ...@@ -963,6 +963,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
return -EFAULT; return -EFAULT;
name[MODULE_NAME_LEN-1] = '\0'; name[MODULE_NAME_LEN-1] = '\0';
audit_log_kern_module(name);
if (mutex_lock_interruptible(&module_mutex) != 0) if (mutex_lock_interruptible(&module_mutex) != 0)
return -EINTR; return -EINTR;
......
...@@ -31,146 +31,76 @@ MODULE_ALIAS("ip6t_AUDIT"); ...@@ -31,146 +31,76 @@ MODULE_ALIAS("ip6t_AUDIT");
MODULE_ALIAS("ebt_AUDIT"); MODULE_ALIAS("ebt_AUDIT");
MODULE_ALIAS("arpt_AUDIT"); MODULE_ALIAS("arpt_AUDIT");
static void audit_proto(struct audit_buffer *ab, struct sk_buff *skb, static bool audit_ip4(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)
{ {
struct iphdr _iph; struct iphdr _iph;
const struct iphdr *ih; const struct iphdr *ih;
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph);
if (!ih) { if (!ih)
audit_log_format(ab, " truncated=1"); return false;
return;
}
audit_log_format(ab, " saddr=%pI4 daddr=%pI4 ipid=%hu proto=%hhu", audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu",
&ih->saddr, &ih->daddr, ntohs(ih->id), ih->protocol); &ih->saddr, &ih->daddr, ih->protocol);
if (ntohs(ih->frag_off) & IP_OFFSET) { return true;
audit_log_format(ab, " frag=1");
return;
}
audit_proto(ab, skb, ih->protocol, ih->ihl * 4);
} }
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; struct ipv6hdr _ip6h;
const struct ipv6hdr *ih; const struct ipv6hdr *ih;
u8 nexthdr; u8 nexthdr;
__be16 frag_off; __be16 frag_off;
int offset;
ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h); ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h);
if (!ih) { if (!ih)
audit_log_format(ab, " truncated=1"); return false;
return;
}
nexthdr = ih->nexthdr; nexthdr = ih->nexthdr;
offset = ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off);
&nexthdr, &frag_off);
audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu", audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu",
&ih->saddr, &ih->daddr, nexthdr); &ih->saddr, &ih->daddr, nexthdr);
if (offset) return true;
audit_proto(ab, skb, nexthdr, offset);
} }
static unsigned int static unsigned int
audit_tg(struct sk_buff *skb, const struct xt_action_param *par) audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
{ {
const struct xt_audit_info *info = par->targinfo;
struct audit_buffer *ab; struct audit_buffer *ab;
int fam = -1;
if (audit_enabled == 0) if (audit_enabled == 0)
goto errout; goto errout;
ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT); ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
if (ab == NULL) if (ab == NULL)
goto errout; goto errout;
audit_log_format(ab, "action=%hhu hook=%u len=%u inif=%s outif=%s", audit_log_format(ab, "mark=%#x", skb->mark);
info->type, xt_hooknum(par), skb->len,
xt_in(par) ? xt_inname(par) : "?",
xt_out(par) ? xt_outname(par) : "?");
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));
if (xt_family(par) == NFPROTO_BRIDGE) {
switch (eth_hdr(skb)->h_proto) {
case htons(ETH_P_IP):
audit_ip4(ab, skb);
break;
case htons(ETH_P_IPV6):
audit_ip6(ab, skb);
break;
}
}
}
switch (xt_family(par)) { switch (xt_family(par)) {
case NFPROTO_BRIDGE:
switch (eth_hdr(skb)->h_proto) {
case htons(ETH_P_IP):
fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
break;
case htons(ETH_P_IPV6):
fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
break;
}
break;
case NFPROTO_IPV4: case NFPROTO_IPV4:
audit_ip4(ab, skb); fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1;
break; break;
case NFPROTO_IPV6: case NFPROTO_IPV6:
audit_ip6(ab, skb); fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1;
break; break;
} }
#ifdef CONFIG_NETWORK_SECMARK if (fam == -1)
if (skb->secmark) audit_log_format(ab, " saddr=? daddr=? proto=-1");
audit_log_secctx(ab, skb->secmark);
#endif
audit_log_end(ab); audit_log_end(ab);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment