Commit 03cc059d authored by James Morris's avatar James Morris Committed by James Morris

[IPSEC]: Guard against potentially fatal stack usage for auth_data.

parent 08506b24
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
#include <net/xfrm.h> #include <net/xfrm.h>
/* This is the maximum truncated ICV length that we know of. */
#define MAX_AH_AUTH_LEN 12
struct ah_data struct ah_data
{ {
u8 *key; u8 *key;
......
...@@ -199,7 +199,7 @@ int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buf ...@@ -199,7 +199,7 @@ int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buf
goto out; goto out;
} }
{ {
u8 auth_data[ahp->icv_trunc_len]; u8 auth_data[MAX_AH_AUTH_LEN];
memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
skb_push(skb, skb->data - skb->nh.raw); skb_push(skb, skb->data - skb->nh.raw);
...@@ -285,6 +285,8 @@ static int ah_init_state(struct xfrm_state *x, void *args) ...@@ -285,6 +285,8 @@ static int ah_init_state(struct xfrm_state *x, void *args)
ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8; ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN);
ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL); ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL);
if (!ahp->work_icv) if (!ahp->work_icv)
goto error; goto error;
......
...@@ -315,7 +315,7 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu ...@@ -315,7 +315,7 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
skb->nh.ipv6h->hop_limit = 0; skb->nh.ipv6h->hop_limit = 0;
{ {
u8 auth_data[ahp->icv_trunc_len]; u8 auth_data[MAX_AH_AUTH_LEN];
memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
memset(ah->auth_data, 0, ahp->icv_trunc_len); memset(ah->auth_data, 0, ahp->icv_trunc_len);
...@@ -420,6 +420,8 @@ static int ah6_init_state(struct xfrm_state *x, void *args) ...@@ -420,6 +420,8 @@ static int ah6_init_state(struct xfrm_state *x, void *args)
ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8; ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN);
ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL); ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL);
if (!ahp->work_icv) if (!ahp->work_icv)
goto error; goto error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment