]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/netfilter-nfnetlink_cttimeout-fetch-timeouts-for-udp.patch
618df287b6ca102819e2c1a39d8d143dfe4d70ba
[thirdparty/kernel/stable-queue.git] / queue-4.19 / netfilter-nfnetlink_cttimeout-fetch-timeouts-for-udp.patch
1 From 6255a964f4da99e383ff4382ebce2efae4d26b3b Mon Sep 17 00:00:00 2001
2 From: Florian Westphal <fw@strlen.de>
3 Date: Fri, 12 Apr 2019 10:55:03 -0700
4 Subject: netfilter: nfnetlink_cttimeout: fetch timeouts for udplite and gre,
5 too
6
7 commit 89259088c1b7fecb43e8e245dc931909132a4e03 upstream
8
9 syzbot was able to trigger the WARN in cttimeout_default_get() by
10 passing UDPLITE as l4protocol. Alias UDPLITE to UDP, both use
11 same timeout values.
12
13 Furthermore, also fetch GRE timeouts. GRE is a bit more complicated,
14 as it still can be a module and its netns_proto_gre struct layout isn't
15 visible outside of the gre module. Can't move timeouts around, it
16 appears conntrack sysctl unregister assumes net_generic() returns
17 nf_proto_net, so we get crash. Expose layout of netns_proto_gre instead.
18
19 A followup nf-next patch could make gre tracker be built-in as well
20 if needed, its not that large.
21
22 Last, make the WARN() mention the missing protocol value in case
23 anything else is missing.
24
25 Reported-by: syzbot+2fae8fa157dd92618cae@syzkaller.appspotmail.com
26 Fixes: 8866df9264a3 ("netfilter: nfnetlink_cttimeout: pass default timeout policy to obj_to_nlattr")
27 Signed-off-by: Florian Westphal <fw@strlen.de>
28 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
29 Signed-off-by: Zubin Mithra <zsm@chromium.org>
30 Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org>
31 ---
32 include/linux/netfilter/nf_conntrack_proto_gre.h | 13 +++++++++++++
33 net/netfilter/nf_conntrack_proto_gre.c | 14 ++------------
34 net/netfilter/nfnetlink_cttimeout.c | 15 +++++++++++++--
35 3 files changed, 28 insertions(+), 14 deletions(-)
36
37 diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h
38 index b8d95564bd53..14edb795ab43 100644
39 --- a/include/linux/netfilter/nf_conntrack_proto_gre.h
40 +++ b/include/linux/netfilter/nf_conntrack_proto_gre.h
41 @@ -21,6 +21,19 @@ struct nf_ct_gre_keymap {
42 struct nf_conntrack_tuple tuple;
43 };
44
45 +enum grep_conntrack {
46 + GRE_CT_UNREPLIED,
47 + GRE_CT_REPLIED,
48 + GRE_CT_MAX
49 +};
50 +
51 +struct netns_proto_gre {
52 + struct nf_proto_net nf;
53 + rwlock_t keymap_lock;
54 + struct list_head keymap_list;
55 + unsigned int gre_timeouts[GRE_CT_MAX];
56 +};
57 +
58 /* add new tuple->key_reply pair to keymap */
59 int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
60 struct nf_conntrack_tuple *t);
61 diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
62 index 650eb4fba2c5..841c472aae1c 100644
63 --- a/net/netfilter/nf_conntrack_proto_gre.c
64 +++ b/net/netfilter/nf_conntrack_proto_gre.c
65 @@ -43,24 +43,12 @@
66 #include <linux/netfilter/nf_conntrack_proto_gre.h>
67 #include <linux/netfilter/nf_conntrack_pptp.h>
68
69 -enum grep_conntrack {
70 - GRE_CT_UNREPLIED,
71 - GRE_CT_REPLIED,
72 - GRE_CT_MAX
73 -};
74 -
75 static const unsigned int gre_timeouts[GRE_CT_MAX] = {
76 [GRE_CT_UNREPLIED] = 30*HZ,
77 [GRE_CT_REPLIED] = 180*HZ,
78 };
79
80 static unsigned int proto_gre_net_id __read_mostly;
81 -struct netns_proto_gre {
82 - struct nf_proto_net nf;
83 - rwlock_t keymap_lock;
84 - struct list_head keymap_list;
85 - unsigned int gre_timeouts[GRE_CT_MAX];
86 -};
87
88 static inline struct netns_proto_gre *gre_pernet(struct net *net)
89 {
90 @@ -408,6 +396,8 @@ static int __init nf_ct_proto_gre_init(void)
91 {
92 int ret;
93
94 + BUILD_BUG_ON(offsetof(struct netns_proto_gre, nf) != 0);
95 +
96 ret = register_pernet_subsys(&proto_gre_net_ops);
97 if (ret < 0)
98 goto out_pernet;
99 diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
100 index 1dc4ea327cbe..70a7382b9787 100644
101 --- a/net/netfilter/nfnetlink_cttimeout.c
102 +++ b/net/netfilter/nfnetlink_cttimeout.c
103 @@ -469,7 +469,8 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
104 case IPPROTO_TCP:
105 timeouts = net->ct.nf_ct_proto.tcp.timeouts;
106 break;
107 - case IPPROTO_UDP:
108 + case IPPROTO_UDP: /* fallthrough */
109 + case IPPROTO_UDPLITE:
110 timeouts = net->ct.nf_ct_proto.udp.timeouts;
111 break;
112 case IPPROTO_DCCP:
113 @@ -483,13 +484,23 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
114 case IPPROTO_SCTP:
115 #ifdef CONFIG_NF_CT_PROTO_SCTP
116 timeouts = net->ct.nf_ct_proto.sctp.timeouts;
117 +#endif
118 + break;
119 + case IPPROTO_GRE:
120 +#ifdef CONFIG_NF_CT_PROTO_GRE
121 + if (l4proto->net_id) {
122 + struct netns_proto_gre *net_gre;
123 +
124 + net_gre = net_generic(net, *l4proto->net_id);
125 + timeouts = net_gre->gre_timeouts;
126 + }
127 #endif
128 break;
129 case 255:
130 timeouts = &net->ct.nf_ct_proto.generic.timeout;
131 break;
132 default:
133 - WARN_ON_ONCE(1);
134 + WARN_ONCE(1, "Missing timeouts for proto %d", l4proto->l4proto);
135 break;
136 }
137
138 --
139 2.19.1
140