From: Greg Kroah-Hartman Date: Wed, 13 Jun 2018 18:17:51 +0000 (+0200) Subject: 4.16-stable patches X-Git-Tag: v4.17.2~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9142c117ec47829754fab1a3c73348b701e4bbd2;p=thirdparty%2Fkernel%2Fstable-queue.git 4.16-stable patches added patches: af_key-always-verify-length-of-provided-sadb_key.patch --- diff --git a/queue-4.16/af_key-always-verify-length-of-provided-sadb_key.patch b/queue-4.16/af_key-always-verify-length-of-provided-sadb_key.patch new file mode 100644 index 00000000000..72ea6de9e68 --- /dev/null +++ b/queue-4.16/af_key-always-verify-length-of-provided-sadb_key.patch @@ -0,0 +1,108 @@ +From 4b66af2d6356a00e94bcdea3e7fea324e8b5c6f4 Mon Sep 17 00:00:00 2001 +From: Kevin Easton +Date: Sat, 7 Apr 2018 11:40:33 -0400 +Subject: af_key: Always verify length of provided sadb_key + +From: Kevin Easton + +commit 4b66af2d6356a00e94bcdea3e7fea324e8b5c6f4 upstream. + +Key extensions (struct sadb_key) include a user-specified number of key +bits. The kernel uses that number to determine how much key data to copy +out of the message in pfkey_msg2xfrm_state(). + +The length of the sadb_key message must be verified to be long enough, +even in the case of SADB_X_AALG_NULL. Furthermore, the sadb_key_len value +must be long enough to include both the key data and the struct sadb_key +itself. + +Introduce a helper function verify_key_len(), and call it from +parse_exthdrs() where other exthdr types are similarly checked for +correctness. + +Signed-off-by: Kevin Easton +Reported-by: syzbot+5022a34ca5a3d49b84223653fab632dfb7b4cf37@syzkaller.appspotmail.com +Signed-off-by: Steffen Klassert +Cc: Zubin Mithra +Signed-off-by: Greg Kroah-Hartman + +--- + net/key/af_key.c | 45 +++++++++++++++++++++++++++++++++++---------- + 1 file changed, 35 insertions(+), 10 deletions(-) + +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -437,6 +437,24 @@ static int verify_address_len(const void + return 0; + } + ++static inline int sadb_key_len(const struct sadb_key *key) ++{ ++ int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8); ++ ++ return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes, ++ sizeof(uint64_t)); ++} ++ ++static int verify_key_len(const void *p) ++{ ++ const struct sadb_key *key = p; ++ ++ if (sadb_key_len(key) > key->sadb_key_len) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) + { + return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) + +@@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff + return -EINVAL; + if (ext_hdrs[ext_type-1] != NULL) + return -EINVAL; +- if (ext_type == SADB_EXT_ADDRESS_SRC || +- ext_type == SADB_EXT_ADDRESS_DST || +- ext_type == SADB_EXT_ADDRESS_PROXY || +- ext_type == SADB_X_EXT_NAT_T_OA) { ++ switch (ext_type) { ++ case SADB_EXT_ADDRESS_SRC: ++ case SADB_EXT_ADDRESS_DST: ++ case SADB_EXT_ADDRESS_PROXY: ++ case SADB_X_EXT_NAT_T_OA: + if (verify_address_len(p)) + return -EINVAL; +- } +- if (ext_type == SADB_X_EXT_SEC_CTX) { ++ break; ++ case SADB_X_EXT_SEC_CTX: + if (verify_sec_ctx_len(p)) + return -EINVAL; ++ break; ++ case SADB_EXT_KEY_AUTH: ++ case SADB_EXT_KEY_ENCRYPT: ++ if (verify_key_len(p)) ++ return -EINVAL; ++ break; ++ default: ++ break; + } + ext_hdrs[ext_type-1] = (void *) p; + } +@@ -1104,14 +1131,12 @@ static struct xfrm_state * pfkey_msg2xfr + key = ext_hdrs[SADB_EXT_KEY_AUTH - 1]; + if (key != NULL && + sa->sadb_sa_auth != SADB_X_AALG_NULL && +- ((key->sadb_key_bits+7) / 8 == 0 || +- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) ++ key->sadb_key_bits == 0) + return ERR_PTR(-EINVAL); + key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; + if (key != NULL && + sa->sadb_sa_encrypt != SADB_EALG_NULL && +- ((key->sadb_key_bits+7) / 8 == 0 || +- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) ++ key->sadb_key_bits == 0) + return ERR_PTR(-EINVAL); + + x = xfrm_state_alloc(net); diff --git a/queue-4.16/series b/queue-4.16/series index 74d1bb64d8c..cf942d031ab 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -1,3 +1,4 @@ netfilter-nf_tables-fix-null-pointer-dereference-on-nft_ct_helper_obj_dump.patch crypto-chelsio-request-to-hw-should-wrap.patch blkdev_report_zones_ioctl-use-vmalloc-to-allocate-large-buffers.patch +af_key-always-verify-length-of-provided-sadb_key.patch