From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dmitry Safonov Subject: [PATCH 10/18] xfrm: Send state notifications in compat format too Date: Thu, 26 Jul 2018 03:31:36 +0100 Message-ID: <20180726023144.31066-11-dima@arista.com> References: <20180726023144.31066-1-dima@arista.com> Cc: Dmitry Safonov , "David S. Miller" , Herbert Xu , Steffen Klassert , Dmitry Safonov <0x7f454c46@gmail.com>, netdev@vger.kernel.org To: linux-kernel@vger.kernel.org Return-path: In-Reply-To: <20180726023144.31066-1-dima@arista.com> Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org Applications that used native bind() syscall are in XFRMNLGRP_SA, so send there xfrm_usersa_info messages (with 64-bit ABI). Compatible applications are added to kernel-hidden XFRMNLGRP_COMPAT_SA group, so send there xfrm_usersa_info messages_packed (with 32-bit ABI) Cc: "David S. Miller" Cc: Herbert Xu Cc: Steffen Klassert Cc: netdev@vger.kernel.org Signed-off-by: Dmitry Safonov --- net/xfrm/xfrm_user.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 63622264a3a9..230462077dc9 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2856,18 +2856,24 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x) return l; } -static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) +static int __xfrm_notify_sa(struct xfrm_state *x, + const struct km_event *c, bool compat) { struct net *net = xs_net(x); - struct xfrm_usersa_info *p; struct xfrm_usersa_id *id; struct nlmsghdr *nlh; struct sk_buff *skb; unsigned int len = xfrm_sa_len(x); - unsigned int headlen; + unsigned int headlen, usersa_info_size; + void *usersa_info; int err; - headlen = sizeof(*p); + if (compat) + usersa_info_size = sizeof(struct xfrm_usersa_info_packed); + else + usersa_info_size = sizeof(struct xfrm_usersa_info); + headlen = usersa_info_size; + if (c->event == XFRM_MSG_DELSA) { len += nla_total_size(headlen); headlen = sizeof(*id); @@ -2884,7 +2890,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) if (nlh == NULL) goto out_free_skb; - p = nlmsg_data(nlh); + usersa_info = nlmsg_data(nlh); if (c->event == XFRM_MSG_DELSA) { struct nlattr *attr; @@ -2895,26 +2901,40 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) id->family = x->props.family; id->proto = x->id.proto; - attr = nla_reserve(skb, XFRMA_SA, sizeof(*p)); + attr = nla_reserve(skb, XFRMA_SA, usersa_info_size); err = -EMSGSIZE; if (attr == NULL) goto out_free_skb; - p = nla_data(attr); + usersa_info = nla_data(attr); } - err = copy_to_user_state_extra(x, p, skb); + + if (compat) + err = copy_to_user_state_extra(x, usersa_info, skb); + else + err = copy_to_user_state_extra_compat(x, usersa_info, skb); if (err) goto out_free_skb; nlmsg_end(skb, nlh); - return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_SA); + return xfrm_nlmsg_multicast(net, skb, 0, + compat ? XFRMNLGRP_COMPAT_SA : XFRMNLGRP_SA); out_free_skb: kfree_skb(skb); return err; } +static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) +{ + int ret = __xfrm_notify_sa(x, c, false); + + if ((ret && ret != -ESRCH) || !IS_ENABLED(CONFIG_COMPAT)) + return ret; + return __xfrm_notify_sa(x, c, true); +} + static int xfrm_send_state_notify(struct xfrm_state *x, const struct km_event *c) { -- 2.13.6