diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index a76be47..30a9aa3 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -368,13 +368,16 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) struct xfrm_algo_auth auth; } u; char buf[XFRM_ALGO_KEY_BUF_SIZE]; - } alg = {}; + } *alg; int len; __u32 icvlen, trunclen; char *name; char *key; char *buf; + alg = alloca (sizeof (*alg) + XFRM_ALGO_KEY_BUF_SIZE); + memset (alg, 0, sizeof (*alg) + XFRM_ALGO_KEY_BUF_SIZE); + switch (type) { case XFRMA_ALG_AEAD: if (aeadop) @@ -412,8 +415,8 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) NEXT_ARG(); key = *argv; - buf = alg.u.alg.alg_key; - len = sizeof(alg.u.alg); + buf = alg->u.alg.alg_key; + len = sizeof(alg->u.alg); switch (type) { case XFRMA_ALG_AEAD: @@ -423,10 +426,10 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) if (get_u32(&icvlen, *argv, 0)) invarg("\"aead\" ICV length is invalid", *argv); - alg.u.aead.alg_icv_len = icvlen; + alg->u.aead.alg_icv_len = icvlen; - buf = alg.u.aead.alg_key; - len = sizeof(alg.u.aead); + buf = alg->u.aead.alg_key; + len = sizeof(alg->u.aead); break; case XFRMA_ALG_AUTH_TRUNC: if (!NEXT_ARG_OK()) @@ -435,19 +438,19 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) if (get_u32(&trunclen, *argv, 0)) invarg("\"auth\" trunc length is invalid", *argv); - alg.u.auth.alg_trunc_len = trunclen; + alg->u.auth.alg_trunc_len = trunclen; - buf = alg.u.auth.alg_key; - len = sizeof(alg.u.auth); + buf = alg->u.auth.alg_key; + len = sizeof(alg->u.auth); break; } - xfrm_algo_parse((void *)&alg, type, name, key, - buf, sizeof(alg.buf)); - len += alg.u.alg.alg_key_len; + xfrm_algo_parse((void *)alg, type, name, key, + buf, sizeof(alg->buf)); + len += alg->u.alg.alg_key_len; addattr_l(&req.n, sizeof(req.buf), type, - (void *)&alg, len); + (void *)alg, len); break; } default: