From 1ef98efdea763e4aa4f399ca1a9d173bfc9c7aa5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 13 Jun 2018 20:18:09 +0200 Subject: [PATCH] 4.9-stable patches added patches: af_key-always-verify-length-of-provided-sadb_key.patch --- ...s-verify-length-of-provided-sadb_key.patch | 108 ++++++++++++++++++ queue-4.9/series | 1 + 2 files changed, 109 insertions(+) create mode 100644 queue-4.9/af_key-always-verify-length-of-provided-sadb_key.patch diff --git a/queue-4.9/af_key-always-verify-length-of-provided-sadb_key.patch b/queue-4.9/af_key-always-verify-length-of-provided-sadb_key.patch new file mode 100644 index 00000000000..1a3888a3df5 --- /dev/null +++ b/queue-4.9/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; + } +@@ -1111,14 +1138,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.9/series b/queue-4.9/series index fec4decd6bf..420fc0f3191 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -3,3 +3,4 @@ bonding-correctly-update-link-status-during-mii-commit-phase.patch bonding-fix-active-backup-transition.patch bonding-require-speed-duplex-only-for-802.3ad-alb-and-tlb.patch nvme-pci-initialize-queue-memory-before-interrupts.patch +af_key-always-verify-length-of-provided-sadb_key.patch -- 2.47.3