[Pkg-zfsonlinux-devel] [SCM] spl branch, master, updated. debian/0.6.5.7-1-20-g6590a5e
Aron Xu
aron at debian.org
Tue Jan 17 14:44:36 UTC 2017
The following commit has been merged in the master branch:
commit 6590a5ea4cd7b0098d886dbeaec8096d41980d43
Author: Aron Xu <aron at debian.org>
Date: Tue Jan 17 22:43:41 2017 +0800
Fix Linux 4.9 compatibility (Closes: #851352)
diff --git a/debian/changelog b/debian/changelog
index efb0c17..c6ced62 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+spl-linux (0.6.5.8-3) unstable; urgency=medium
+
+ * Fix Linux 4.9 compatibility (Closes: #851352)
+ Thanks to Fabian Grünbichler!
+
+ -- Aron Xu <aron at debian.org> Tue, 17 Jan 2017 20:57:13 +0800
+
spl-linux (0.6.5.8-2) unstable; urgency=medium
[ Petter Reinholdtsen ]
diff --git a/debian/patches/0001-Fix-crgetgroups-out-of-bound-and-misc-cred-fix.patch b/debian/patches/0001-Fix-crgetgroups-out-of-bound-and-misc-cred-fix.patch
new file mode 100644
index 0000000..56e2bb8
--- /dev/null
+++ b/debian/patches/0001-Fix-crgetgroups-out-of-bound-and-misc-cred-fix.patch
@@ -0,0 +1,101 @@
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Tue, 18 Oct 2016 15:52:30 -0700
+Subject: 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/debian/patches/0002-Fix-splat-cred.c-cred-usage.patch b/debian/patches/0002-Fix-splat-cred.c-cred-usage.patch
new file mode 100644
index 0000000..2ff9018
--- /dev/null
+++ b/debian/patches/0002-Fix-splat-cred.c-cred-usage.patch
@@ -0,0 +1,79 @@
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Tue, 18 Oct 2016 17:29:26 -0700
+Subject: 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/debian/patches/0003-Linux-4.9-compat-group_info-changes.patch b/debian/patches/0003-Linux-4.9-compat-group_info-changes.patch
new file mode 100644
index 0000000..79b3fa8
--- /dev/null
+++ b/debian/patches/0003-Linux-4.9-compat-group_info-changes.patch
@@ -0,0 +1,145 @@
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Tue, 18 Oct 2016 17:30:41 -0700
+Subject: 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 c401fd8..5a2f1de 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_MUTEX_OWNER], [
+ ])
+ 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 4f62b00..480e268 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
+
+ /*
+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
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..13b420c
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,3 @@
+0001-Fix-crgetgroups-out-of-bound-and-misc-cred-fix.patch
+0002-Fix-splat-cred.c-cred-usage.patch
+0003-Linux-4.9-compat-group_info-changes.patch
--
Solaris Porting Layer for Linux
More information about the Pkg-zfsonlinux-devel
mailing list