audit/stable-5.8 PR 20200601
-----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAl7VnKEUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXMbHA/+PQmrPdzPvkLAjjf1y3LXvyEIAXIQ h2r8SxHa7iGyF6vVPz+ya7ux0KAm8wCVdfkokWG5jxjwK7pysS6gx9JzBVK7dbhD FsKBSoq9+to9fYlaCyX7vn85C7kK5oGrwS/ECos0BHBpij8ukLgvPQu+PDs7d4xW 1X2Nrgqnc7M4L8ayzXTQX0fDWcOkapzaN86+R+Lavb4hO/FownaYbuCFn+1mdzux ZNBpt3/y1pM6vi5YBkI1rkauBCmkl/YSX/mf/EwDNlQ0XmcadGQ6z7iwjyiE826g etCHWD3cgQH7Zzz6CxBNX8Xbq0nIQueHHiFYpVyy9lf4xleFvnfFDebrs8Q9TB6G jTWU8okioUKPZyRDaRuIAmCf/LBQRsMkIYTU3w6J0ZqsBycTw3NXPiQArmlxZESM HquxWpKoZytRiw581hiSGKNqY+R3FvA+Jroc/7bWfNOE3IdFxegvCsC3giKJf1rY AlQitehql9a5jp7A57+477WRYOygYRnd+ntMD5KqR90QSIcQXeg0/lFKhco+zc2p bXbWLE+aaOTGCeC+3Eow3T7FMWmrIn6ccKgM84+WT7YQYtRqUYu3RIZbnlYXN7uH 8xGXT6ccPcEwIjgyF87J0KyGhrbT1N91Jd2jMJkEry9OLAn/yr+pUBQtAa456MMi JYevS4atZaUqgvw= =iLfC -----END PGP SIGNATURE----- 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()
This commit is contained in:
Коммит
9d99b1647f
|
@ -19,7 +19,7 @@
|
||||||
struct audit_sig_info {
|
struct audit_sig_info {
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char ctx[0];
|
char ctx[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct audit_buffer;
|
struct audit_buffer;
|
||||||
|
@ -94,6 +94,12 @@ struct audit_ntp_data {
|
||||||
struct audit_ntp_data {};
|
struct audit_ntp_data {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum audit_nfcfgop {
|
||||||
|
AUDIT_XT_OP_REGISTER,
|
||||||
|
AUDIT_XT_OP_REPLACE,
|
||||||
|
AUDIT_XT_OP_UNREGISTER,
|
||||||
|
};
|
||||||
|
|
||||||
extern int is_audit_feature_set(int which);
|
extern int is_audit_feature_set(int which);
|
||||||
|
|
||||||
extern int __init audit_register_class(int class, unsigned *list);
|
extern int __init audit_register_class(int class, unsigned *list);
|
||||||
|
@ -379,6 +385,8 @@ extern void __audit_log_kern_module(char *name);
|
||||||
extern void __audit_fanotify(unsigned int response);
|
extern void __audit_fanotify(unsigned int response);
|
||||||
extern void __audit_tk_injoffset(struct timespec64 offset);
|
extern void __audit_tk_injoffset(struct timespec64 offset);
|
||||||
extern void __audit_ntp_log(const struct audit_ntp_data *ad);
|
extern void __audit_ntp_log(const struct audit_ntp_data *ad);
|
||||||
|
extern void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
|
||||||
|
enum audit_nfcfgop op);
|
||||||
|
|
||||||
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
|
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
|
||||||
{
|
{
|
||||||
|
@ -514,6 +522,14 @@ static inline void audit_ntp_log(const struct audit_ntp_data *ad)
|
||||||
__audit_ntp_log(ad);
|
__audit_ntp_log(ad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void audit_log_nfcfg(const char *name, u8 af,
|
||||||
|
unsigned int nentries,
|
||||||
|
enum audit_nfcfgop op)
|
||||||
|
{
|
||||||
|
if (audit_enabled)
|
||||||
|
__audit_log_nfcfg(name, af, nentries, op);
|
||||||
|
}
|
||||||
|
|
||||||
extern int audit_n_rules;
|
extern int audit_n_rules;
|
||||||
extern int audit_signals;
|
extern int audit_signals;
|
||||||
#else /* CONFIG_AUDITSYSCALL */
|
#else /* CONFIG_AUDITSYSCALL */
|
||||||
|
@ -646,6 +662,12 @@ static inline void audit_ntp_log(const struct audit_ntp_data *ad)
|
||||||
|
|
||||||
static inline void audit_ptrace(struct task_struct *t)
|
static inline void audit_ptrace(struct task_struct *t)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
static inline void audit_log_nfcfg(const char *name, u8 af,
|
||||||
|
unsigned int nentries,
|
||||||
|
enum audit_nfcfgop op)
|
||||||
|
{ }
|
||||||
|
|
||||||
#define audit_n_rules 0
|
#define audit_n_rules 0
|
||||||
#define audit_signals 0
|
#define audit_signals 0
|
||||||
#endif /* CONFIG_AUDITSYSCALL */
|
#endif /* CONFIG_AUDITSYSCALL */
|
||||||
|
|
|
@ -117,6 +117,7 @@
|
||||||
#define AUDIT_TIME_INJOFFSET 1332 /* Timekeeping offset injected */
|
#define AUDIT_TIME_INJOFFSET 1332 /* Timekeeping offset injected */
|
||||||
#define AUDIT_TIME_ADJNTPVAL 1333 /* NTP value adjustment */
|
#define AUDIT_TIME_ADJNTPVAL 1333 /* NTP value adjustment */
|
||||||
#define AUDIT_BPF 1334 /* BPF subsystem */
|
#define AUDIT_BPF 1334 /* BPF subsystem */
|
||||||
|
#define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */
|
||||||
|
|
||||||
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
|
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
|
||||||
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
|
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
|
||||||
|
|
104
kernel/audit.c
104
kernel/audit.c
|
@ -880,7 +880,7 @@ main_queue:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int audit_send_list(void *_dest)
|
int audit_send_list_thread(void *_dest)
|
||||||
{
|
{
|
||||||
struct audit_netlink_list *dest = _dest;
|
struct audit_netlink_list *dest = _dest;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
@ -924,19 +924,30 @@ out_kfree_skb:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void audit_free_reply(struct audit_reply *reply)
|
||||||
|
{
|
||||||
|
if (!reply)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (reply->skb)
|
||||||
|
kfree_skb(reply->skb);
|
||||||
|
if (reply->net)
|
||||||
|
put_net(reply->net);
|
||||||
|
kfree(reply);
|
||||||
|
}
|
||||||
|
|
||||||
static int audit_send_reply_thread(void *arg)
|
static int audit_send_reply_thread(void *arg)
|
||||||
{
|
{
|
||||||
struct audit_reply *reply = (struct audit_reply *)arg;
|
struct audit_reply *reply = (struct audit_reply *)arg;
|
||||||
struct sock *sk = audit_get_sk(reply->net);
|
|
||||||
|
|
||||||
audit_ctl_lock();
|
audit_ctl_lock();
|
||||||
audit_ctl_unlock();
|
audit_ctl_unlock();
|
||||||
|
|
||||||
/* Ignore failure. It'll only happen if the sender goes away,
|
/* Ignore failure. It'll only happen if the sender goes away,
|
||||||
because our timeout is set to infinite. */
|
because our timeout is set to infinite. */
|
||||||
netlink_unicast(sk, reply->skb, reply->portid, 0);
|
netlink_unicast(audit_get_sk(reply->net), reply->skb, reply->portid, 0);
|
||||||
put_net(reply->net);
|
reply->skb = NULL;
|
||||||
kfree(reply);
|
audit_free_reply(reply);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,35 +961,32 @@ static int audit_send_reply_thread(void *arg)
|
||||||
* @payload: payload data
|
* @payload: payload data
|
||||||
* @size: payload size
|
* @size: payload size
|
||||||
*
|
*
|
||||||
* Allocates an skb, builds the netlink message, and sends it to the port id.
|
* Allocates a skb, builds the netlink message, and sends it to the port id.
|
||||||
* No failure notifications.
|
|
||||||
*/
|
*/
|
||||||
static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
|
static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
|
||||||
int multi, const void *payload, int size)
|
int multi, const void *payload, int size)
|
||||||
{
|
{
|
||||||
struct net *net = sock_net(NETLINK_CB(request_skb).sk);
|
|
||||||
struct sk_buff *skb;
|
|
||||||
struct task_struct *tsk;
|
struct task_struct *tsk;
|
||||||
struct audit_reply *reply = kmalloc(sizeof(struct audit_reply),
|
struct audit_reply *reply;
|
||||||
GFP_KERNEL);
|
|
||||||
|
|
||||||
|
reply = kzalloc(sizeof(*reply), GFP_KERNEL);
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
skb = audit_make_reply(seq, type, done, multi, payload, size);
|
reply->skb = audit_make_reply(seq, type, done, multi, payload, size);
|
||||||
if (!skb)
|
if (!reply->skb)
|
||||||
goto out;
|
goto err;
|
||||||
|
reply->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
|
||||||
reply->net = get_net(net);
|
|
||||||
reply->portid = NETLINK_CB(request_skb).portid;
|
reply->portid = NETLINK_CB(request_skb).portid;
|
||||||
reply->skb = skb;
|
|
||||||
|
|
||||||
tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
|
tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
|
||||||
if (!IS_ERR(tsk))
|
if (IS_ERR(tsk))
|
||||||
return;
|
goto err;
|
||||||
kfree_skb(skb);
|
|
||||||
out:
|
return;
|
||||||
kfree(reply);
|
|
||||||
|
err:
|
||||||
|
audit_free_reply(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1525,20 +1533,60 @@ static void audit_receive(struct sk_buff *skb)
|
||||||
audit_ctl_unlock();
|
audit_ctl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run custom bind function on netlink socket group connect or bind requests. */
|
/* Log information about who is connecting to the audit multicast socket */
|
||||||
static int audit_bind(struct net *net, int group)
|
static void audit_log_multicast(int group, const char *op, int err)
|
||||||
{
|
{
|
||||||
if (!capable(CAP_AUDIT_READ))
|
const struct cred *cred;
|
||||||
return -EPERM;
|
struct tty_struct *tty;
|
||||||
|
char comm[sizeof(current->comm)];
|
||||||
|
struct audit_buffer *ab;
|
||||||
|
|
||||||
return 0;
|
if (!audit_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_EVENT_LISTENER);
|
||||||
|
if (!ab)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cred = current_cred();
|
||||||
|
tty = audit_get_tty();
|
||||||
|
audit_log_format(ab, "pid=%u uid=%u auid=%u tty=%s ses=%u",
|
||||||
|
task_pid_nr(current),
|
||||||
|
from_kuid(&init_user_ns, cred->uid),
|
||||||
|
from_kuid(&init_user_ns, audit_get_loginuid(current)),
|
||||||
|
tty ? tty_name(tty) : "(none)",
|
||||||
|
audit_get_sessionid(current));
|
||||||
|
audit_put_tty(tty);
|
||||||
|
audit_log_task_context(ab); /* subj= */
|
||||||
|
audit_log_format(ab, " comm=");
|
||||||
|
audit_log_untrustedstring(ab, get_task_comm(comm, current));
|
||||||
|
audit_log_d_path_exe(ab, current->mm); /* exe= */
|
||||||
|
audit_log_format(ab, " nl-mcgrp=%d op=%s res=%d", group, op, !err);
|
||||||
|
audit_log_end(ab);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run custom bind function on netlink socket group connect or bind requests. */
|
||||||
|
static int audit_multicast_bind(struct net *net, int group)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!capable(CAP_AUDIT_READ))
|
||||||
|
err = -EPERM;
|
||||||
|
audit_log_multicast(group, "connect", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void audit_multicast_unbind(struct net *net, int group)
|
||||||
|
{
|
||||||
|
audit_log_multicast(group, "disconnect", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __net_init audit_net_init(struct net *net)
|
static int __net_init audit_net_init(struct net *net)
|
||||||
{
|
{
|
||||||
struct netlink_kernel_cfg cfg = {
|
struct netlink_kernel_cfg cfg = {
|
||||||
.input = audit_receive,
|
.input = audit_receive,
|
||||||
.bind = audit_bind,
|
.bind = audit_multicast_bind,
|
||||||
|
.unbind = audit_multicast_unbind,
|
||||||
.flags = NL_CFG_F_NONROOT_RECV,
|
.flags = NL_CFG_F_NONROOT_RECV,
|
||||||
.groups = AUDIT_NLGRP_MAX,
|
.groups = AUDIT_NLGRP_MAX,
|
||||||
};
|
};
|
||||||
|
|
|
@ -229,7 +229,7 @@ struct audit_netlink_list {
|
||||||
struct sk_buff_head q;
|
struct sk_buff_head q;
|
||||||
};
|
};
|
||||||
|
|
||||||
int audit_send_list(void *_dest);
|
int audit_send_list_thread(void *_dest);
|
||||||
|
|
||||||
extern int selinux_audit_rule_update(void);
|
extern int selinux_audit_rule_update(void);
|
||||||
|
|
||||||
|
|
|
@ -1161,11 +1161,8 @@ int audit_rule_change(int type, int seq, void *data, size_t datasz)
|
||||||
*/
|
*/
|
||||||
int audit_list_rules_send(struct sk_buff *request_skb, int seq)
|
int audit_list_rules_send(struct sk_buff *request_skb, int seq)
|
||||||
{
|
{
|
||||||
u32 portid = NETLINK_CB(request_skb).portid;
|
|
||||||
struct net *net = sock_net(NETLINK_CB(request_skb).sk);
|
|
||||||
struct task_struct *tsk;
|
struct task_struct *tsk;
|
||||||
struct audit_netlink_list *dest;
|
struct audit_netlink_list *dest;
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
/* We can't just spew out the rules here because we might fill
|
/* We can't just spew out the rules here because we might fill
|
||||||
* the available socket buffer space and deadlock waiting for
|
* the available socket buffer space and deadlock waiting for
|
||||||
|
@ -1173,25 +1170,26 @@ int audit_list_rules_send(struct sk_buff *request_skb, int seq)
|
||||||
* happen if we're actually running in the context of auditctl
|
* happen if we're actually running in the context of auditctl
|
||||||
* trying to _send_ the stuff */
|
* trying to _send_ the stuff */
|
||||||
|
|
||||||
dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
|
dest = kmalloc(sizeof(*dest), GFP_KERNEL);
|
||||||
if (!dest)
|
if (!dest)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
dest->net = get_net(net);
|
dest->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
|
||||||
dest->portid = portid;
|
dest->portid = NETLINK_CB(request_skb).portid;
|
||||||
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(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_thread, dest, "audit_send_list");
|
||||||
if (IS_ERR(tsk)) {
|
if (IS_ERR(tsk)) {
|
||||||
skb_queue_purge(&dest->q);
|
skb_queue_purge(&dest->q);
|
||||||
|
put_net(dest->net);
|
||||||
kfree(dest);
|
kfree(dest);
|
||||||
err = PTR_ERR(tsk);
|
return PTR_ERR(tsk);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int audit_comparator(u32 left, u32 op, u32 right)
|
int audit_comparator(u32 left, u32 op, u32 right)
|
||||||
|
|
|
@ -130,6 +130,17 @@ struct audit_tree_refs {
|
||||||
struct audit_chunk *c[31];
|
struct audit_chunk *c[31];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct audit_nfcfgop_tab {
|
||||||
|
enum audit_nfcfgop op;
|
||||||
|
const char *s;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct audit_nfcfgop_tab audit_nfcfgs[] = {
|
||||||
|
{ AUDIT_XT_OP_REGISTER, "register" },
|
||||||
|
{ AUDIT_XT_OP_REPLACE, "replace" },
|
||||||
|
{ AUDIT_XT_OP_UNREGISTER, "unregister" },
|
||||||
|
};
|
||||||
|
|
||||||
static int audit_match_perm(struct audit_context *ctx, int mask)
|
static int audit_match_perm(struct audit_context *ctx, int mask)
|
||||||
{
|
{
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
@ -2542,6 +2553,26 @@ void __audit_ntp_log(const struct audit_ntp_data *ad)
|
||||||
audit_log_ntp_val(ad, "adjust", AUDIT_NTP_ADJUST);
|
audit_log_ntp_val(ad, "adjust", AUDIT_NTP_ADJUST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
|
||||||
|
enum audit_nfcfgop op)
|
||||||
|
{
|
||||||
|
struct audit_buffer *ab;
|
||||||
|
char comm[sizeof(current->comm)];
|
||||||
|
|
||||||
|
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_NETFILTER_CFG);
|
||||||
|
if (!ab)
|
||||||
|
return;
|
||||||
|
audit_log_format(ab, "table=%s family=%u entries=%u op=%s",
|
||||||
|
name, af, nentries, audit_nfcfgs[op].s);
|
||||||
|
|
||||||
|
audit_log_format(ab, " pid=%u", task_pid_nr(current));
|
||||||
|
audit_log_task_context(ab); /* subj= */
|
||||||
|
audit_log_format(ab, " comm=");
|
||||||
|
audit_log_untrustedstring(ab, get_task_comm(comm, current));
|
||||||
|
audit_log_end(ab);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__audit_log_nfcfg);
|
||||||
|
|
||||||
static void audit_log_task(struct audit_buffer *ab)
|
static void audit_log_task(struct audit_buffer *ab)
|
||||||
{
|
{
|
||||||
kuid_t auid, uid;
|
kuid_t auid, uid;
|
||||||
|
|
|
@ -1046,14 +1046,8 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
|
||||||
vfree(table);
|
vfree(table);
|
||||||
vfree(counterstmp);
|
vfree(counterstmp);
|
||||||
|
|
||||||
#ifdef CONFIG_AUDIT
|
audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
|
||||||
if (audit_enabled) {
|
AUDIT_XT_OP_REPLACE);
|
||||||
audit_log(audit_context(), GFP_KERNEL,
|
|
||||||
AUDIT_NETFILTER_CFG,
|
|
||||||
"table=%s family=%u entries=%u",
|
|
||||||
repl->name, AF_BRIDGE, repl->nentries);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
free_unlock:
|
free_unlock:
|
||||||
|
@ -1128,6 +1122,8 @@ static void __ebt_unregister_table(struct net *net, struct ebt_table *table)
|
||||||
mutex_lock(&ebt_mutex);
|
mutex_lock(&ebt_mutex);
|
||||||
list_del(&table->list);
|
list_del(&table->list);
|
||||||
mutex_unlock(&ebt_mutex);
|
mutex_unlock(&ebt_mutex);
|
||||||
|
audit_log_nfcfg(table->name, AF_BRIDGE, table->private->nentries,
|
||||||
|
AUDIT_XT_OP_UNREGISTER);
|
||||||
EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
|
EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
|
||||||
ebt_cleanup_entry, net, NULL);
|
ebt_cleanup_entry, net, NULL);
|
||||||
if (table->private->nentries)
|
if (table->private->nentries)
|
||||||
|
@ -1221,6 +1217,8 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
|
||||||
*res = NULL;
|
*res = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
|
||||||
|
AUDIT_XT_OP_REGISTER);
|
||||||
return ret;
|
return ret;
|
||||||
free_unlock:
|
free_unlock:
|
||||||
mutex_unlock(&ebt_mutex);
|
mutex_unlock(&ebt_mutex);
|
||||||
|
|
|
@ -1408,15 +1408,9 @@ xt_replace_table(struct xt_table *table,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_AUDIT
|
audit_log_nfcfg(table->name, table->af, private->number,
|
||||||
if (audit_enabled) {
|
!private->number ? AUDIT_XT_OP_REGISTER :
|
||||||
audit_log(audit_context(), GFP_KERNEL,
|
AUDIT_XT_OP_REPLACE);
|
||||||
AUDIT_NETFILTER_CFG,
|
|
||||||
"table=%s family=%u entries=%u",
|
|
||||||
table->name, table->af, private->number);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return private;
|
return private;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xt_replace_table);
|
EXPORT_SYMBOL_GPL(xt_replace_table);
|
||||||
|
@ -1478,6 +1472,8 @@ void *xt_unregister_table(struct xt_table *table)
|
||||||
private = table->private;
|
private = table->private;
|
||||||
list_del(&table->list);
|
list_del(&table->list);
|
||||||
mutex_unlock(&xt[table->af].mutex);
|
mutex_unlock(&xt[table->af].mutex);
|
||||||
|
audit_log_nfcfg(table->name, table->af, private->number,
|
||||||
|
AUDIT_XT_OP_UNREGISTER);
|
||||||
kfree(table);
|
kfree(table);
|
||||||
|
|
||||||
return private;
|
return private;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче