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
6 From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
8 commit 62e7b6a57c7b9bf3c6fd99418eeec05b08a85c38 upstream.
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
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.
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>
28 net/l2tp/l2tp_core.c | 34 ++++++++++++++++------------------
29 net/l2tp/l2tp_core.h | 11 +++++++++++
30 2 files changed, 27 insertions(+), 18 deletions(-)
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);
41 - /* Advance past L2-specific header, if present */
42 - ptr += session->l2specific_len;
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;
51 - if (session->l2specific_len) {
52 - if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
54 - if (session->send_seq) {
55 - l2h = 0x40000000 | 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);
62 + if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) {
65 - *((__be32 *) bufp) = htonl(l2h);
66 + if (session->send_seq) {
67 + l2h = 0x40000000 | 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);
74 - bufp += session->l2specific_len;
76 + *((__be32 *)bufp) = htonl(l2h);
80 bufp += session->offset;
81 @@ -1723,7 +1720,7 @@ int l2tp_session_delete(struct l2tp_sess
82 EXPORT_SYMBOL_GPL(l2tp_session_delete);
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.
88 void l2tp_session_set_header_len(struct l2tp_session *session, int version)
90 @@ -1732,7 +1729,8 @@ void l2tp_session_set_header_len(struct
91 if (session->send_seq)
92 session->hdr_len += 4;
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;
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)
106 +static inline int l2tp_get_l2specific_len(struct l2tp_session *session)
108 + switch (session->l2specific_type) {
109 + case L2TP_L2SPECTYPE_DEFAULT:
111 + case L2TP_L2SPECTYPE_NONE:
117 #define l2tp_printk(ptr, type, func, fmt, ...) \
119 if (((ptr)->debug) & (type)) \