Skip to content

Commit 9d99b16

Browse files
committed
Merge tag 'audit-pr-20200601' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit
Pull audit updates from Paul Moore: "Summary of the significant patches: - Record information about binds/unbinds to the audit multicast socket. This helps identify which processes have/had access to the information in the audit stream. - Cleanup and add some additional information to the netfilter configuration events collected by audit. - Fix some of the audit error handling code so we don't leak network namespace references" * tag 'audit-pr-20200601' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: add subj creds to NETFILTER_CFG record to audit: Replace zero-length array with flexible-array audit: make symbol 'audit_nfcfgs' static netfilter: add audit table unregister actions audit: tidy and extend netfilter_cfg x_tables audit: log audit netlink multicast bind and unbind audit: fix a net reference leak in audit_list_rules_send() audit: fix a net reference leak in audit_send_reply()
2 parents 91681e8 + 9d44a12 commit 9d99b16

File tree

8 files changed

+148
-54
lines changed

8 files changed

+148
-54
lines changed

include/linux/audit.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
struct audit_sig_info {
2020
uid_t uid;
2121
pid_t pid;
22-
char ctx[0];
22+
char ctx[];
2323
};
2424

2525
struct audit_buffer;
@@ -94,6 +94,12 @@ struct audit_ntp_data {
9494
struct audit_ntp_data {};
9595
#endif
9696

97+
enum audit_nfcfgop {
98+
AUDIT_XT_OP_REGISTER,
99+
AUDIT_XT_OP_REPLACE,
100+
AUDIT_XT_OP_UNREGISTER,
101+
};
102+
97103
extern int is_audit_feature_set(int which);
98104

99105
extern int __init audit_register_class(int class, unsigned *list);
@@ -379,6 +385,8 @@ extern void __audit_log_kern_module(char *name);
379385
extern void __audit_fanotify(unsigned int response);
380386
extern void __audit_tk_injoffset(struct timespec64 offset);
381387
extern void __audit_ntp_log(const struct audit_ntp_data *ad);
388+
extern void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
389+
enum audit_nfcfgop op);
382390

383391
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
384392
{
@@ -514,6 +522,14 @@ static inline void audit_ntp_log(const struct audit_ntp_data *ad)
514522
__audit_ntp_log(ad);
515523
}
516524

525+
static inline void audit_log_nfcfg(const char *name, u8 af,
526+
unsigned int nentries,
527+
enum audit_nfcfgop op)
528+
{
529+
if (audit_enabled)
530+
__audit_log_nfcfg(name, af, nentries, op);
531+
}
532+
517533
extern int audit_n_rules;
518534
extern int audit_signals;
519535
#else /* CONFIG_AUDITSYSCALL */
@@ -646,6 +662,12 @@ static inline void audit_ntp_log(const struct audit_ntp_data *ad)
646662

647663
static inline void audit_ptrace(struct task_struct *t)
648664
{ }
665+
666+
static inline void audit_log_nfcfg(const char *name, u8 af,
667+
unsigned int nentries,
668+
enum audit_nfcfgop op)
669+
{ }
670+
649671
#define audit_n_rules 0
650672
#define audit_signals 0
651673
#endif /* CONFIG_AUDITSYSCALL */

include/uapi/linux/audit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
#define AUDIT_TIME_INJOFFSET 1332 /* Timekeeping offset injected */
118118
#define AUDIT_TIME_ADJNTPVAL 1333 /* NTP value adjustment */
119119
#define AUDIT_BPF 1334 /* BPF subsystem */
120+
#define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */
120121

121122
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
122123
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */

kernel/audit.c

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ static int kauditd_thread(void *dummy)
880880
return 0;
881881
}
882882

