[packages/spl] - fixes to get spl to build with linux 4.9 - rel 2

baggins baggins at pld-linux.org
Sat Jan 21 21:19:29 CET 2017


commit 1f0a73c186bcf17575c3c9e0292b02ca2f582b14
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Sat Jan 21 21:19:07 2017 +0100

    - fixes to get spl to build with linux 4.9
    - rel 2

 fix-crgetgroups-out-of-bound.patch | 102 ++++++++++++++++++++++++++
 fix-splat-cred.c-cred-usage.patch  |  80 ++++++++++++++++++++
 linux-4.9.patch                    | 146 +++++++++++++++++++++++++++++++++++++
 spl.spec                           |   8 +-
 4 files changed, 335 insertions(+), 1 deletion(-)
---
diff --git a/spl.spec b/spl.spec
index 77f2666..33fc820 100644
--- a/spl.spec
+++ b/spl.spec
@@ -21,7 +21,7 @@ exit 1
 %define		_duplicate_files_terminate_build	0
 
 %define		pname	spl
-%define		rel	1
+%define		rel	2
 Summary:	Solaris Porting Layer
 Summary(pl.UTF-8):	Solaris Porting Layer - warstwa do portowania kodu z Solarisa
 Name:		%{pname}%{?_pld_builder:%{?with_kernel:-kernel}}%{_alt_kernel}
@@ -31,6 +31,9 @@ License:	GPL v2+
 Group:		Applications/System
 Source0:	https://github.com/zfsonlinux/zfs/releases/download/zfs-%{version}/%{pname}-%{version}.tar.gz
 # Source0-md5:	54b049cde051d0bd67f3f18ff58113c2
+Patch0:		fix-crgetgroups-out-of-bound.patch
+Patch1:		fix-splat-cred.c-cred-usage.patch
+Patch2:		linux-4.9.patch
 URL:		http://zfsonlinux.org/
 BuildRequires:	rpmbuild(macros) >= 1.701
 %{?with_kernel:%{expand:%buildrequires_kernel kernel%%{_alt_kernel}-module-build >= 3:2.6.20.2}}
@@ -122,6 +125,9 @@ p=`pwd`\
 
 %prep
 %setup -q -n %{pname}-%{version}
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
 
 %build
 %{__aclocal} -I config
