]> git.proxmox.com Git - mirror_spl-debian.git/blob - debian/patches/0001-Fix-crgetgroups-out-of-bound-and-misc-cred-fix.patch
56e2bb811222202a4396c58edf5d531b16e9e840
[mirror_spl-debian.git] / debian / patches / 0001-Fix-crgetgroups-out-of-bound-and-misc-cred-fix.patch
1 From: Chunwei Chen <david.chen@osnexus.com>
2 Date: Tue, 18 Oct 2016 15:52:30 -0700
3 Subject: Fix crgetgroups out-of-bound and misc cred fix
4
5 init_groups has 0 nblocks, therefore calling the current crgetgroups with
6 init_groups would result in out-of-bound access. We fix this by returning NULL
7 when nblocks is 0.
8
9 Cap crgetngroups to NGROUPS_PER_BLOCK, since crgetgroups will only return
10 blocks[0].
11
12 Also, remove all get_group_info. The cred already holds reference on the
13 group_info, and cred is not mutable. So there's no reason to hold extra
14 reference, if we hold cred.
15
16 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
17 Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
18 Closes #556
19 ---
20 module/spl/spl-cred.c | 31 ++++++++++++++++---------------
21 1 file changed, 16 insertions(+), 15 deletions(-)
22
23 diff --git a/module/spl/spl-cred.c b/module/spl/spl-cred.c
24 index a03f459..d046f95 100644
25 --- a/module/spl/spl-cred.c
26 +++ b/module/spl/spl-cred.c
27 @@ -62,19 +62,17 @@ cr_groups_search(const struct group_info *group_info, gid_t grp)
28 return 0;
29 }
30
31 -/* Hold a reference on the credential and group info */
32 +/* Hold a reference on the credential */
33 void
34 crhold(cred_t *cr)
35 {
36 (void)get_cred((const cred_t *)cr);
37 - (void)get_group_info(cr->group_info);
38 }
39
40 -/* Free a reference on the credential and group info */
41 +/* Free a reference on the credential */
42 void
43 crfree(cred_t *cr)
44 {
45 - put_group_info(cr->group_info);
46 put_cred((const cred_t *)cr);
47 }
48
49 @@ -85,28 +83,32 @@ crgetngroups(const cred_t *cr)
50 struct group_info *gi;
51 int rc;
52
53 - gi = get_group_info(cr->group_info);
54 + gi = cr->group_info;
55 rc = gi->ngroups;
56 - put_group_info(gi);
57 -
58 + /*
59 + * crgetgroups will only returns gi->blocks[0], which contains only
60 + * the first NGROUPS_PER_BLOCK groups.
61 + */
62 + if (rc > NGROUPS_PER_BLOCK) {
63 + WARN_ON_ONCE(1);
64 + rc = NGROUPS_PER_BLOCK;
65 + }
66 return rc;
67 }
68
69 /*
70 * Return an array of supplemental gids. The returned address is safe
71 * to use as long as the caller has taken a reference with crhold().
72 - * The caller is responsible for releasing the reference with crfree().
73 */
74 gid_t *
75 crgetgroups(const cred_t *cr)
76 {
77 struct group_info *gi;
78 - gid_t *gids;
79 -
80 - gi = get_group_info(cr->group_info);
81 - gids = KGIDP_TO_SGIDP(gi->blocks[0]);
82 - put_group_info(gi);
83 + gid_t *gids = NULL;
84
85 + gi = cr->group_info;
86 + if (gi->nblocks > 0)
87 + gids = KGIDP_TO_SGIDP(gi->blocks[0]);
88 return gids;
89 }
90
91 @@ -117,9 +119,8 @@ groupmember(gid_t gid, const cred_t *cr)
92 struct group_info *gi;
93 int rc;
94
95 - gi = get_group_info(cr->group_info);
96 + gi = cr->group_info;
97 rc = cr_groups_search(gi, SGID_TO_KGID(gid));
98 - put_group_info(gi);
99
100 return rc;
101 }