Blob Blame History Raw
From: Shung-Hsi Yu <shung-hsi.yu@suse.com>
Patch-mainline: Never, kABI
Subject: kABI: restore signature of xfrm_policy_bysel_ctx() and xfrm_policy_byid()
References: bsc#1174645

Upstream commit 4f47e8ab6ab7 ("xfrm: policy: match with both mark and mask
on user interfaces"), imported as
patches.suse/xfrm-policy-match-with-both-mark-and-mask-on-user-in.patch,
changes the signature of xfrm_policy_bysel_ctx() and xfrm_policy_byid() to
take `const struct xfrm_mark *mark` instead of `u32 mark`, breaking the
kABI.

This patch renames both xfrm_policy_bysel_ctx() and xfrm_policy_byid() to
have a prefix of `__kabi__` and create wrapper functions that takes their
name with the original function signature.

Signed-off-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
---
 include/net/xfrm.h     |   21 ++++++++++++++-------
 net/key/af_key.c       |   10 +++++-----
 net/xfrm/xfrm_policy.c |   30 +++++++++++++++++++++++++-----
 net/xfrm/xfrm_user.c   |   16 ++++++++--------
 4 files changed, 52 insertions(+), 25 deletions(-)

--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1635,16 +1635,23 @@ int xfrm_policy_walk(struct net *net, st
 		     void *);
 void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
-struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
-					  const struct xfrm_mark *mark,
-					  u32 if_id, u8 type, int dir,
+struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
+					  u8 type, int dir,
 					  struct xfrm_selector *sel,
 					  struct xfrm_sec_ctx *ctx, int delete,
 					  int *err);
-struct xfrm_policy *xfrm_policy_byid(struct net *net,
-				     const struct xfrm_mark *mark, u32 if_id,
-				     u8 type, int dir, u32 id, int delete,
-				     int *err);
+struct xfrm_policy *__kabi__xfrm_policy_bysel_ctx(struct net *net,
+						  const struct xfrm_mark *mark,
+						  u32 if_id, u8 type, int dir,
+						  struct xfrm_selector *sel,
+						  struct xfrm_sec_ctx *ctx, int delete,
+						  int *err);
+struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id, u8,
+				     int dir, u32 id, int delete, int *err);
+struct xfrm_policy *__kabi__xfrm_policy_byid(struct net *net,
+					     const struct xfrm_mark *mark, u32 if_id,
+					     u8 type, int dir, u32 id, int delete,
+					     int *err);
 int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
 void xfrm_policy_hash_rebuild(struct net *net);
 u32 xfrm_get_acqseq(void);
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2407,9 +2407,9 @@ static int pfkey_spddelete(struct sock *
 			return err;
 	}
 
-	xp = xfrm_policy_bysel_ctx(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN,
-				   pol->sadb_x_policy_dir - 1, &sel, pol_ctx,
-				   1, &err);
+	xp = __kabi__xfrm_policy_bysel_ctx(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN,
+					   pol->sadb_x_policy_dir - 1, &sel, pol_ctx,
+					   1, &err);
 	security_xfrm_policy_free(pol_ctx);
 	if (xp == NULL)
 		return -ENOENT;
@@ -2658,8 +2658,8 @@ static int pfkey_spdget(struct sock *sk,
 		return -EINVAL;
 
 	delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2);
-	xp = xfrm_policy_byid(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN,
-			      dir, pol->sadb_x_policy_id, delete, &err);
+	xp = __kabi__xfrm_policy_byid(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN,
+				      dir, pol->sadb_x_policy_id, delete, &err);
 	if (xp == NULL)
 		return -ENOENT;
 
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1623,9 +1623,9 @@ __xfrm_policy_bysel_ctx(struct hlist_hea
 }
 
 struct xfrm_policy *
-xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
-		      u8 type, int dir, struct xfrm_selector *sel,
-		      struct xfrm_sec_ctx *ctx, int delete, int *err)
+__kabi__xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+			      u8 type, int dir, struct xfrm_selector *sel,
+			      struct xfrm_sec_ctx *ctx, int delete, int *err)
 {
 	struct xfrm_pol_inexact_bin *bin = NULL;
 	struct xfrm_policy *pol, *ret = NULL;
@@ -1690,11 +1690,22 @@ xfrm_policy_bysel_ctx(struct net *net, c
 		xfrm_policy_inexact_prune_bin(bin);
 	return ret;
 }
+EXPORT_SYMBOL(__kabi__xfrm_policy_bysel_ctx);
+
+/* kABI compatibility wrapper */
+struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
+					  u8 type, int dir,
+					  struct xfrm_selector *sel,
+					  struct xfrm_sec_ctx *ctx, int delete,
+					  int *err)
+{
+	return __kabi__xfrm_policy_bysel_ctx(net, (const struct xfrm_mark *) &mark, if_id, type, dir, sel, ctx, delete, err);
+}
 EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
 struct xfrm_policy *
-xfrm_policy_byid(struct net *net, const struct xfrm_mark *mark, u32 if_id,
-		 u8 type, int dir, u32 id, int delete, int *err)
+__kabi__xfrm_policy_byid(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+			 u8 type, int dir, u32 id, int delete, int *err)
 {
 	struct xfrm_policy *pol, *ret;
 	struct hlist_head *chain;
@@ -1730,6 +1741,15 @@ xfrm_policy_byid(struct net *net, const
 		xfrm_policy_kill(ret);
 	return ret;
 }
+EXPORT_SYMBOL(__kabi__xfrm_policy_byid);
+
+/* kABI compatibility wrapper */
+struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id,
+				     u8 type, int dir, u32 id, int delete,
+				     int *err)
+{
+	return __kabi__xfrm_policy_byid(net, (const struct xfrm_mark *) &mark, if_id, type, dir, id, delete, err);
+}
 EXPORT_SYMBOL(xfrm_policy_byid);
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1881,8 +1881,8 @@ static int xfrm_get_policy(struct sk_buf
 	xfrm_mark_get(attrs, &m);
 
 	if (p->index)
-		xp = xfrm_policy_byid(net, &m, if_id, type, p->dir,
-				      p->index, delete, &err);
+		xp = __kabi__xfrm_policy_byid(net, &m, if_id, type, p->dir,
+					      p->index, delete, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -1899,8 +1899,8 @@ static int xfrm_get_policy(struct sk_buf
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir,
-					   &p->sel, ctx, delete, &err);
+		xp = __kabi__xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir,
+						   &p->sel, ctx, delete, &err);
 		security_xfrm_policy_free(ctx);
 	}
 	if (xp == NULL)
@@ -2183,8 +2183,8 @@ static int xfrm_add_pol_expire(struct sk
 	xfrm_mark_get(attrs, &m);
 
 	if (p->index)
-		xp = xfrm_policy_byid(net, &m, if_id, type, p->dir, p->index,
-				      0, &err);
+		xp = __kabi__xfrm_policy_byid(net, &m, if_id, type, p->dir, p->index,
+					      0, &err);
 	else {
 		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_sec_ctx *ctx;
@@ -2201,8 +2201,8 @@ static int xfrm_add_pol_expire(struct sk
 			if (err)
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir,
-					   &p->sel, ctx, 0, &err);
+		xp = __kabi__xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir,
+						   &p->sel, ctx, 0, &err);
 		security_xfrm_policy_free(ctx);
 	}
 	if (xp == NULL)