| .. | .. |
|---|
| 5 | 5 | * Based on code and translator idea by: Florian Westphal <fw@strlen.de> |
|---|
| 6 | 6 | */ |
|---|
| 7 | 7 | #include <linux/compat.h> |
|---|
| 8 | +#include <linux/nospec.h> |
|---|
| 8 | 9 | #include <linux/xfrm.h> |
|---|
| 9 | 10 | #include <net/xfrm.h> |
|---|
| 10 | 11 | |
|---|
| .. | .. |
|---|
| 107 | 108 | [XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) }, |
|---|
| 108 | 109 | [XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) }, |
|---|
| 109 | 110 | [XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) }, |
|---|
| 110 | | - [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) }, |
|---|
| 111 | + [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_user_sec_ctx) }, |
|---|
| 111 | 112 | [XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) }, |
|---|
| 112 | 113 | [XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) }, |
|---|
| 113 | 114 | [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 }, |
|---|
| .. | .. |
|---|
| 300 | 301 | nla_for_each_attr(nla, attrs, len, remaining) { |
|---|
| 301 | 302 | int err; |
|---|
| 302 | 303 | |
|---|
| 303 | | - switch (type) { |
|---|
| 304 | + switch (nlh_src->nlmsg_type) { |
|---|
| 304 | 305 | case XFRM_MSG_NEWSPDINFO: |
|---|
| 305 | 306 | err = xfrm_nla_cpy(dst, nla, nla_len(nla)); |
|---|
| 306 | 307 | break; |
|---|
| .. | .. |
|---|
| 435 | 436 | NL_SET_ERR_MSG(extack, "Bad attribute"); |
|---|
| 436 | 437 | return -EOPNOTSUPP; |
|---|
| 437 | 438 | } |
|---|
| 439 | + type = array_index_nospec(type, XFRMA_MAX + 1); |
|---|
| 438 | 440 | if (nla_len(nla) < compat_policy[type].len) { |
|---|
| 439 | 441 | NL_SET_ERR_MSG(extack, "Attribute bad length"); |
|---|
| 440 | 442 | return -EOPNOTSUPP; |
|---|