]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.18.114/af_key-always-verify-length-of-provided-sadb_key.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.18.114 / af_key-always-verify-length-of-provided-sadb_key.patch
1 From 4b66af2d6356a00e94bcdea3e7fea324e8b5c6f4 Mon Sep 17 00:00:00 2001
2 From: Kevin Easton <kevin@guarana.org>
3 Date: Sat, 7 Apr 2018 11:40:33 -0400
4 Subject: af_key: Always verify length of provided sadb_key
5
6 From: Kevin Easton <kevin@guarana.org>
7
8 commit 4b66af2d6356a00e94bcdea3e7fea324e8b5c6f4 upstream.
9
10 Key extensions (struct sadb_key) include a user-specified number of key
11 bits. The kernel uses that number to determine how much key data to copy
12 out of the message in pfkey_msg2xfrm_state().
13
14 The length of the sadb_key message must be verified to be long enough,
15 even in the case of SADB_X_AALG_NULL. Furthermore, the sadb_key_len value
16 must be long enough to include both the key data and the struct sadb_key
17 itself.
18
19 Introduce a helper function verify_key_len(), and call it from
20 parse_exthdrs() where other exthdr types are similarly checked for
21 correctness.
22
23 Signed-off-by: Kevin Easton <kevin@guarana.org>
24 Reported-by: syzbot+5022a34ca5a3d49b84223653fab632dfb7b4cf37@syzkaller.appspotmail.com
25 Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
26 Cc: Zubin Mithra <zsm@chromium.org>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29 ---
30 net/key/af_key.c | 45 +++++++++++++++++++++++++++++++++++----------
31 1 file changed, 35 insertions(+), 10 deletions(-)
32
33 --- a/net/key/af_key.c
34 +++ b/net/key/af_key.c
35 @@ -437,6 +437,24 @@ static int verify_address_len(const void
36 return 0;
37 }
38
39 +static inline int sadb_key_len(const struct sadb_key *key)
40 +{
41 + int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8);
42 +
43 + return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes,
44 + sizeof(uint64_t));
45 +}
46 +
47 +static int verify_key_len(const void *p)
48 +{
49 + const struct sadb_key *key = p;
50 +
51 + if (sadb_key_len(key) > key->sadb_key_len)
52 + return -EINVAL;
53 +
54 + return 0;
55 +}
56 +
57 static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx)
58 {
59 return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) +
60 @@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff
61 return -EINVAL;
62 if (ext_hdrs[ext_type-1] != NULL)
63 return -EINVAL;
64 - if (ext_type == SADB_EXT_ADDRESS_SRC ||
65 - ext_type == SADB_EXT_ADDRESS_DST ||
66 - ext_type == SADB_EXT_ADDRESS_PROXY ||
67 - ext_type == SADB_X_EXT_NAT_T_OA) {
68 + switch (ext_type) {
69 + case SADB_EXT_ADDRESS_SRC:
70 + case SADB_EXT_ADDRESS_DST:
71 + case SADB_EXT_ADDRESS_PROXY:
72 + case SADB_X_EXT_NAT_T_OA:
73 if (verify_address_len(p))
74 return -EINVAL;
75 - }
76 - if (ext_type == SADB_X_EXT_SEC_CTX) {
77 + break;
78 + case SADB_X_EXT_SEC_CTX:
79 if (verify_sec_ctx_len(p))
80 return -EINVAL;
81 + break;
82 + case SADB_EXT_KEY_AUTH:
83 + case SADB_EXT_KEY_ENCRYPT:
84 + if (verify_key_len(p))
85 + return -EINVAL;
86 + break;
87 + default:
88 + break;
89 }
90 ext_hdrs[ext_type-1] = (void *) p;
91 }
92 @@ -1111,14 +1138,12 @@ static struct xfrm_state * pfkey_msg2xfr
93 key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
94 if (key != NULL &&
95 sa->sadb_sa_auth != SADB_X_AALG_NULL &&
96 - ((key->sadb_key_bits+7) / 8 == 0 ||
97 - (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
98 + key->sadb_key_bits == 0)
99 return ERR_PTR(-EINVAL);
100 key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
101 if (key != NULL &&
102 sa->sadb_sa_encrypt != SADB_EALG_NULL &&
103 - ((key->sadb_key_bits+7) / 8 == 0 ||
104 - (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
105 + key->sadb_key_bits == 0)
106 return ERR_PTR(-EINVAL);
107
108 x = xfrm_state_alloc(net);