diff --git a/fix-crgetgroups-out-of-bound.patch b/fix-crgetgroups-out-of-bound.patch
new file mode 100644
index 0000000..537e2d2
--- /dev/null
+++ b/fix-crgetgroups-out-of-bound.patch
@@ -0,0 +1,102 @@
+From 9ba3c01923d45a19003641ceab311150752ed491 Mon Sep 17 00:00:00 2001
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Tue, 18 Oct 2016 15:52:30 -0700
+Subject: [PATCH] Fix crgetgroups out-of-bound and misc cred fix
+
+init_groups has 0 nblocks, therefore calling the current crgetgroups with
+init_groups would result in out-of-bound access. We fix this by returning NULL
+when nblocks is 0.
+
+Cap crgetngroups to NGROUPS_PER_BLOCK, since crgetgroups will only return
+blocks[0].
+
+Also, remove all get_group_info. The cred already holds reference on the
+group_info, and cred is not mutable. So there's no reason to hold extra
+reference, if we hold cred.
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Chunwei Chen <david.chen at osnexus.com>
+Closes #556
+---
+ module/spl/spl-cred.c | 31 ++++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/module/spl/spl-cred.c b/module/spl/spl-cred.c
+index a03f459..d046f95 100644
+--- a/module/spl/spl-cred.c
++++ b/module/spl/spl-cred.c
+@@ -62,19 +62,17 @@ cr_groups_search(const struct group_info *group_info, gid_t grp)
+ 	return 0;
+ }
+ 
+-/* Hold a reference on the credential and group info */
++/* Hold a reference on the credential */
+ void
+ crhold(cred_t *cr)
+ {
+ 	(void)get_cred((const cred_t *)cr);
+-	(void)get_group_info(cr->group_info);
+ }
+ 
+-/* Free a reference on the credential and group info */
++/* Free a reference on the credential */
+ void
+ crfree(cred_t *cr)
+ {
+-	put_group_info(cr->group_info);
+ 	put_cred((const cred_t *)cr);
+ }
+ 
+@@ -85,28 +83,32 @@ crgetngroups(const cred_t *cr)
+ 	struct group_info *gi;
+ 	int rc;
+ 
+-	gi = get_group_info(cr->group_info);
++	gi = cr->group_info;
+ 	rc = gi->ngroups;
+-	put_group_info(gi);
+-
++	/*
++	 * crgetgroups will only returns gi->blocks[0], which contains only
++	 * the first NGROUPS_PER_BLOCK groups.
++	 */
++	if (rc > NGROUPS_PER_BLOCK) {
++		WARN_ON_ONCE(1);
++		rc = NGROUPS_PER_BLOCK;
++	}
+ 	return rc;
+ }
+ 
+ /*
+  * Return an array of supplemental gids.  The returned address is safe
+  * to use as long as the caller has taken a reference with crhold().
+- * The caller is responsible for releasing the reference with crfree().
+  */
+ gid_t *
+ crgetgroups(const cred_t *cr)
+ {
+ 	struct group_info *gi;
+-	gid_t *gids;
+-
+-	gi = get_group_info(cr->group_info);
+-	gids = KGIDP_TO_SGIDP(gi->blocks[0]);
+-	put_group_info(gi);
++	gid_t *gids = NULL;
+ 
++	gi = cr->group_info;
++	if (gi->nblocks > 0)
++		gids = KGIDP_TO_SGIDP(gi->blocks[0]);
+ 	return gids;
+ }
+ 
+@@ -117,9 +119,8 @@ groupmember(gid_t gid, const cred_t *cr)
+ 	struct group_info *gi;
+ 	int rc;
+ 
+-	gi = get_group_info(cr->group_info);
++	gi = cr->group_info;
+ 	rc = cr_groups_search(gi, SGID_TO_KGID(gid));
+-	put_group_info(gi);
+ 
+ 	return rc;
+ }
diff --git a/fix-splat-cred.c-cred-usage.patch b/fix-splat-cred.c-cred-usage.patch
new file mode 100644
index 0000000..59e9c47
--- /dev/null
+++ b/fix-splat-cred.c-cred-usage.patch
@@ -0,0 +1,80 @@
+From 87063d7dc392cb710c70dba49021d6e4ec8961a9 Mon Sep 17 00:00:00 2001
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Tue, 18 Oct 2016 17:29:26 -0700
+Subject: [PATCH] Fix splat-cred.c cred usage
+
+No need to crhold current_cred(), fix possible leak in splat_cred_test2
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Chunwei Chen <david.chen at osnexus.com>
+Closes #556
+---
+ module/splat/splat-cred.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/module/splat/splat-cred.c b/module/splat/splat-cred.c
+index fadf9bc..e3d1c4e 100644
+--- a/module/splat/splat-cred.c
++++ b/module/splat/splat-cred.c
+@@ -53,18 +53,18 @@ splat_cred_test1(struct file *file, void *arg)
+ 	uid_t uid, ruid, suid;
+ 	gid_t gid, rgid, sgid, *groups;
+ 	int ngroups, i, count = 0;
++	cred_t *cr = CRED();
+ 
+-	uid  = crgetuid(CRED());
+-	ruid = crgetruid(CRED());
+-	suid = crgetsuid(CRED());
++	uid  = crgetuid(cr);
++	ruid = crgetruid(cr);
++	suid = crgetsuid(cr);
+ 
+-	gid  = crgetgid(CRED());
+-	rgid = crgetrgid(CRED());
+-	sgid = crgetsgid(CRED());
++	gid  = crgetgid(cr);
++	rgid = crgetrgid(cr);
++	sgid = crgetsgid(cr);
+ 
+-	crhold(CRED());
+-	ngroups = crgetngroups(CRED());
+-	groups  = crgetgroups(CRED());
++	ngroups = crgetngroups(cr);
++	groups = crgetgroups(cr);
+ 
+ 	memset(str, 0, GROUP_STR_SIZE);
+ 	for (i = 0; i < ngroups; i++) {
+@@ -78,8 +78,6 @@ splat_cred_test1(struct file *file, void *arg)
+ 		}
+ 	}
+ 
+-	crfree(CRED());
+-
+ 	splat_vprint(file, SPLAT_CRED_TEST1_NAME,
+ 		     "uid: %d ruid: %d suid: %d "
+ 		     "gid: %d rgid: %d sgid: %d\n",
+@@ -114,6 +112,8 @@ splat_cred_test2(struct file *file, void *arg)
+ 	gid_t gid, rgid, sgid, *groups;
+ 	int ngroups, i, count = 0;
+ 
++	crhold(kcred);
++
+ 	uid  = crgetuid(kcred);
+ 	ruid = crgetruid(kcred);
+ 	suid = crgetsuid(kcred);
+@@ -122,7 +122,6 @@ splat_cred_test2(struct file *file, void *arg)
+ 	rgid = crgetrgid(kcred);
+ 	sgid = crgetsgid(kcred);
+ 
+-	crhold(kcred);
+ 	ngroups = crgetngroups(kcred);
+ 	groups  = crgetgroups(kcred);
+ 
+@@ -134,6 +133,7 @@ splat_cred_test2(struct file *file, void *arg)
+ 			splat_vprint(file, SPLAT_CRED_TEST2_NAME,
+ 				     "Failed too many group entries for temp "
+ 				     "buffer: %d, %s\n", ngroups, str);
++			crfree(kcred);
+ 			return -ENOSPC;
+ 		}
+ 	}
diff --git a/linux-4.9.patch b/linux-4.9.patch
new file mode 100644
index 0000000..2bbf3ce
--- /dev/null
+++ b/linux-4.9.patch
@@ -0,0 +1,146 @@
+From ae7eda1dde8aebc298a013254dcd90f7fa42171a Mon Sep 17 00:00:00 2001
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Tue, 18 Oct 2016 17:30:41 -0700
+Subject: [PATCH] Linux 4.9 compat: group_info changes
+
+In Linux 4.9, torvalds/linux at 81243ea, group_info changed from 2d array via
+->blocks to 1d array via ->gid. We change the spl cred functions accordingly.
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Chunwei Chen <david.chen at osnexus.com>
+Closes #581
+---
+ config/spl-build.m4       | 23 +++++++++++++++++++++++
+ include/sys/cred.h        |  5 +++++
+ module/spl/spl-cred.c     | 10 ++++++++++
+ module/splat/splat-cred.c |  5 +++--
+ 4 files changed, 41 insertions(+), 2 deletions(-)
+
+diff --git a/config/spl-build.m4 b/config/spl-build.m4
+index 94e692a..7e2e7a0 100644
+--- a/config/spl-build.m4
++++ b/config/spl-build.m4
+@@ -49,6 +49,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
+ 	SPL_AC_WAIT_ON_BIT
+ 	SPL_AC_INODE_LOCK
+ 	SPL_AC_MUTEX_OWNER
++	SPL_AC_GROUP_INFO_GID
+ ])
+ 
+ AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
+@@ -1574,3 +1575,25 @@ AC_DEFUN([SPL_AC_INODE_LOCK], [
+ 	])
+ 	EXTRA_KCFLAGS="$tmp_flags"
+ ])
++
++dnl #
++dnl # 4.9 API change
++dnl # group_info changed from 2d array via >blocks to 1d array via ->gid
++dnl #
++AC_DEFUN([SPL_AC_GROUP_INFO_GID], [
++	AC_MSG_CHECKING([whether group_info->gid exists])
++	tmp_flags="$EXTRA_KCFLAGS"
++	EXTRA_KCFLAGS="-Werror"
++	SPL_LINUX_TRY_COMPILE([
++		#include <linux/cred.h>
++	],[
++		struct group_info *gi = groups_alloc(1);
++		gi->gid[0] = KGIDT_INIT(0);
++	],[
++		AC_MSG_RESULT(yes)
++		AC_DEFINE(HAVE_GROUP_INFO_GID, 1, [group_info->gid exists])
++	],[
++		AC_MSG_RESULT(no)
++	])
++	EXTRA_KCFLAGS="$tmp_flags"
++])
+diff --git a/include/sys/cred.h b/include/sys/cred.h
+index 58f7aaf..2ad7115 100644
+--- a/include/sys/cred.h
++++ b/include/sys/cred.h
+@@ -34,6 +34,11 @@ typedef struct cred cred_t;
+ #define	kcred		((cred_t *)(init_task.cred))
+ #define	CRED()		((cred_t *)current_cred())
+ 
++/* Linux 4.9 API change, GROUP_AT was removed */
++#ifndef GROUP_AT
++#define	GROUP_AT(gi, i)	((gi)->gid[i])
++#endif
++
+ #ifdef HAVE_KUIDGID_T
+ 
+ #define	KUID_TO_SUID(x)		(__kuid_val(x))
+diff --git a/module/spl/spl-cred.c b/module/spl/spl-cred.c
+index d046f95..1d486c1 100644
+--- a/module/spl/spl-cred.c
++++ b/module/spl/spl-cred.c
+@@ -85,7 +85,9 @@ crgetngroups(const cred_t *cr)
+ 
+ 	gi = cr->group_info;
+ 	rc = gi->ngroups;
++#ifndef HAVE_GROUP_INFO_GID
+ 	/*
++	 * For Linux <= 4.8,
+ 	 * crgetgroups will only returns gi->blocks[0], which contains only
+ 	 * the first NGROUPS_PER_BLOCK groups.
+ 	 */
+@@ -93,12 +95,16 @@ crgetngroups(const cred_t *cr)
+ 		WARN_ON_ONCE(1);
+ 		rc = NGROUPS_PER_BLOCK;
+ 	}
++#endif
+ 	return rc;
+ }
+ 
+ /*
+  * Return an array of supplemental gids.  The returned address is safe
+  * to use as long as the caller has taken a reference with crhold().
++ *
++ * Linux 4.9 API change, group_info changed from 2d array via ->blocks to 1d
++ * array via ->gid.
+  */
+ gid_t *
+ crgetgroups(const cred_t *cr)
+@@ -107,8 +113,12 @@ crgetgroups(const cred_t *cr)
+ 	gid_t *gids = NULL;
+ 
+ 	gi = cr->group_info;
++#ifdef HAVE_GROUP_INFO_GID
++	gids = KGIDP_TO_SGIDP(gi->gid);
++#else
+ 	if (gi->nblocks > 0)
+ 		gids = KGIDP_TO_SGIDP(gi->blocks[0]);
++#endif
+ 	return gids;
+ }
+ 
+diff --git a/module/splat/splat-cred.c b/module/splat/splat-cred.c
+index e3d1c4e..f6b70ce 100644
+--- a/module/splat/splat-cred.c
++++ b/module/splat/splat-cred.c
+@@ -166,6 +166,7 @@ splat_cred_test2(struct file *file, void *arg)
+         return 0;
+ } /* splat_cred_test2() */
+ 
++#define	SPLAT_NGROUPS	32
+ /*
+  * Verify the groupmember() works correctly by constructing an interesting
+  * CRED() and checking that the expected gids are part of it.
+@@ -188,7 +189,7 @@ splat_cred_test3(struct file *file, void *arg)
+ 	 * 1:(NGROUPS_MAX-1).  Gid 0 is explicitly avoided so we can reliably
+ 	 * test for its absence in the test cases.
+ 	 */
+-	gi = groups_alloc(NGROUPS_SMALL);
++	gi = groups_alloc(SPLAT_NGROUPS);
+ 	if (gi == NULL) {
+ 		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Failed create "
+ 		    "group_info for known gids: %d\n", -ENOMEM);
+@@ -196,7 +197,7 @@ splat_cred_test3(struct file *file, void *arg)
+ 		goto show_groups;
+ 	}
+ 
+-	for (i = 0, tmp_gid = known_gid; i < NGROUPS_SMALL; i++) {
++	for (i = 0, tmp_gid = known_gid; i < SPLAT_NGROUPS; i++) {
+ 		splat_vprint(file, SPLAT_CRED_TEST3_NAME, "Adding gid %d "
+ 		    "to current CRED() (%d/%d)\n", tmp_gid, i, gi->ngroups);
+ #ifdef HAVE_KUIDGID_T
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/spl.git/commitdiff/1f0a73c186bcf17575c3c9e0292b02ca2f582b14



More information about the pld-cvs-commit mailing list