1111#include <linux/types.h>
1212#include <linux/sched.h>
1313#include <linux/module.h>
14+ #include <linux/mempool.h>
1415#include <linux/sunrpc/clnt.h>
1516#include <linux/sunrpc/auth.h>
1617#include <linux/user_namespace.h>
1718
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
2419
2520#if IS_ENABLED (CONFIG_SUNRPC_DEBUG )
2621# define RPCDBG_FACILITY RPCDBG_AUTH
2722#endif
2823
2924static struct rpc_auth unix_auth ;
3025static const struct rpc_credops unix_credops ;
26+ static mempool_t * unix_pool ;
3127
3228static struct rpc_auth *
3329unx_create (const struct rpc_auth_create_args * args , struct rpc_clnt * clnt )
@@ -42,15 +38,6 @@ static void
4238unx_destroy (struct rpc_auth * auth )
4339{
4440 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 );
5441}
5542
5643/*
@@ -59,53 +46,24 @@ unx_hash_cred(struct auth_cred *acred, unsigned int hashbits)
5946static struct rpc_cred *
6047unx_lookup_cred (struct rpc_auth * auth , struct auth_cred * acred , int flags )
6148{
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 );
7150
7251 dprintk ("RPC: allocating UNIX cred for uid %d gid %d\n" ,
7352 from_kuid (& init_user_ns , acred -> cred -> fsuid ),
7453 from_kgid (& init_user_ns , acred -> cred -> fsgid ));
7554
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 ;
10258}
10359
10460static void
10561unx_free_cred_callback (struct rcu_head * head )
10662{
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 );
10967}
11068
11169static void
@@ -115,30 +73,32 @@ unx_destroy_cred(struct rpc_cred *cred)
11573}
11674
11775/*
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.
12177 */
12278static 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 )
12480{
125- struct unx_cred * cred = container_of (rcred , struct unx_cred , uc_base );
12681 unsigned int groups = 0 ;
12782 unsigned int i ;
12883
84+ if (cred -> cr_cred == acred -> cred )
85+ return 1 ;
12986
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 ))
13188 return 0 ;
13289
13390 if (acred -> cred && acred -> cred -> group_info != NULL )
13491 groups = acred -> cred -> group_info -> ngroups ;
13592 if (groups > UNX_NGROUPS )
13693 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+
13799 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 ]))
139101 return 0 ;
140- if (groups < UNX_NGROUPS && gid_valid (cred -> uc_gids [groups ]))
141- return 0 ;
142102 return 1 ;
143103}
144104
@@ -150,9 +110,10 @@ static __be32 *
150110unx_marshal (struct rpc_task * task , __be32 * p )
151111{
152112 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 ;
154114 __be32 * base , * hold ;
155115 int i ;
116+ struct group_info * gi = cred -> cr_cred -> group_info ;
156117
157118 * p ++ = htonl (RPC_AUTH_UNIX );
158119 base = p ++ ;
@@ -163,11 +124,12 @@ unx_marshal(struct rpc_task *task, __be32 *p)
163124 */
164125 p = xdr_encode_array (p , clnt -> cl_nodename , clnt -> cl_nodelen );
165126
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 ));
168129 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 ]));
171133 * hold = htonl (p - hold - 1 ); /* gid array length */
172134 * base = htonl ((p - base - 1 ) << 2 ); /* cred length */
173135
@@ -214,12 +176,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
214176
215177int __init rpc_init_authunix (void )
216178{
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 ;
218181}
219182
220183void rpc_destroy_authunix (void )
221184{
222- rpcauth_destroy_credcache ( & unix_auth );
185+ mempool_destroy ( unix_pool );
223186}
224187
225188const struct rpc_authops authunix_ops = {
@@ -228,9 +191,7 @@ const struct rpc_authops authunix_ops = {
228191 .au_name = "UNIX" ,
229192 .create = unx_create ,
230193 .destroy = unx_destroy ,
231- .hash_cred = unx_hash_cred ,
232194 .lookup_cred = unx_lookup_cred ,
233- .crcreate = unx_create_cred ,
234195};
235196
236197static
0 commit comments