^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * XFRM compat layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Dmitry Safonov <dima@arista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Based on code and translator idea by: Florian Westphal <fw@strlen.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <net/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct compat_xfrm_lifetime_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) compat_u64 soft_byte_limit, hard_byte_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) compat_u64 soft_packet_limit, hard_packet_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) compat_u64 soft_add_expires_seconds, hard_add_expires_seconds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) compat_u64 soft_use_expires_seconds, hard_use_expires_seconds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) }; /* same size on 32bit, but only 4 byte alignment required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct compat_xfrm_lifetime_cur {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) compat_u64 bytes, packets, add_time, use_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }; /* same size on 32bit, but only 4 byte alignment required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct compat_xfrm_userpolicy_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct xfrm_selector sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct compat_xfrm_lifetime_cfg lft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct compat_xfrm_lifetime_cur curlft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) __u32 priority, index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) u8 dir, action, flags, share;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* 4 bytes additional padding on 64bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct compat_xfrm_usersa_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct xfrm_selector sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct xfrm_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) xfrm_address_t saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct compat_xfrm_lifetime_cfg lft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct compat_xfrm_lifetime_cur curlft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct xfrm_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) __u32 seq, reqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u16 family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 mode, replay_window, flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* 4 bytes additional padding on 64bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct compat_xfrm_user_acquire {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct xfrm_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) xfrm_address_t saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct xfrm_selector sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct compat_xfrm_userpolicy_info policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* 4 bytes additional padding on 64bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) __u32 aalgos, ealgos, calgos, seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct compat_xfrm_userspi_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct compat_xfrm_usersa_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* 4 bytes additional padding on 64bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) __u32 min, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct compat_xfrm_user_expire {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct compat_xfrm_usersa_info state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* 8 bytes additional padding on 64bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct compat_xfrm_user_polexpire {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct compat_xfrm_userpolicy_info pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* 8 bytes additional padding on 64bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u8 hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define XMSGSIZE(type) sizeof(struct type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static const int compat_msg_min[XFRM_NR_MSGTYPES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_usersa_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_userpolicy_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_userspi_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_user_acquire),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_user_expire),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_userpolicy_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_usersa_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(compat_xfrm_user_polexpire),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) [XFRM_MSG_NEWSADINFO - XFRM_MSG_BASE] = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) [XFRM_MSG_NEWSPDINFO - XFRM_MSG_BASE] = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) [XFRM_MSG_MAPPING - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_mapping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static const struct nla_policy compat_policy[XFRMA_MAX+1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) [XFRMA_SA] = { .len = XMSGSIZE(compat_xfrm_usersa_info)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) [XFRMA_POLICY] = { .len = XMSGSIZE(compat_xfrm_userpolicy_info)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) [XFRMA_LASTUSED] = { .type = NLA_U64},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) [XFRMA_ALG_AUTH_TRUNC] = { .len = sizeof(struct xfrm_algo_auth)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) [XFRMA_ALG_AEAD] = { .len = sizeof(struct xfrm_algo_aead) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) [XFRMA_ALG_AUTH] = { .len = sizeof(struct xfrm_algo) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) [XFRMA_ALG_CRYPT] = { .len = sizeof(struct xfrm_algo) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) [XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) [XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) [XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) [XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) [XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) [XFRMA_ETIMER_THRESH] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) [XFRMA_SRCADDR] = { .len = sizeof(xfrm_address_t) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) [XFRMA_COADDR] = { .len = sizeof(xfrm_address_t) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) [XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) [XFRMA_TFCPAD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) [XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) [XFRMA_PROTO] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) [XFRMA_SET_MARK] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) [XFRMA_SET_MARK_MASK] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) [XFRMA_IF_ID] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static struct nlmsghdr *xfrm_nlmsg_put_compat(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) const struct nlmsghdr *nlh_src, u16 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int payload = compat_msg_min[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int src_len = xfrm_msg_min[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct nlmsghdr *nlh_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Compat messages are shorter or equal to native (+padding) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (WARN_ON_ONCE(src_len < payload))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return ERR_PTR(-EMSGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) nlh_dst = nlmsg_put(skb, nlh_src->nlmsg_pid, nlh_src->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) nlh_src->nlmsg_type, payload, nlh_src->nlmsg_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!nlh_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return ERR_PTR(-EMSGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) memset(nlmsg_data(nlh_dst), 0, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) switch (nlh_src->nlmsg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Compat message has the same layout as native */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case XFRM_MSG_DELSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case XFRM_MSG_DELPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case XFRM_MSG_FLUSHSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case XFRM_MSG_FLUSHPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case XFRM_MSG_NEWAE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case XFRM_MSG_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case XFRM_MSG_MIGRATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case XFRM_MSG_NEWSADINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case XFRM_MSG_NEWSPDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case XFRM_MSG_MAPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) WARN_ON_ONCE(src_len != payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) memcpy(nlmsg_data(nlh_dst), nlmsg_data(nlh_src), src_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* 4 byte alignment for trailing u64 on native, but not on compat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case XFRM_MSG_NEWSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case XFRM_MSG_NEWPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case XFRM_MSG_UPDSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case XFRM_MSG_UPDPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) WARN_ON_ONCE(src_len != payload + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) memcpy(nlmsg_data(nlh_dst), nlmsg_data(nlh_src), payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case XFRM_MSG_EXPIRE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) const struct xfrm_user_expire *src_ue = nlmsg_data(nlh_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct compat_xfrm_user_expire *dst_ue = nlmsg_data(nlh_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* compat_xfrm_user_expire has 4-byte smaller state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) memcpy(dst_ue, src_ue, sizeof(dst_ue->state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) dst_ue->hard = src_ue->hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case XFRM_MSG_ACQUIRE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) const struct xfrm_user_acquire *src_ua = nlmsg_data(nlh_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct compat_xfrm_user_acquire *dst_ua = nlmsg_data(nlh_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) memcpy(dst_ua, src_ua, offsetof(struct compat_xfrm_user_acquire, aalgos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) dst_ua->aalgos = src_ua->aalgos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dst_ua->ealgos = src_ua->ealgos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dst_ua->calgos = src_ua->calgos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dst_ua->seq = src_ua->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case XFRM_MSG_POLEXPIRE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) const struct xfrm_user_polexpire *src_upe = nlmsg_data(nlh_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct compat_xfrm_user_polexpire *dst_upe = nlmsg_data(nlh_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* compat_xfrm_user_polexpire has 4-byte smaller state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) memcpy(dst_upe, src_upe, sizeof(dst_upe->pol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) dst_upe->hard = src_upe->hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case XFRM_MSG_ALLOCSPI: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) const struct xfrm_userspi_info *src_usi = nlmsg_data(nlh_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct compat_xfrm_userspi_info *dst_usi = nlmsg_data(nlh_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* compat_xfrm_user_polexpire has 4-byte smaller state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) memcpy(dst_usi, src_usi, sizeof(src_usi->info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dst_usi->min = src_usi->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dst_usi->max = src_usi->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Not being sent by kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case XFRM_MSG_GETSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case XFRM_MSG_GETPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case XFRM_MSG_GETAE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case XFRM_MSG_GETSADINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case XFRM_MSG_GETSPDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) pr_warn_once("unsupported nlmsg_type %d\n", nlh_src->nlmsg_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return ERR_PTR(-EOPNOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return nlh_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int xfrm_nla_cpy(struct sk_buff *dst, const struct nlattr *src, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return nla_put(dst, src->nla_type, len, nla_data(src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int xfrm_xlate64_attr(struct sk_buff *dst, const struct nlattr *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) switch (src->nla_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case XFRMA_PAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* Ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case XFRMA_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case XFRMA_ALG_AUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case XFRMA_ALG_CRYPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case XFRMA_ALG_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case XFRMA_ENCAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case XFRMA_TMPL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return xfrm_nla_cpy(dst, src, nla_len(src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case XFRMA_SA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return xfrm_nla_cpy(dst, src, XMSGSIZE(compat_xfrm_usersa_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case XFRMA_POLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return xfrm_nla_cpy(dst, src, XMSGSIZE(compat_xfrm_userpolicy_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) case XFRMA_SEC_CTX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return xfrm_nla_cpy(dst, src, nla_len(src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case XFRMA_LTIME_VAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return nla_put_64bit(dst, src->nla_type, nla_len(src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) nla_data(src), XFRMA_PAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case XFRMA_REPLAY_VAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case XFRMA_REPLAY_THRESH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case XFRMA_ETIMER_THRESH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case XFRMA_SRCADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case XFRMA_COADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return xfrm_nla_cpy(dst, src, nla_len(src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case XFRMA_LASTUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return nla_put_64bit(dst, src->nla_type, nla_len(src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) nla_data(src), XFRMA_PAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case XFRMA_POLICY_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case XFRMA_MIGRATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case XFRMA_ALG_AEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case XFRMA_KMADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case XFRMA_ALG_AUTH_TRUNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case XFRMA_MARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case XFRMA_TFCPAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case XFRMA_REPLAY_ESN_VAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case XFRMA_SA_EXTRA_FLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case XFRMA_PROTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case XFRMA_ADDRESS_FILTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case XFRMA_OFFLOAD_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case XFRMA_SET_MARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case XFRMA_SET_MARK_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case XFRMA_IF_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return xfrm_nla_cpy(dst, src, nla_len(src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) BUILD_BUG_ON(XFRMA_MAX != XFRMA_IF_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) pr_warn_once("unsupported nla_type %d\n", src->nla_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* Take kernel-built (64bit layout) and create 32bit layout for userspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int xfrm_xlate64(struct sk_buff *dst, const struct nlmsghdr *nlh_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) u16 type = nlh_src->nlmsg_type - XFRM_MSG_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) const struct nlattr *nla, *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct nlmsghdr *nlh_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int len, remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) nlh_dst = xfrm_nlmsg_put_compat(dst, nlh_src, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (IS_ERR(nlh_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return PTR_ERR(nlh_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) attrs = nlmsg_attrdata(nlh_src, xfrm_msg_min[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) len = nlmsg_attrlen(nlh_src, xfrm_msg_min[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) nla_for_each_attr(nla, attrs, len, remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case XFRM_MSG_NEWSPDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) err = xfrm_nla_cpy(dst, nla, nla_len(nla));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) err = xfrm_xlate64_attr(dst, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) nlmsg_end(dst, nlh_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int xfrm_alloc_compat(struct sk_buff *skb, const struct nlmsghdr *nlh_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) u16 type = nlh_src->nlmsg_type - XFRM_MSG_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct sk_buff *new = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (type >= ARRAY_SIZE(xfrm_msg_min)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) pr_warn_once("unsupported nlmsg_type %d\n", nlh_src->nlmsg_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (skb_shinfo(skb)->frag_list == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) new = alloc_skb(skb->len + skb_tailroom(skb), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) skb_shinfo(skb)->frag_list = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) err = xfrm_xlate64(skb_shinfo(skb)->frag_list, nlh_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) kfree_skb(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) skb_shinfo(skb)->frag_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* Calculates len of translated 64-bit message. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static size_t xfrm_user_rcv_calculate_len64(const struct nlmsghdr *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct nlattr *attrs[XFRMA_MAX + 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int maxtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) size_t len = nlmsg_len(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) switch (src->nlmsg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case XFRM_MSG_NEWSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case XFRM_MSG_NEWPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case XFRM_MSG_ALLOCSPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case XFRM_MSG_ACQUIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case XFRM_MSG_UPDPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) case XFRM_MSG_UPDSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case XFRM_MSG_EXPIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case XFRM_MSG_POLEXPIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) len += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case XFRM_MSG_NEWSPDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* attirbutes are xfrm_spdattr_type_t, not xfrm_attr_type_t */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Unexpected for anything, but XFRM_MSG_NEWSPDINFO, please
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * correct both 64=>32-bit and 32=>64-bit translators to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * new attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (WARN_ON_ONCE(maxtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (attrs[XFRMA_SA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (attrs[XFRMA_POLICY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* XXX: some attrs may need to be realigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * if !CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int xfrm_attr_cpy32(void *dst, size_t *pos, const struct nlattr *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) size_t size, int copy_len, int payload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct nlmsghdr *nlmsg = dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* xfrm_user_rcv_msg_compat() relies on fact that 32-bit messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * have the same len or shorted than 64-bit ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * 32-bit translation that is bigger than 64-bit original is unexpected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (WARN_ON_ONCE(copy_len > payload))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) copy_len = payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (size - *pos < nla_attr_size(payload))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) nla = dst + *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) memcpy(nla, src, nla_attr_size(copy_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) nla->nla_len = nla_attr_size(payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) *pos += nla_attr_size(copy_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) nlmsg->nlmsg_len += nla->nla_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) memset(dst + *pos, 0, payload - copy_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *pos += payload - copy_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int xfrm_xlate32_attr(void *dst, const struct nlattr *nla,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) size_t *pos, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int type = nla_type(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) u16 pol_len32, pol_len64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (type > XFRMA_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) BUILD_BUG_ON(XFRMA_MAX != XFRMA_IF_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) NL_SET_ERR_MSG(extack, "Bad attribute");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (nla_len(nla) < compat_policy[type].len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) NL_SET_ERR_MSG(extack, "Attribute bad length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) pol_len32 = compat_policy[type].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pol_len64 = xfrma_policy[type].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /* XFRMA_SA and XFRMA_POLICY - need to know how-to translate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (pol_len32 != pol_len64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (nla_len(nla) != compat_policy[type].len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) NL_SET_ERR_MSG(extack, "Attribute bad length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) err = xfrm_attr_cpy32(dst, pos, nla, size, pol_len32, pol_len64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return xfrm_attr_cpy32(dst, pos, nla, size, nla_len(nla), nla_len(nla));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int xfrm_xlate32(struct nlmsghdr *dst, const struct nlmsghdr *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct nlattr *attrs[XFRMA_MAX+1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) size_t size, u8 type, int maxtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) size_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) memcpy(dst, src, NLMSG_HDRLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dst->nlmsg_len = NLMSG_HDRLEN + xfrm_msg_min[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) memset(nlmsg_data(dst), 0, xfrm_msg_min[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) switch (src->nlmsg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* Compat message has the same layout as native */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) case XFRM_MSG_DELSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case XFRM_MSG_GETSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case XFRM_MSG_DELPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case XFRM_MSG_GETPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case XFRM_MSG_FLUSHSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) case XFRM_MSG_FLUSHPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case XFRM_MSG_NEWAE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case XFRM_MSG_GETAE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) case XFRM_MSG_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) case XFRM_MSG_MIGRATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case XFRM_MSG_NEWSADINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) case XFRM_MSG_GETSADINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case XFRM_MSG_NEWSPDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case XFRM_MSG_GETSPDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case XFRM_MSG_MAPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) memcpy(nlmsg_data(dst), nlmsg_data(src), compat_msg_min[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* 4 byte alignment for trailing u64 on native, but not on compat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) case XFRM_MSG_NEWSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case XFRM_MSG_NEWPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) case XFRM_MSG_UPDSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case XFRM_MSG_UPDPOLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) memcpy(nlmsg_data(dst), nlmsg_data(src), compat_msg_min[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) case XFRM_MSG_EXPIRE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) const struct compat_xfrm_user_expire *src_ue = nlmsg_data(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct xfrm_user_expire *dst_ue = nlmsg_data(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* compat_xfrm_user_expire has 4-byte smaller state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) memcpy(dst_ue, src_ue, sizeof(src_ue->state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) dst_ue->hard = src_ue->hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case XFRM_MSG_ACQUIRE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) const struct compat_xfrm_user_acquire *src_ua = nlmsg_data(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct xfrm_user_acquire *dst_ua = nlmsg_data(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) memcpy(dst_ua, src_ua, offsetof(struct compat_xfrm_user_acquire, aalgos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dst_ua->aalgos = src_ua->aalgos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) dst_ua->ealgos = src_ua->ealgos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dst_ua->calgos = src_ua->calgos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dst_ua->seq = src_ua->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) case XFRM_MSG_POLEXPIRE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) const struct compat_xfrm_user_polexpire *src_upe = nlmsg_data(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct xfrm_user_polexpire *dst_upe = nlmsg_data(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* compat_xfrm_user_polexpire has 4-byte smaller state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) memcpy(dst_upe, src_upe, sizeof(src_upe->pol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dst_upe->hard = src_upe->hard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case XFRM_MSG_ALLOCSPI: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) const struct compat_xfrm_userspi_info *src_usi = nlmsg_data(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct xfrm_userspi_info *dst_usi = nlmsg_data(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* compat_xfrm_user_polexpire has 4-byte smaller state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) memcpy(dst_usi, src_usi, sizeof(src_usi->info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dst_usi->min = src_usi->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dst_usi->max = src_usi->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) NL_SET_ERR_MSG(extack, "Unsupported message type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) pos = dst->nlmsg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (maxtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* attirbutes are xfrm_spdattr_type_t, not xfrm_attr_type_t */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) WARN_ON_ONCE(src->nlmsg_type != XFRM_MSG_NEWSPDINFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) for (i = 1; i <= maxtype; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!attrs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* just copy - no need for translation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) err = xfrm_attr_cpy32(dst, &pos, attrs[i], size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) nla_len(attrs[i]), nla_len(attrs[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) for (i = 1; i < XFRMA_MAX + 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (i == XFRMA_PAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (!attrs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) err = xfrm_xlate32_attr(dst, attrs[i], &pos, size, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static struct nlmsghdr *xfrm_user_rcv_msg_compat(const struct nlmsghdr *h32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int maxtype, const struct nla_policy *policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* netlink_rcv_skb() checks if a message has full (struct nlmsghdr) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) u16 type = h32->nlmsg_type - XFRM_MSG_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct nlattr *attrs[XFRMA_MAX+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct nlmsghdr *h64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) BUILD_BUG_ON(ARRAY_SIZE(xfrm_msg_min) != ARRAY_SIZE(compat_msg_min));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (type >= ARRAY_SIZE(xfrm_msg_min))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* Don't call parse: the message might have only nlmsg header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if ((h32->nlmsg_type == XFRM_MSG_GETSA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) h32->nlmsg_type == XFRM_MSG_GETPOLICY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) (h32->nlmsg_flags & NLM_F_DUMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) err = nlmsg_parse_deprecated(h32, compat_msg_min[type], attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) maxtype ? : XFRMA_MAX, policy ? : compat_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) len = xfrm_user_rcv_calculate_len64(h32, attrs, maxtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* The message doesn't need translation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (len == nlmsg_len(h32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) len += NLMSG_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) h64 = kvmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (!h64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) err = xfrm_xlate32(h64, h32, attrs, len, type, maxtype, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) kvfree(h64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return h64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static int xfrm_user_policy_compat(u8 **pdata32, int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct compat_xfrm_userpolicy_info *p = (void *)*pdata32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) u8 *src_templates, *dst_templates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) u8 *data64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (optlen < sizeof(*p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) data64 = kmalloc_track_caller(optlen + 4, GFP_USER | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (!data64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) memcpy(data64, *pdata32, sizeof(*p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) memset(data64 + sizeof(*p), 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) src_templates = *pdata32 + sizeof(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) dst_templates = data64 + sizeof(*p) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) memcpy(dst_templates, src_templates, optlen - sizeof(*p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) kfree(*pdata32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *pdata32 = data64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static struct xfrm_translator xfrm_translator = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .alloc_compat = xfrm_alloc_compat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .rcv_msg_compat = xfrm_user_rcv_msg_compat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .xlate_user_policy_sockptr = xfrm_user_policy_compat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int __init xfrm_compat_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return xfrm_register_translator(&xfrm_translator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static void __exit xfrm_compat_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) xfrm_unregister_translator(&xfrm_translator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) module_init(xfrm_compat_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) module_exit(xfrm_compat_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) MODULE_AUTHOR("Dmitry Safonov");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) MODULE_DESCRIPTION("XFRM 32-bit compatibility layer");