diff options
author | Hans Schillstrom <hans@schillstrom.com> | 2013-05-14 21:23:45 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-05-15 08:11:07 -0400 |
commit | 8cdb46da06ea94543a3b2e53e3e92736421d1093 (patch) | |
tree | 2f3d5703ee736daf10a3556c5c80f6bcca8731b8 /net | |
parent | 42010ed0c669aeb1c5b015f5edf590c73919380c (diff) |
netfilter: log: netns NULL ptr bug when calling from conntrack
Since (69b34fb netfilter: xt_LOG: add net namespace support
for xt_LOG), we hit this:
[ 4224.708977] BUG: unable to handle kernel NULL pointer dereference at 0000000000000388
[ 4224.709074] IP: [<ffffffff8147f699>] ipt_log_packet+0x29/0x270
when callling log functions from conntrack both in and out
are NULL i.e. the net pointer is invalid.
Adding struct net *net in call to nf_logfn() will secure that
there always is a vaild net ptr.
Reported as netfilter's bugzilla bug 818:
https://bugzilla.netfilter.org/show_bug.cgi?id=818
Reported-by: Ronald <ronald645@gmail.com>
Signed-off-by: Hans Schillstrom <hans@schillstrom.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/netfilter/ebt_log.c | 11 | ||||
-rw-r--r-- | net/bridge/netfilter/ebt_ulog.c | 18 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 13 | ||||
-rw-r--r-- | net/netfilter/nf_log.c | 2 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 4 | ||||
-rw-r--r-- | net/netfilter/xt_LOG.c | 13 | ||||
-rw-r--r-- | net/netfilter/xt_NFLOG.c | 3 |
7 files changed, 36 insertions, 28 deletions
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 9878eb8204c5..19c37a4929bc 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -72,13 +72,12 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | static void | 74 | static void |
75 | ebt_log_packet(u_int8_t pf, unsigned int hooknum, | 75 | ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum, |
76 | const struct sk_buff *skb, const struct net_device *in, | 76 | const struct sk_buff *skb, const struct net_device *in, |
77 | const struct net_device *out, const struct nf_loginfo *loginfo, | 77 | const struct net_device *out, const struct nf_loginfo *loginfo, |
78 | const char *prefix) | 78 | const char *prefix) |
79 | { | 79 | { |
80 | unsigned int bitmask; | 80 | unsigned int bitmask; |
81 | struct net *net = dev_net(in ? in : out); | ||
82 | 81 | ||
83 | /* FIXME: Disabled from containers until syslog ns is supported */ | 82 | /* FIXME: Disabled from containers until syslog ns is supported */ |
84 | if (!net_eq(net, &init_net)) | 83 | if (!net_eq(net, &init_net)) |
@@ -191,7 +190,7 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
191 | nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, | 190 | nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, |
192 | par->in, par->out, &li, "%s", info->prefix); | 191 | par->in, par->out, &li, "%s", info->prefix); |
193 | else | 192 | else |
194 | ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in, | 193 | ebt_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in, |
195 | par->out, &li, info->prefix); | 194 | par->out, &li, info->prefix); |
196 | return EBT_CONTINUE; | 195 | return EBT_CONTINUE; |
197 | } | 196 | } |
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index fc1905c51417..df0364aa12d5 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
@@ -131,14 +131,16 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) | |||
131 | return skb; | 131 | return skb; |
132 | } | 132 | } |
133 | 133 | ||
134 | static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, | 134 | static void ebt_ulog_packet(struct net *net, unsigned int hooknr, |
135 | const struct net_device *in, const struct net_device *out, | 135 | const struct sk_buff *skb, |
136 | const struct ebt_ulog_info *uloginfo, const char *prefix) | 136 | const struct net_device *in, |
137 | const struct net_device *out, | ||
138 | const struct ebt_ulog_info *uloginfo, | ||
139 | const char *prefix) | ||
137 | { | 140 | { |
138 | ebt_ulog_packet_msg_t *pm; | 141 | ebt_ulog_packet_msg_t *pm; |
139 | size_t size, copy_len; | 142 | size_t size, copy_len; |
140 | struct nlmsghdr *nlh; | 143 | struct nlmsghdr *nlh; |
141 | struct net *net = dev_net(in ? in : out); | ||
142 | struct ebt_ulog_net *ebt = ebt_ulog_pernet(net); | 144 | struct ebt_ulog_net *ebt = ebt_ulog_pernet(net); |
143 | unsigned int group = uloginfo->nlgroup; | 145 | unsigned int group = uloginfo->nlgroup; |
144 | ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group]; | 146 | ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group]; |
@@ -233,7 +235,7 @@ unlock: | |||
233 | } | 235 | } |
234 | 236 | ||
235 | /* this function is registered with the netfilter core */ | 237 | /* this function is registered with the netfilter core */ |
236 | static void ebt_log_packet(u_int8_t pf, unsigned int hooknum, | 238 | static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum, |
237 | const struct sk_buff *skb, const struct net_device *in, | 239 | const struct sk_buff *skb, const struct net_device *in, |
238 | const struct net_device *out, const struct nf_loginfo *li, | 240 | const struct net_device *out, const struct nf_loginfo *li, |
239 | const char *prefix) | 241 | const char *prefix) |
@@ -252,13 +254,15 @@ static void ebt_log_packet(u_int8_t pf, unsigned int hooknum, | |||
252 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); | 254 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); |
253 | } | 255 | } |
254 | 256 | ||
255 | ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 257 | ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix); |
256 | } | 258 | } |
257 | 259 | ||
258 | static unsigned int | 260 | static unsigned int |
259 | ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) | 261 | ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) |
260 | { | 262 | { |
261 | ebt_ulog_packet(par->hooknum, skb, par->in, par->out, | 263 | struct net *net = dev_net(par->in ? par->in : par->out); |
264 | |||
265 | ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out, | ||
262 | par->targinfo, NULL); | 266 | par->targinfo, NULL); |
263 | return EBT_CONTINUE; | 267 | return EBT_CONTINUE; |
264 | } | 268 | } |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index f8a222cb6448..cf08218ddbcf 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -162,7 +162,8 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) | |||
162 | return skb; | 162 | return skb; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void ipt_ulog_packet(unsigned int hooknum, | 165 | static void ipt_ulog_packet(struct net *net, |
166 | unsigned int hooknum, | ||
166 | const struct sk_buff *skb, | 167 | const struct sk_buff *skb, |
167 | const struct net_device *in, | 168 | const struct net_device *in, |
168 | const struct net_device *out, | 169 | const struct net_device *out, |
@@ -174,7 +175,6 @@ static void ipt_ulog_packet(unsigned int hooknum, | |||
174 | size_t size, copy_len; | 175 | size_t size, copy_len; |
175 | struct nlmsghdr *nlh; | 176 | struct nlmsghdr *nlh; |
176 | struct timeval tv; | 177 | struct timeval tv; |
177 | struct net *net = dev_net(in ? in : out); | ||
178 | struct ulog_net *ulog = ulog_pernet(net); | 178 | struct ulog_net *ulog = ulog_pernet(net); |
179 | 179 | ||
180 | /* ffs == find first bit set, necessary because userspace | 180 | /* ffs == find first bit set, necessary because userspace |
@@ -291,12 +291,15 @@ alloc_failure: | |||
291 | static unsigned int | 291 | static unsigned int |
292 | ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) | 292 | ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) |
293 | { | 293 | { |
294 | ipt_ulog_packet(par->hooknum, skb, par->in, par->out, | 294 | struct net *net = dev_net(par->in ? par->in : par->out); |
295 | |||
296 | ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out, | ||
295 | par->targinfo, NULL); | 297 | par->targinfo, NULL); |
296 | return XT_CONTINUE; | 298 | return XT_CONTINUE; |
297 | } | 299 | } |
298 | 300 | ||
299 | static void ipt_logfn(u_int8_t pf, | 301 | static void ipt_logfn(struct net *net, |
302 | u_int8_t pf, | ||
300 | unsigned int hooknum, | 303 | unsigned int hooknum, |
301 | const struct sk_buff *skb, | 304 | const struct sk_buff *skb, |
302 | const struct net_device *in, | 305 | const struct net_device *in, |
@@ -318,7 +321,7 @@ static void ipt_logfn(u_int8_t pf, | |||
318 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); | 321 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); |
319 | } | 322 | } |
320 | 323 | ||
321 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 324 | ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix); |
322 | } | 325 | } |
323 | 326 | ||
324 | static int ulog_tg_check(const struct xt_tgchk_param *par) | 327 | static int ulog_tg_check(const struct xt_tgchk_param *par) |
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index 757951d251e3..3b18dd1be7d9 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c | |||
@@ -148,7 +148,7 @@ void nf_log_packet(struct net *net, | |||
148 | va_start(args, fmt); | 148 | va_start(args, fmt); |
149 | vsnprintf(prefix, sizeof(prefix), fmt, args); | 149 | vsnprintf(prefix, sizeof(prefix), fmt, args); |
150 | va_end(args); | 150 | va_end(args); |
151 | logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix); | 151 | logger->logfn(net, pf, hooknum, skb, in, out, loginfo, prefix); |
152 | } | 152 | } |
153 | rcu_read_unlock(); | 153 | rcu_read_unlock(); |
154 | } | 154 | } |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index d83d881002a6..962e9792e317 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -602,7 +602,8 @@ static struct nf_loginfo default_loginfo = { | |||
602 | 602 | ||
603 | /* log handler for internal netfilter logging api */ | 603 | /* log handler for internal netfilter logging api */ |
604 | void | 604 | void |
605 | nfulnl_log_packet(u_int8_t pf, | 605 | nfulnl_log_packet(struct net *net, |
606 | u_int8_t pf, | ||
606 | unsigned int hooknum, | 607 | unsigned int hooknum, |
607 | const struct sk_buff *skb, | 608 | const struct sk_buff *skb, |
608 | const struct net_device *in, | 609 | const struct net_device *in, |
@@ -615,7 +616,6 @@ nfulnl_log_packet(u_int8_t pf, | |||
615 | const struct nf_loginfo *li; | 616 | const struct nf_loginfo *li; |
616 | unsigned int qthreshold; | 617 | unsigned int qthreshold; |
617 | unsigned int plen; | 618 | unsigned int plen; |
618 | struct net *net = dev_net(in ? in : out); | ||
619 | struct nfnl_log_net *log = nfnl_log_pernet(net); | 619 | struct nfnl_log_net *log = nfnl_log_pernet(net); |
620 | 620 | ||
621 | if (li_user && li_user->type == NF_LOG_TYPE_ULOG) | 621 | if (li_user && li_user->type == NF_LOG_TYPE_ULOG) |
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c index fe573f6c9e91..491c7d821a0b 100644 --- a/net/netfilter/xt_LOG.c +++ b/net/netfilter/xt_LOG.c | |||
@@ -466,7 +466,8 @@ log_packet_common(struct sbuff *m, | |||
466 | 466 | ||
467 | 467 | ||
468 | static void | 468 | static void |
469 | ipt_log_packet(u_int8_t pf, | 469 | ipt_log_packet(struct net *net, |
470 | u_int8_t pf, | ||
470 | unsigned int hooknum, | 471 | unsigned int hooknum, |
471 | const struct sk_buff *skb, | 472 | const struct sk_buff *skb, |
472 | const struct net_device *in, | 473 | const struct net_device *in, |
@@ -475,7 +476,6 @@ ipt_log_packet(u_int8_t pf, | |||
475 | const char *prefix) | 476 | const char *prefix) |
476 | { | 477 | { |
477 | struct sbuff *m; | 478 | struct sbuff *m; |
478 | struct net *net = dev_net(in ? in : out); | ||
479 | 479 | ||
480 | /* FIXME: Disabled from containers until syslog ns is supported */ | 480 | /* FIXME: Disabled from containers until syslog ns is supported */ |
481 | if (!net_eq(net, &init_net)) | 481 | if (!net_eq(net, &init_net)) |
@@ -797,7 +797,8 @@ fallback: | |||
797 | } | 797 | } |
798 | 798 | ||
799 | static void | 799 | static void |
800 | ip6t_log_packet(u_int8_t pf, | 800 | ip6t_log_packet(struct net *net, |
801 | u_int8_t pf, | ||
801 | unsigned int hooknum, | 802 | unsigned int hooknum, |
802 | const struct sk_buff *skb, | 803 | const struct sk_buff *skb, |
803 | const struct net_device *in, | 804 | const struct net_device *in, |
@@ -806,7 +807,6 @@ ip6t_log_packet(u_int8_t pf, | |||
806 | const char *prefix) | 807 | const char *prefix) |
807 | { | 808 | { |
808 | struct sbuff *m; | 809 | struct sbuff *m; |
809 | struct net *net = dev_net(in ? in : out); | ||
810 | 810 | ||
811 | /* FIXME: Disabled from containers until syslog ns is supported */ | 811 | /* FIXME: Disabled from containers until syslog ns is supported */ |
812 | if (!net_eq(net, &init_net)) | 812 | if (!net_eq(net, &init_net)) |
@@ -833,17 +833,18 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
833 | { | 833 | { |
834 | const struct xt_log_info *loginfo = par->targinfo; | 834 | const struct xt_log_info *loginfo = par->targinfo; |
835 | struct nf_loginfo li; | 835 | struct nf_loginfo li; |
836 | struct net *net = dev_net(par->in ? par->in : par->out); | ||
836 | 837 | ||
837 | li.type = NF_LOG_TYPE_LOG; | 838 | li.type = NF_LOG_TYPE_LOG; |
838 | li.u.log.level = loginfo->level; | 839 | li.u.log.level = loginfo->level; |
839 | li.u.log.logflags = loginfo->logflags; | 840 | li.u.log.logflags = loginfo->logflags; |
840 | 841 | ||
841 | if (par->family == NFPROTO_IPV4) | 842 | if (par->family == NFPROTO_IPV4) |
842 | ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, | 843 | ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in, |
843 | par->out, &li, loginfo->prefix); | 844 | par->out, &li, loginfo->prefix); |
844 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) | 845 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
845 | else if (par->family == NFPROTO_IPV6) | 846 | else if (par->family == NFPROTO_IPV6) |
846 | ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, | 847 | ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in, |
847 | par->out, &li, loginfo->prefix); | 848 | par->out, &li, loginfo->prefix); |
848 | #endif | 849 | #endif |
849 | else | 850 | else |
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c index a17dd0f589b2..fb7497c928a0 100644 --- a/net/netfilter/xt_NFLOG.c +++ b/net/netfilter/xt_NFLOG.c | |||
@@ -26,13 +26,14 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
26 | { | 26 | { |
27 | const struct xt_nflog_info *info = par->targinfo; | 27 | const struct xt_nflog_info *info = par->targinfo; |
28 | struct nf_loginfo li; | 28 | struct nf_loginfo li; |
29 | struct net *net = dev_net(par->in ? par->in : par->out); | ||
29 | 30 | ||
30 | li.type = NF_LOG_TYPE_ULOG; | 31 | li.type = NF_LOG_TYPE_ULOG; |
31 | li.u.ulog.copy_len = info->len; | 32 | li.u.ulog.copy_len = info->len; |
32 | li.u.ulog.group = info->group; | 33 | li.u.ulog.group = info->group; |
33 | li.u.ulog.qthreshold = info->threshold; | 34 | li.u.ulog.qthreshold = info->threshold; |
34 | 35 | ||
35 | nfulnl_log_packet(par->family, par->hooknum, skb, par->in, | 36 | nfulnl_log_packet(net, par->family, par->hooknum, skb, par->in, |
36 | par->out, &li, info->prefix); | 37 | par->out, &li, info->prefix); |
37 | return XT_CONTINUE; | 38 | return XT_CONTINUE; |
38 | } | 39 | } |