Commit c2d27b33 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by Greg Kroah-Hartman

netfilter: nfnetlink_cttimeout: pass default timeout policy to obj_to_nlattr

commit 8866df92 upstream

Otherwise, we hit a NULL pointer deference since handlers always assume
default timeout policy is passed.

  netlink: 24 bytes leftover after parsing attributes in process `syz-executor2'.
  kasan: CONFIG_KASAN_INLINE enabled
  kasan: GPF could be caused by NULL-ptr deref or user memory access
  general protection fault: 0000 [#1] PREEMPT SMP KASAN
  CPU: 0 PID: 9575 Comm: syz-executor1 Not tainted 4.19.0+ #312
  Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
  RIP: 0010:icmp_timeout_obj_to_nlattr+0x77/0x170 net/netfilter/nf_conntrack_proto_icmp.c:297

Fixes: c779e849 ("netfilter: conntrack: remove get_timeout() indirection")
Reported-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarZubin Mithra <zsm@chromium.org>
Signed-off-by: default avatarSasha Levin (Microsoft) <sashal@kernel.org>
parent 564f0391
......@@ -392,7 +392,8 @@ static int cttimeout_default_set(struct net *net, struct sock *ctnl,
static int
cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
u32 seq, u32 type, int event,
const struct nf_conntrack_l4proto *l4proto)
const struct nf_conntrack_l4proto *l4proto,
const unsigned int *timeouts)
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg;
......@@ -421,7 +422,7 @@ cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
if (!nest_parms)
goto nla_put_failure;
ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, NULL);
ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
if (ret < 0)
goto nla_put_failure;
......@@ -444,6 +445,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
struct netlink_ext_ack *extack)
{
const struct nf_conntrack_l4proto *l4proto;
unsigned int *timeouts = NULL;
struct sk_buff *skb2;
int ret, err;
__u16 l3num;
......@@ -456,12 +458,44 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
l4proto = nf_ct_l4proto_find_get(l3num, l4num);
/* This protocol is not supported, skip. */
if (l4proto->l4proto != l4num) {
err = -EOPNOTSUPP;
if (l4proto->l4proto != l4num)
goto err;
switch (l4proto->l4proto) {
case IPPROTO_ICMP:
timeouts = &net->ct.nf_ct_proto.icmp.timeout;
break;
case IPPROTO_TCP:
timeouts = net->ct.nf_ct_proto.tcp.timeouts;
break;
case IPPROTO_UDP:
timeouts = net->ct.nf_ct_proto.udp.timeouts;
break;
case IPPROTO_DCCP:
#ifdef CONFIG_NF_CT_PROTO_DCCP
timeouts = net->ct.nf_ct_proto.dccp.dccp_timeout;
#endif
break;
case IPPROTO_ICMPV6:
timeouts = &net->ct.nf_ct_proto.icmpv6.timeout;
break;
case IPPROTO_SCTP:
#ifdef CONFIG_NF_CT_PROTO_SCTP
timeouts = net->ct.nf_ct_proto.sctp.timeouts;
#endif
break;
case 255:
timeouts = &net->ct.nf_ct_proto.generic.timeout;
break;
default:
WARN_ON_ONCE(1);
break;
}
if (!timeouts)
goto err;
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (skb2 == NULL) {
err = -ENOMEM;
......@@ -472,7 +506,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
nlh->nlmsg_seq,
NFNL_MSG_TYPE(nlh->nlmsg_type),
IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
l4proto);
l4proto, timeouts);
if (ret <= 0) {
kfree_skb(skb2);
err = -ENOMEM;
......
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