11
11
#include <linux/types.h>
12
12
#include <linux/sched.h>
13
13
#include <linux/module.h>
14
+ #include <linux/mempool.h>
14
15
#include <linux/sunrpc/clnt.h>
15
16
#include <linux/sunrpc/auth.h>
16
17
#include <linux/user_namespace.h>
17
18
18
- struct unx_cred {
19
- struct rpc_cred uc_base ;
20
- kgid_t uc_gid ;
21
- kgid_t uc_gids [UNX_NGROUPS ];
22
- };
23
- #define uc_uid uc_base.cr_uid
24
19
25
20
#if IS_ENABLED (CONFIG_SUNRPC_DEBUG )
26
21
# define RPCDBG_FACILITY RPCDBG_AUTH
27
22
#endif
28
23
29
24
static struct rpc_auth unix_auth ;
30
25
static const struct rpc_credops unix_credops ;
26
+ static mempool_t * unix_pool ;
31
27
32
28
static struct rpc_auth *
33
29
unx_create (const struct rpc_auth_create_args * args , struct rpc_clnt * clnt )
@@ -42,15 +38,6 @@ static void
42
38
unx_destroy (struct rpc_auth * auth )
43
39
{
44
40
dprintk ("RPC: destroying UNIX authenticator %p\n" , auth );
45
- rpcauth_clear_credcache (auth -> au_credcache );
46
- }
47
-
48
- static int
49
- unx_hash_cred (struct auth_cred * acred , unsigned int hashbits )
50
- {
51
- return hash_64 (from_kgid (& init_user_ns , acred -> cred -> fsgid ) |
52
- ((u64 )from_kuid (& init_user_ns , acred -> cred -> fsuid ) <<
53
- (sizeof (gid_t ) * 8 )), hashbits );
54
41
}
55
42
56
43
/*
@@ -59,53 +46,24 @@ unx_hash_cred(struct auth_cred *acred, unsigned int hashbits)
59
46
static struct rpc_cred *
60
47
unx_lookup_cred (struct rpc_auth * auth , struct auth_cred * acred , int flags )
61
48
{
62
- return rpcauth_lookup_credcache (auth , acred , flags , GFP_NOFS );
63
- }
64
-
65
- static struct rpc_cred *
66
- unx_create_cred (struct rpc_auth * auth , struct auth_cred * acred , int flags , gfp_t gfp )
67
- {
68
- struct unx_cred * cred ;
69
- unsigned int groups = 0 ;
70
- unsigned int i ;
49
+ struct rpc_cred * ret = mempool_alloc (unix_pool , GFP_NOFS );
71
50
72
51
dprintk ("RPC: allocating UNIX cred for uid %d gid %d\n" ,
73
52
from_kuid (& init_user_ns , acred -> cred -> fsuid ),
74
53
from_kgid (& init_user_ns , acred -> cred -> fsgid ));
75
54
76
- if (!(cred = kmalloc (sizeof (* cred ), gfp )))
77
- return ERR_PTR (- ENOMEM );
78
-
79
- rpcauth_init_cred (& cred -> uc_base , acred , auth , & unix_credops );
80
- cred -> uc_base .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE ;
81
-
82
- if (acred -> cred && acred -> cred -> group_info != NULL )
83
- groups = acred -> cred -> group_info -> ngroups ;
84
- if (groups > UNX_NGROUPS )
85
- groups = UNX_NGROUPS ;
86
-
87
- cred -> uc_gid = acred -> cred -> fsgid ;
88
- for (i = 0 ; i < groups ; i ++ )
89
- cred -> uc_gids [i ] = acred -> cred -> group_info -> gid [i ];
90
- if (i < UNX_NGROUPS )
91
- cred -> uc_gids [i ] = INVALID_GID ;
92
-
93
- return & cred -> uc_base ;
94
- }
95
-
96
- static void
97
- unx_free_cred (struct unx_cred * unx_cred )
98
- {
99
- dprintk ("RPC: unx_free_cred %p\n" , unx_cred );
100
- put_cred (unx_cred -> uc_base .cr_cred );
101
- kfree (unx_cred );
55
+ rpcauth_init_cred (ret , acred , auth , & unix_credops );
56
+ ret -> cr_flags = 1UL << RPCAUTH_CRED_UPTODATE ;
57
+ return ret ;
102
58
}
103
59
104
60
static void
105
61
unx_free_cred_callback (struct rcu_head * head )
106
62
{
107
- struct unx_cred * unx_cred = container_of (head , struct unx_cred , uc_base .cr_rcu );
108
- unx_free_cred (unx_cred );
63
+ struct rpc_cred * rpc_cred = container_of (head , struct rpc_cred , cr_rcu );
64
+ dprintk ("RPC: unx_free_cred %p\n" , rpc_cred );
65
+ put_cred (rpc_cred -> cr_cred );
66
+ mempool_free (rpc_cred , unix_pool );
109
67
}
110
68
111
69
static void
@@ -115,30 +73,32 @@ unx_destroy_cred(struct rpc_cred *cred)
115
73
}
116
74
117
75
/*
118
- * Match credentials against current process creds.
119
- * The root_override argument takes care of cases where the caller may
120
- * request root creds (e.g. for NFS swapping).
76
+ * Match credentials against current the auth_cred.
121
77
*/
122
78
static int
123
- unx_match (struct auth_cred * acred , struct rpc_cred * rcred , int flags )
79
+ unx_match (struct auth_cred * acred , struct rpc_cred * cred , int flags )
124
80
{
125
- struct unx_cred * cred = container_of (rcred , struct unx_cred , uc_base );
126
81
unsigned int groups = 0 ;
127
82
unsigned int i ;
128
83
84
+ if (cred -> cr_cred == acred -> cred )
85
+ return 1 ;
129
86
130
- if (!uid_eq (cred -> uc_uid , acred -> cred -> fsuid ) || !gid_eq (cred -> uc_gid , acred -> cred -> fsgid ))
87
+ if (!uid_eq (cred -> cr_cred -> fsuid , acred -> cred -> fsuid ) || !gid_eq (cred -> cr_cred -> fsgid , acred -> cred -> fsgid ))
131
88
return 0 ;
132
89
133
90
if (acred -> cred && acred -> cred -> group_info != NULL )
134
91
groups = acred -> cred -> group_info -> ngroups ;
135
92
if (groups > UNX_NGROUPS )
136
93
groups = UNX_NGROUPS ;
94
+ if (cred -> cr_cred -> group_info == NULL )
95
+ return groups == 0 ;
96
+ if (groups != cred -> cr_cred -> group_info -> ngroups )
97
+ return 0 ;
98
+
137
99
for (i = 0 ; i < groups ; i ++ )
138
- if (!gid_eq (cred -> uc_gids [i ], acred -> cred -> group_info -> gid [i ]))
100
+ if (!gid_eq (cred -> cr_cred -> group_info -> gid [i ], acred -> cred -> group_info -> gid [i ]))
139
101
return 0 ;
140
- if (groups < UNX_NGROUPS && gid_valid (cred -> uc_gids [groups ]))
141
- return 0 ;
142
102
return 1 ;
143
103
}
144
104
@@ -150,9 +110,10 @@ static __be32 *
150
110
unx_marshal (struct rpc_task * task , __be32 * p )
151
111
{
152
112
struct rpc_clnt * clnt = task -> tk_client ;
153
- struct unx_cred * cred = container_of ( task -> tk_rqstp -> rq_cred , struct unx_cred , uc_base ) ;
113
+ struct rpc_cred * cred = task -> tk_rqstp -> rq_cred ;
154
114
__be32 * base , * hold ;
155
115
int i ;
116
+ struct group_info * gi = cred -> cr_cred -> group_info ;
156
117
157
118
* p ++ = htonl (RPC_AUTH_UNIX );
158
119
base = p ++ ;
@@ -163,11 +124,12 @@ unx_marshal(struct rpc_task *task, __be32 *p)
163
124
*/
164
125
p = xdr_encode_array (p , clnt -> cl_nodename , clnt -> cl_nodelen );
165
126
166
- * p ++ = htonl ((u32 ) from_kuid (& init_user_ns , cred -> uc_uid ));
167
- * p ++ = htonl ((u32 ) from_kgid (& init_user_ns , cred -> uc_gid ));
127
+ * p ++ = htonl ((u32 ) from_kuid (& init_user_ns , cred -> cr_cred -> fsuid ));
128
+ * p ++ = htonl ((u32 ) from_kgid (& init_user_ns , cred -> cr_cred -> fsgid ));
168
129
hold = p ++ ;
169
- for (i = 0 ; i < UNX_NGROUPS && gid_valid (cred -> uc_gids [i ]); i ++ )
170
- * p ++ = htonl ((u32 ) from_kgid (& init_user_ns , cred -> uc_gids [i ]));
130
+ if (gi )
131
+ for (i = 0 ; i < UNX_NGROUPS && i < gi -> ngroups ; i ++ )
132
+ * p ++ = htonl ((u32 ) from_kgid (& init_user_ns , gi -> gid [i ]));
171
133
* hold = htonl (p - hold - 1 ); /* gid array length */
172
134
* base = htonl ((p - base - 1 ) << 2 ); /* cred length */
173
135
@@ -214,12 +176,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
214
176
215
177
int __init rpc_init_authunix (void )
216
178
{
217
- return rpcauth_init_credcache (& unix_auth );
179
+ unix_pool = mempool_create_kmalloc_pool (16 , sizeof (struct rpc_cred ));
180
+ return unix_pool ? 0 : - ENOMEM ;
218
181
}
219
182
220
183
void rpc_destroy_authunix (void )
221
184
{
222
- rpcauth_destroy_credcache ( & unix_auth );
185
+ mempool_destroy ( unix_pool );
223
186
}
224
187
225
188
const struct rpc_authops authunix_ops = {
@@ -228,9 +191,7 @@ const struct rpc_authops authunix_ops = {
228
191
.au_name = "UNIX" ,
229
192
.create = unx_create ,
230
193
.destroy = unx_destroy ,
231
- .hash_cred = unx_hash_cred ,
232
194
.lookup_cred = unx_lookup_cred ,
233
- .crcreate = unx_create_cred ,
234
195
};
235
196
236
197
static
0 commit comments