883-
int audit_send_list(void *_dest)
883+
int audit_send_list_thread(void *_dest)
884884
{
885885
struct audit_netlink_list *dest = _dest;
886886
struct sk_buff *skb;
@@ -924,19 +924,30 @@ struct sk_buff *audit_make_reply(int seq, int type, int done,
924924
return NULL;
925925
}
926926

927+
static void audit_free_reply(struct audit_reply *reply)
928+
{
929+
if (!reply)
930+
return;
931+
932+
if (reply->skb)
933+
kfree_skb(reply->skb);
934+
if (reply->net)
935+
put_net(reply->net);
936+
kfree(reply);
937+
}
938+
927939
static int audit_send_reply_thread(void *arg)
928940
{
929941
struct audit_reply *reply = (struct audit_reply *)arg;
930-
struct sock *sk = audit_get_sk(reply->net);
931942

932943
audit_ctl_lock();
933944
audit_ctl_unlock();
934945

935946
/* Ignore failure. It'll only happen if the sender goes away,
936947
because our timeout is set to infinite. */
937-
netlink_unicast(sk, reply->skb, reply->portid, 0);
938-
put_net(reply->net);
939-
kfree(reply);
948+
netlink_unicast(audit_get_sk(reply->net), reply->skb, reply->portid, 0);
949+
reply->skb = NULL;
950+
audit_free_reply(reply);
940951
return 0;
941952
}
942953

@@ -950,35 +961,32 @@ static int audit_send_reply_thread(void *arg)
950961
* @payload: payload data
951962
* @size: payload size
952963
*
953-
* Allocates an skb, builds the netlink message, and sends it to the port id.
954-
* No failure notifications.
964+
* Allocates a skb, builds the netlink message, and sends it to the port id.
955965
*/
956966
static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
957967
int multi, const void *payload, int size)
958968
{
959-
struct net *net = sock_net(NETLINK_CB(request_skb).sk);
960-
struct sk_buff *skb;
961969
struct task_struct *tsk;
962-
struct audit_reply *reply = kmalloc(sizeof(struct audit_reply),
963-
GFP_KERNEL);
970+
struct audit_reply *reply;
964971

972+
reply = kzalloc(sizeof(*reply), GFP_KERNEL);
965973
if (!reply)
966974
return;
967975

968-
skb = audit_make_reply(seq, type, done, multi, payload, size);
969-
if (!skb)
970-
goto out;
971-
972-
reply->net = get_net(net);
976+
reply->skb = audit_make_reply(seq, type, done, multi, payload, size);
977+
if (!reply->skb)
978+
goto err;
979+
reply->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
973980
reply->portid = NETLINK_CB(request_skb).portid;
974-
reply->skb = skb;
975981

976982
tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
977-
if (!IS_ERR(tsk))
978-
return;
979-
kfree_skb(skb);
980-
out:
981-
kfree(reply);
983+
if (IS_ERR(tsk))
984+
goto err;
985+
986+
return;
987+
988+
err:
989+
audit_free_reply(reply);
982990
}
983991

984992
/*
@@ -1525,20 +1533,60 @@ static void audit_receive(struct sk_buff *skb)
15251533
audit_ctl_unlock();
15261534
}
15271535

1536+
/* Log information about who is connecting to the audit multicast socket */
1537+
static void audit_log_multicast(int group, const char *op, int err)
1538+
{
1539+
const struct cred *cred;
1540+
struct tty_struct *tty;
1541+
char comm[sizeof(current->comm)];
1542+
struct audit_buffer *ab;
1543+
1544+
if (!audit_enabled)
1545+
return;
1546+
1547+
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_EVENT_LISTENER);
1548+
if (!ab)
1549+
return;
1550+
1551+
cred = current_cred();
1552+
tty = audit_get_tty();
1553+
audit_log_format(ab, "pid=%u uid=%u auid=%u tty=%s ses=%u",
1554+
task_pid_nr(current),
1555+
from_kuid(&init_user_ns, cred->uid),
1556+
from_kuid(&init_user_ns, audit_get_loginuid(current)),
1557+
tty ? tty_name(tty) : "(none)",
1558+
audit_get_sessionid(current));
1559+
audit_put_tty(tty);
1560+
audit_log_task_context(ab); /* subj= */
1561+
audit_log_format(ab, " comm=");
1562+
audit_log_untrustedstring(ab, get_task_comm(comm, current));
1563+
audit_log_d_path_exe(ab, current->mm); /* exe= */
1564+
audit_log_format(ab, " nl-mcgrp=%d op=%s res=%d", group, op, !err);
1565+
audit_log_end(ab);
1566+
}
1567+
15281568
/* Run custom bind function on netlink socket group connect or bind requests. */
1529-
static int audit_bind(struct net *net, int group)
1569+
static int audit_multicast_bind(struct net *net, int group)
15301570
{
1571+
int err = 0;
1572+
15311573
if (!capable(CAP_AUDIT_READ))
1532-
return -EPERM;
1574+
err = -EPERM;
1575+
audit_log_multicast(group, "connect", err);
1576+
return err;
1577+
}
15331578

