Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^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");