]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.173/l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.173 / l2tp-remove-l2specific_len-dependency-in-l2tp_core.patch
1 From 62e7b6a57c7b9bf3c6fd99418eeec05b08a85c38 Mon Sep 17 00:00:00 2001
2 From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
3 Date: Tue, 16 Jan 2018 23:01:55 +0100
4 Subject: l2tp: remove l2specific_len dependency in l2tp_core
5
6 From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
7
8 commit 62e7b6a57c7b9bf3c6fd99418eeec05b08a85c38 upstream.
9
10 Remove l2specific_len dependency while building l2tpv3 header or
11 parsing the received frame since default L2-Specific Sublayer is
12 always four bytes long and we don't need to rely on a user supplied
13 value.
14 Moreover in l2tp netlink code there are no sanity checks to
15 enforce the relation between l2specific_len and l2specific_type,
16 so sending a malformed netlink message is possible to set
17 l2specific_type to L2TP_L2SPECTYPE_DEFAULT (or even
18 L2TP_L2SPECTYPE_NONE) and set l2specific_len to a value greater than
19 4 leaking memory on the wire and sending corrupted frames.
20
21 Reviewed-by: Guillaume Nault <g.nault@alphalink.fr>
22 Tested-by: Guillaume Nault <g.nault@alphalink.fr>
23 Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
24 Signed-off-by: David S. Miller <davem@davemloft.net>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26
27 ---
28 net/l2tp/l2tp_core.c | 34 ++++++++++++++++------------------
29 net/l2tp/l2tp_core.h | 11 +++++++++++
30 2 files changed, 27 insertions(+), 18 deletions(-)
31
32 --- a/net/l2tp/l2tp_core.c
33 +++ b/net/l2tp/l2tp_core.c
34 @@ -704,11 +704,9 @@ void l2tp_recv_common(struct l2tp_sessio
35 "%s: recv data ns=%u, session nr=%u\n",
36 session->name, ns, session->nr);
37 }
38 + ptr += 4;
39 }
40
41 - /* Advance past L2-specific header, if present */
42 - ptr += session->l2specific_len;
43 -
44 if (L2TP_SKB_CB(skb)->has_seq) {
45 /* Received a packet with sequence numbers. If we're the LNS,
46 * check if we sre sending sequence numbers and if not,
47 @@ -1030,21 +1028,20 @@ static int l2tp_build_l2tpv3_header(stru
48 memcpy(bufp, &session->cookie[0], session->cookie_len);
49 bufp += session->cookie_len;
50 }
51 - if (session->l2specific_len) {
52 - if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
53 - u32 l2h = 0;
54 - if (session->send_seq) {
55 - l2h = 0x40000000 | session->ns;
56 - session->ns++;
57 - session->ns &= 0xffffff;
58 - l2tp_dbg(session, L2TP_MSG_SEQ,
59 - "%s: updated ns to %u\n",
60 - session->name, session->ns);
61 - }
62 + if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
63 + u32 l2h = 0;
64
65 - *((__be32 *) bufp) = htonl(l2h);
66 + if (session->send_seq) {
67 + l2h = 0x40000000 | session->ns;
68 + session->ns++;
69 + session->ns &= 0xffffff;
70 + l2tp_dbg(session, L2TP_MSG_SEQ,
71 + "%s: updated ns to %u\n",
72 + session->name, session->ns);
73 }
74 - bufp += session->l2specific_len;
75 +
76 + *((__be32 *)bufp) = htonl(l2h);
77 + bufp += 4;
78 }
79 if (session->offset)
80 bufp += session->offset;
81 @@ -1723,7 +1720,7 @@ int l2tp_session_delete(struct l2tp_sess
82 EXPORT_SYMBOL_GPL(l2tp_session_delete);
83
84 /* We come here whenever a session's send_seq, cookie_len or
85 - * l2specific_len parameters are set.
86 + * l2specific_type parameters are set.
87 */
88 void l2tp_session_set_header_len(struct l2tp_session *session, int version)
89 {
90 @@ -1732,7 +1729,8 @@ void l2tp_session_set_header_len(struct
91 if (session->send_seq)
92 session->hdr_len += 4;
93 } else {
94 - session->hdr_len = 4 + session->cookie_len + session->l2specific_len + session->offset;
95 + session->hdr_len = 4 + session->cookie_len + session->offset;
96 + session->hdr_len += l2tp_get_l2specific_len(session);
97 if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP)
98 session->hdr_len += 4;
99 }
100 --- a/net/l2tp/l2tp_core.h
101 +++ b/net/l2tp/l2tp_core.h
102 @@ -313,6 +313,17 @@ do { \
103 #define l2tp_session_dec_refcount(s) l2tp_session_dec_refcount_1(s)
104 #endif
105
106 +static inline int l2tp_get_l2specific_len(struct l2tp_session *session)
107 +{
108 + switch (session->l2specific_type) {
109 + case L2TP_L2SPECTYPE_DEFAULT:
110 + return 4;
111 + case L2TP_L2SPECTYPE_NONE:
112 + default:
113 + return 0;
114 + }
115 +}
116 +
117 #define l2tp_printk(ptr, type, func, fmt, ...) \
118 do { \
119 if (((ptr)->debug) & (type)) \