Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8cdb46da authored by Hans Schillstrom's avatar Hans Schillstrom Committed by Pablo Neira Ayuso
Browse files

netfilter: log: netns NULL ptr bug when calling from conntrack

Since (69b34fb9 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: default avatarRonald <ronald645@gmail.com>
Signed-off-by: default avatarHans Schillstrom <hans@schillstrom.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 42010ed0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -30,7 +30,8 @@ struct nf_loginfo {
	} u;
};

typedef void nf_logfn(u_int8_t pf,
typedef void nf_logfn(struct net *net,
		      u_int8_t pf,
		      unsigned int hooknum,
		      const struct sk_buff *skb,
		      const struct net_device *in,
+2 −1
Original line number Diff line number Diff line
@@ -2,7 +2,8 @@
#define _KER_NFNETLINK_LOG_H

void
nfulnl_log_packet(u_int8_t pf,
nfulnl_log_packet(struct net *net,
		  u_int8_t pf,
		  unsigned int hooknum,
		  const struct sk_buff *skb,
		  const struct net_device *in,
+5 −6
Original line number Diff line number Diff line
@@ -72,13 +72,12 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
}

static void
ebt_log_packet(u_int8_t pf, unsigned int hooknum,
ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
	       const struct sk_buff *skb, const struct net_device *in,
	       const struct net_device *out, const struct nf_loginfo *loginfo,
	       const char *prefix)
{
	unsigned int bitmask;
	struct net *net = dev_net(in ? in : out);

	/* FIXME: Disabled from containers until syslog ns is supported */
	if (!net_eq(net, &init_net))
@@ -191,7 +190,7 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
		nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb,
			      par->in, par->out, &li, "%s", info->prefix);
	else
		ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
		ebt_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in,
			       par->out, &li, info->prefix);
	return EBT_CONTINUE;
}
+11 −7
Original line number Diff line number Diff line
@@ -131,14 +131,16 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
	return skb;
}

static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
   const struct net_device *in, const struct net_device *out,
   const struct ebt_ulog_info *uloginfo, const char *prefix)
static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
			    const struct sk_buff *skb,
			    const struct net_device *in,
			    const struct net_device *out,
			    const struct ebt_ulog_info *uloginfo,
			    const char *prefix)
{
	ebt_ulog_packet_msg_t *pm;
	size_t size, copy_len;
	struct nlmsghdr *nlh;
	struct net *net = dev_net(in ? in : out);
	struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
	unsigned int group = uloginfo->nlgroup;
	ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group];
@@ -233,7 +235,7 @@ unlock:
}

/* this function is registered with the netfilter core */
static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
   const struct sk_buff *skb, const struct net_device *in,
   const struct net_device *out, const struct nf_loginfo *li,
   const char *prefix)
@@ -252,13 +254,15 @@ static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
		strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
	}

	ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
	ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
}

static unsigned int
ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
	ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
	struct net *net = dev_net(par->in ? par->in : par->out);

	ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
	                par->targinfo, NULL);
	return EBT_CONTINUE;
}
+8 −5
Original line number Diff line number Diff line
@@ -162,7 +162,8 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
	return skb;
}

static void ipt_ulog_packet(unsigned int hooknum,
static void ipt_ulog_packet(struct net *net,
			    unsigned int hooknum,
			    const struct sk_buff *skb,
			    const struct net_device *in,
			    const struct net_device *out,
@@ -174,7 +175,6 @@ static void ipt_ulog_packet(unsigned int hooknum,
	size_t size, copy_len;
	struct nlmsghdr *nlh;
	struct timeval tv;
	struct net *net = dev_net(in ? in : out);
	struct ulog_net *ulog = ulog_pernet(net);

	/* ffs == find first bit set, necessary because userspace
@@ -291,12 +291,15 @@ alloc_failure:
static unsigned int
ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
	ipt_ulog_packet(par->hooknum, skb, par->in, par->out,
	struct net *net = dev_net(par->in ? par->in : par->out);

	ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
	                par->targinfo, NULL);
	return XT_CONTINUE;
}

static void ipt_logfn(u_int8_t pf,
static void ipt_logfn(struct net *net,
		      u_int8_t pf,
		      unsigned int hooknum,
		      const struct sk_buff *skb,
		      const struct net_device *in,
@@ -318,7 +321,7 @@ static void ipt_logfn(u_int8_t pf,
		strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
	}

	ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
	ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
}

static int ulog_tg_check(const struct xt_tgchk_param *par)
Loading