1534-
return 0;
1579+
static void audit_multicast_unbind(struct net *net, int group)
1580+
{
1581+
audit_log_multicast(group, "disconnect", 0);
15351582
}
15361583

15371584
static int __net_init audit_net_init(struct net *net)
15381585
{
15391586
struct netlink_kernel_cfg cfg = {
15401587
.input = audit_receive,
1541-
.bind = audit_bind,
1588+
.bind = audit_multicast_bind,
1589+
.unbind = audit_multicast_unbind,
15421590
.flags = NL_CFG_F_NONROOT_RECV,
15431591
.groups = AUDIT_NLGRP_MAX,
15441592
};

kernel/audit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ struct audit_netlink_list {
229229
struct sk_buff_head q;
230230
};
231231

232-
int audit_send_list(void *_dest);
232+
int audit_send_list_thread(void *_dest);
233233

234234
extern int selinux_audit_rule_update(void);
235235

kernel/auditfilter.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,37 +1161,35 @@ int audit_rule_change(int type, int seq, void *data, size_t datasz)
11611161
*/
11621162
int audit_list_rules_send(struct sk_buff *request_skb, int seq)
11631163
{
1164-
u32 portid = NETLINK_CB(request_skb).portid;
1165-
struct net *net = sock_net(NETLINK_CB(request_skb).sk);
11661164
struct task_struct *tsk;
11671165
struct audit_netlink_list *dest;
1168-
int err = 0;
11691166

11701167
/* We can't just spew out the rules here because we might fill
11711168
* the available socket buffer space and deadlock waiting for
11721169
* auditctl to read from it... which isn't ever going to
11731170
* happen if we're actually running in the context of auditctl
11741171
* trying to _send_ the stuff */
11751172

1176-
dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
1173+
dest = kmalloc(sizeof(*dest), GFP_KERNEL);
11771174
if (!dest)
11781175
return -ENOMEM;
1179-
dest->net = get_net(net);
1180-
dest->portid = portid;
1176+
dest->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
1177+
dest->portid = NETLINK_CB(request_skb).portid;
11811178
skb_queue_head_init(&dest->q);
11821179

11831180
mutex_lock(&audit_filter_mutex);
11841181
audit_list_rules(seq, &dest->q);
11851182
mutex_unlock(&audit_filter_mutex);
11861183

1187-
tsk = kthread_run(audit_send_list, dest, "audit_send_list");
1184+
tsk = kthread_run(audit_send_list_thread, dest, "audit_send_list");
11881185
if (IS_ERR(tsk)) {
11891186
skb_queue_purge(&dest->q);
1187+
put_net(dest->net);
11901188
kfree(dest);
1191-
err = PTR_ERR(tsk);
1189+
return PTR_ERR(tsk);
11921190
}
11931191

1194-
return err;
1192+
return 0;
11951193
}
11961194

11971195
int audit_comparator(u32 left, u32 op, u32 right)

kernel/auditsc.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@ struct audit_tree_refs {
130130
struct audit_chunk *c[31];
131131
};
132132

133+
struct audit_nfcfgop_tab {
134+
enum audit_nfcfgop op;
135+
const char *s;
136+
};
137+
138+
static const struct audit_nfcfgop_tab audit_nfcfgs[] = {
139+
{ AUDIT_XT_OP_REGISTER, "register" },
140+
{ AUDIT_XT_OP_REPLACE, "replace" },
141+
{ AUDIT_XT_OP_UNREGISTER, "unregister" },
142+
};
143+
133144
static int audit_match_perm(struct audit_context *ctx, int mask)
134145
{
135146
unsigned n;
@@ -2542,6 +2553,26 @@ void __audit_ntp_log(const struct audit_ntp_data *ad)
25422553
audit_log_ntp_val(ad, "adjust", AUDIT_NTP_ADJUST);
25432554
}
25442555

2556+
void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
2557+
enum audit_nfcfgop op)
2558+
{
2559+
struct audit_buffer *ab;
2560+
char comm[sizeof(current->comm)];
2561+
2562+
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_NETFILTER_CFG);
2563+
if (!ab)
2564+
return;
2565+
audit_log_format(ab, "table=%s family=%u entries=%u op=%s",
2566+
name, af, nentries, audit_nfcfgs[op].s);
2567+
2568+
audit_log_format(ab, " pid=%u", task_pid_nr(current));
2569+
audit_log_task_context(ab); /* subj= */
2570+
audit_log_format(ab, " comm=");
2571+
audit_log_untrustedstring(ab, get_task_comm(comm, current));
2572+
audit_log_end(ab);
2573+
}
2574+
EXPORT_SYMBOL_GPL(__audit_log_nfcfg);
2575+
25452576
static void audit_log_task(struct audit_buffer *ab)
25462577
{
25472578
kuid_t auid, uid;

net/bridge/netfilter/ebtables.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,14 +1046,8 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
10461046
vfree(table);
10471047
vfree(counterstmp);
10481048

1049-
#ifdef CONFIG_AUDIT
1050-
if (audit_enabled) {
1051-
audit_log(audit_context(), GFP_KERNEL,
1052-
AUDIT_NETFILTER_CFG,
1053-
"table=%s family=%u entries=%u",
1054-
repl->name, AF_BRIDGE, repl->nentries);
1055-
}
1056-
#endif
1049+
audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
1050+
AUDIT_XT_OP_REPLACE);
10571051
return ret;
10581052

10591053
free_unlock:
@@ -1128,6 +1122,8 @@ static void __ebt_unregister_table(struct net *net, struct ebt_table *table)
11281122
mutex_lock(&ebt_mutex);
11291123
list_del(&table->list);
11301124
mutex_unlock(&ebt_mutex);
1125+
audit_log_nfcfg(table->name, AF_BRIDGE, table->private->nentries,
1126+
AUDIT_XT_OP_UNREGISTER);
11311127
EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
11321128
ebt_cleanup_entry, net, NULL);
11331129
if (table->private->nentries)
@@ -1221,6 +1217,8 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
12211217
*res = NULL;
12221218
}
12231219

1220+
audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
1221+
AUDIT_XT_OP_REGISTER);
12241222
return ret;
12251223
free_unlock:
12261224
mutex_unlock(&ebt_mutex);

net/netfilter/x_tables.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,15 +1408,9 @@ xt_replace_table(struct xt_table *table,
14081408
}
14091409
}
14101410

1411-
#ifdef CONFIG_AUDIT
1412-
if (audit_enabled) {
1413-
audit_log(audit_context(), GFP_KERNEL,
1414-
AUDIT_NETFILTER_CFG,
1415-
"table=%s family=%u entries=%u",
1416-
table->name, table->af, private->number);
1417-
}
1418-
#endif
1419-
1411+
audit_log_nfcfg(table->name, table->af, private->number,
1412+
!private->number ? AUDIT_XT_OP_REGISTER :
1413+
AUDIT_XT_OP_REPLACE);
14201414
return private;
14211415
}
14221416
EXPORT_SYMBOL_GPL(xt_replace_table);
@@ -1478,6 +1472,8 @@ void *xt_unregister_table(struct xt_table *table)
14781472
private = table->private;
14791473
list_del(&table->list);
14801474
mutex_unlock(&xt[table->af].mutex);
1475+
audit_log_nfcfg(table->name, table->af, private->number,
1476+
AUDIT_XT_OP_UNREGISTER);
14811477
kfree(table);
14821478

14831479
return private;

0 commit comments

Comments
 (0)