~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/sunrpc/auth_unix.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /net/sunrpc/auth_unix.c (Version linux-6.12-rc7) and /net/sunrpc/auth_unix.c (Version linux-4.14.336)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2 /*                                                  2 /*
  3  * linux/net/sunrpc/auth_unix.c                     3  * linux/net/sunrpc/auth_unix.c
  4  *                                                  4  *
  5  * UNIX-style authentication; no AUTH_SHORT su      5  * UNIX-style authentication; no AUTH_SHORT support
  6  *                                                  6  *
  7  * Copyright (C) 1996, Olaf Kirch <okir@monad.      7  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  8  */                                                 8  */
  9                                                     9 
 10 #include <linux/slab.h>                            10 #include <linux/slab.h>
 11 #include <linux/types.h>                           11 #include <linux/types.h>
 12 #include <linux/sched.h>                           12 #include <linux/sched.h>
 13 #include <linux/module.h>                          13 #include <linux/module.h>
 14 #include <linux/mempool.h>                     << 
 15 #include <linux/sunrpc/clnt.h>                     14 #include <linux/sunrpc/clnt.h>
 16 #include <linux/sunrpc/auth.h>                     15 #include <linux/sunrpc/auth.h>
 17 #include <linux/user_namespace.h>                  16 #include <linux/user_namespace.h>
 18                                                    17 
                                                   >>  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
 19                                                    24 
 20 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)                25 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 21 # define RPCDBG_FACILITY        RPCDBG_AUTH        26 # define RPCDBG_FACILITY        RPCDBG_AUTH
 22 #endif                                             27 #endif
 23                                                    28 
 24 static struct rpc_auth          unix_auth;         29 static struct rpc_auth          unix_auth;
 25 static const struct rpc_credops unix_credops;      30 static const struct rpc_credops unix_credops;
 26 static mempool_t                *unix_pool;    << 
 27                                                    31 
 28 static struct rpc_auth *                           32 static struct rpc_auth *
 29 unx_create(const struct rpc_auth_create_args * !!  33 unx_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
 30 {                                                  34 {
 31         refcount_inc(&unix_auth.au_count);     !!  35         dprintk("RPC:       creating UNIX authenticator for client %p\n",
                                                   >>  36                         clnt);
                                                   >>  37         atomic_inc(&unix_auth.au_count);
 32         return &unix_auth;                         38         return &unix_auth;
 33 }                                                  39 }
 34                                                    40 
 35 static void                                        41 static void
 36 unx_destroy(struct rpc_auth *auth)                 42 unx_destroy(struct rpc_auth *auth)
 37 {                                                  43 {
                                                   >>  44         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->gid) |
                                                   >>  52                 ((u64)from_kuid(&init_user_ns, acred->uid) <<
                                                   >>  53                         (sizeof(gid_t) * 8)), hashbits);
 38 }                                                  54 }
 39                                                    55 
 40 /*                                                 56 /*
 41  * Lookup AUTH_UNIX creds for current process      57  * Lookup AUTH_UNIX creds for current process
 42  */                                                58  */
 43 static struct rpc_cred *unx_lookup_cred(struct !!  59 static struct rpc_cred *
 44                                         struct !!  60 unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 45 {                                                  61 {
 46         struct rpc_cred *ret;                  !!  62         return rpcauth_lookup_credcache(auth, acred, flags, GFP_NOFS);
                                                   >>  63 }
 47                                                    64 
 48         ret = kmalloc(sizeof(*ret), rpc_task_g !!  65 static struct rpc_cred *
 49         if (!ret) {                            !!  66 unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t gfp)
 50                 if (!(flags & RPCAUTH_LOOKUP_A !!  67 {
 51                         return ERR_PTR(-ENOMEM !!  68         struct unx_cred *cred;
 52                 ret = mempool_alloc(unix_pool, !!  69         unsigned int groups = 0;
 53                 if (!ret)                      !!  70         unsigned int i;
 54                         return ERR_PTR(-ENOMEM !!  71 
 55         }                                      !!  72         dprintk("RPC:       allocating UNIX cred for uid %d gid %d\n",
 56         rpcauth_init_cred(ret, acred, auth, &u !!  73                         from_kuid(&init_user_ns, acred->uid),
 57         ret->cr_flags = 1UL << RPCAUTH_CRED_UP !!  74                         from_kgid(&init_user_ns, acred->gid));
 58         return ret;                            !!  75 
                                                   >>  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->group_info != NULL)
                                                   >>  83                 groups = acred->group_info->ngroups;
                                                   >>  84         if (groups > UNX_NGROUPS)
                                                   >>  85                 groups = UNX_NGROUPS;
                                                   >>  86 
                                                   >>  87         cred->uc_gid = acred->gid;
                                                   >>  88         for (i = 0; i < groups; i++)
                                                   >>  89                 cred->uc_gids[i] = acred->group_info->gid[i];
                                                   >>  90         if (i < UNX_NGROUPS)
                                                   >>  91                 cred->uc_gids[i] = INVALID_GID;
                                                   >>  92 
                                                   >>  93         return &cred->uc_base;
 59 }                                                  94 }
 60                                                    95 
 61 static void                                        96 static void
 62 unx_free_cred_callback(struct rcu_head *head)  !!  97 unx_free_cred(struct unx_cred *unx_cred)
 63 {                                                  98 {
 64         struct rpc_cred *rpc_cred = container_ !!  99         dprintk("RPC:       unx_free_cred %p\n", unx_cred);
                                                   >> 100         kfree(unx_cred);
                                                   >> 101 }
 65                                                   102 
 66         put_cred(rpc_cred->cr_cred);           !! 103 static void
 67         mempool_free(rpc_cred, unix_pool);     !! 104 unx_free_cred_callback(struct rcu_head *head)
                                                   >> 105 {
                                                   >> 106         struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
                                                   >> 107         unx_free_cred(unx_cred);
 68 }                                                 108 }
 69                                                   109 
 70 static void                                       110 static void
 71 unx_destroy_cred(struct rpc_cred *cred)           111 unx_destroy_cred(struct rpc_cred *cred)
 72 {                                                 112 {
 73         call_rcu(&cred->cr_rcu, unx_free_cred_    113         call_rcu(&cred->cr_rcu, unx_free_cred_callback);
 74 }                                                 114 }
 75                                                   115 
 76 /*                                                116 /*
 77  * Match credentials against current the auth_ !! 117  * Match credentials against current process creds.
                                                   >> 118  * The root_override argument takes care of cases where the caller may
                                                   >> 119  * request root creds (e.g. for NFS swapping).
 78  */                                               120  */
 79 static int                                        121 static int
 80 unx_match(struct auth_cred *acred, struct rpc_ !! 122 unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 81 {                                                 123 {
                                                   >> 124         struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
 82         unsigned int groups = 0;                  125         unsigned int groups = 0;
 83         unsigned int i;                           126         unsigned int i;
 84                                                   127 
 85         if (cred->cr_cred == acred->cred)      << 
 86                 return 1;                      << 
 87                                                   128 
 88         if (!uid_eq(cred->cr_cred->fsuid, acre !! 129         if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
 89                 return 0;                         130                 return 0;
 90                                                   131 
 91         if (acred->cred->group_info != NULL)   !! 132         if (acred->group_info != NULL)
 92                 groups = acred->cred->group_in !! 133                 groups = acred->group_info->ngroups;
 93         if (groups > UNX_NGROUPS)                 134         if (groups > UNX_NGROUPS)
 94                 groups = UNX_NGROUPS;             135                 groups = UNX_NGROUPS;
 95         if (cred->cr_cred->group_info == NULL) << 
 96                 return groups == 0;            << 
 97         if (groups != cred->cr_cred->group_inf << 
 98                 return 0;                      << 
 99                                                << 
100         for (i = 0; i < groups ; i++)             136         for (i = 0; i < groups ; i++)
101                 if (!gid_eq(cred->cr_cred->gro !! 137                 if (!gid_eq(cred->uc_gids[i], acred->group_info->gid[i]))
102                         return 0;                 138                         return 0;
                                                   >> 139         if (groups < UNX_NGROUPS && gid_valid(cred->uc_gids[groups]))
                                                   >> 140                 return 0;
103         return 1;                                 141         return 1;
104 }                                                 142 }
105                                                   143 
106 /*                                                144 /*
107  * Marshal credentials.                           145  * Marshal credentials.
108  * Maybe we should keep a cached credential fo    146  * Maybe we should keep a cached credential for performance reasons.
109  */                                               147  */
110 static int                                     !! 148 static __be32 *
111 unx_marshal(struct rpc_task *task, struct xdr_ !! 149 unx_marshal(struct rpc_task *task, __be32 *p)
112 {                                                 150 {
113         struct rpc_clnt *clnt = task->tk_clien    151         struct rpc_clnt *clnt = task->tk_client;
114         struct rpc_cred *cred = task->tk_rqstp !! 152         struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
115         __be32          *p, *cred_len, *gidarr !! 153         __be32          *base, *hold;
116         int             i;                        154         int             i;
117         struct group_info *gi = cred->cr_cred- << 
118         struct user_namespace *userns = clnt-> << 
119                 clnt->cl_cred->user_ns : &init << 
120                                                << 
121         /* Credential */                       << 
122                                                << 
123         p = xdr_reserve_space(xdr, 3 * sizeof( << 
124         if (!p)                                << 
125                 goto marshal_failed;           << 
126         *p++ = rpc_auth_unix;                  << 
127         cred_len = p++;                        << 
128         *p++ = xdr_zero;        /* stamp */    << 
129         if (xdr_stream_encode_opaque(xdr, clnt << 
130                                      clnt->cl_ << 
131                 goto marshal_failed;           << 
132         p = xdr_reserve_space(xdr, 3 * sizeof( << 
133         if (!p)                                << 
134                 goto marshal_failed;           << 
135         *p++ = cpu_to_be32(from_kuid_munged(us << 
136         *p++ = cpu_to_be32(from_kgid_munged(us << 
137                                                << 
138         gidarr_len = p++;                      << 
139         if (gi)                                << 
140                 for (i = 0; i < UNX_NGROUPS && << 
141                         *p++ = cpu_to_be32(fro << 
142         *gidarr_len = cpu_to_be32(p - gidarr_l << 
143         *cred_len = cpu_to_be32((p - cred_len  << 
144         p = xdr_reserve_space(xdr, (p - gidarr << 
145         if (!p)                                << 
146                 goto marshal_failed;           << 
147                                                << 
148         /* Verifier */                         << 
149                                                << 
150         p = xdr_reserve_space(xdr, 2 * sizeof( << 
151         if (!p)                                << 
152                 goto marshal_failed;           << 
153         *p++ = rpc_auth_null;                  << 
154         *p   = xdr_zero;                       << 
155                                                   155 
156         return 0;                              !! 156         *p++ = htonl(RPC_AUTH_UNIX);
                                                   >> 157         base = p++;
                                                   >> 158         *p++ = htonl(jiffies/HZ);
                                                   >> 159 
                                                   >> 160         /*
                                                   >> 161          * Copy the UTS nodename captured when the client was created.
                                                   >> 162          */
                                                   >> 163         p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
                                                   >> 164 
                                                   >> 165         *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
                                                   >> 166         *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
                                                   >> 167         hold = p++;
                                                   >> 168         for (i = 0; i < UNX_NGROUPS && gid_valid(cred->uc_gids[i]); i++)
                                                   >> 169                 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
                                                   >> 170         *hold = htonl(p - hold - 1);            /* gid array length */
                                                   >> 171         *base = htonl((p - base - 1) << 2);     /* cred length */
                                                   >> 172 
                                                   >> 173         *p++ = htonl(RPC_AUTH_NULL);
                                                   >> 174         *p++ = htonl(0);
157                                                   175 
158 marshal_failed:                                !! 176         return p;
159         return -EMSGSIZE;                      << 
160 }                                                 177 }
161                                                   178 
162 /*                                                179 /*
163  * Refresh credentials. This is a no-op for AU    180  * Refresh credentials. This is a no-op for AUTH_UNIX
164  */                                               181  */
165 static int                                        182 static int
166 unx_refresh(struct rpc_task *task)                183 unx_refresh(struct rpc_task *task)
167 {                                                 184 {
168         set_bit(RPCAUTH_CRED_UPTODATE, &task->    185         set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
169         return 0;                                 186         return 0;
170 }                                                 187 }
171                                                   188 
172 static int                                     !! 189 static __be32 *
173 unx_validate(struct rpc_task *task, struct xdr !! 190 unx_validate(struct rpc_task *task, __be32 *p)
174 {                                                 191 {
175         struct rpc_auth *auth = task->tk_rqstp !! 192         rpc_authflavor_t        flavor;
176         __be32 *p;                             !! 193         u32                     size;
177         u32 size;                              !! 194 
178                                                !! 195         flavor = ntohl(*p++);
179         p = xdr_inline_decode(xdr, 2 * sizeof( !! 196         if (flavor != RPC_AUTH_NULL &&
180         if (!p)                                !! 197             flavor != RPC_AUTH_UNIX &&
181                 return -EIO;                   !! 198             flavor != RPC_AUTH_SHORT) {
182         switch (*p++) {                        !! 199                 printk("RPC: bad verf flavor: %u\n", flavor);
183         case rpc_auth_null:                    !! 200                 return ERR_PTR(-EIO);
184         case rpc_auth_unix:                    << 
185         case rpc_auth_short:                   << 
186                 break;                         << 
187         default:                               << 
188                 return -EIO;                   << 
189         }                                         201         }
190         size = be32_to_cpup(p);                !! 202 
191         if (size > RPC_MAX_AUTH_SIZE)          !! 203         size = ntohl(*p++);
192                 return -EIO;                   !! 204         if (size > RPC_MAX_AUTH_SIZE) {
193         p = xdr_inline_decode(xdr, size);      !! 205                 printk("RPC: giant verf size: %u\n", size);
194         if (!p)                                !! 206                 return ERR_PTR(-EIO);
195                 return -EIO;                   !! 207         }
196                                                !! 208         task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
197         auth->au_verfsize = XDR_QUADLEN(size)  !! 209         p += (size >> 2);
198         auth->au_rslack = XDR_QUADLEN(size) +  !! 210 
199         auth->au_ralign = XDR_QUADLEN(size) +  !! 211         return p;
200         return 0;                              << 
201 }                                                 212 }
202                                                   213 
203 int __init rpc_init_authunix(void)                214 int __init rpc_init_authunix(void)
204 {                                                 215 {
205         unix_pool = mempool_create_kmalloc_poo !! 216         return rpcauth_init_credcache(&unix_auth);
206         return unix_pool ? 0 : -ENOMEM;        << 
207 }                                                 217 }
208                                                   218 
209 void rpc_destroy_authunix(void)                   219 void rpc_destroy_authunix(void)
210 {                                                 220 {
211         mempool_destroy(unix_pool);            !! 221         rpcauth_destroy_credcache(&unix_auth);
212 }                                                 222 }
213                                                   223 
214 const struct rpc_authops authunix_ops = {         224 const struct rpc_authops authunix_ops = {
215         .owner          = THIS_MODULE,            225         .owner          = THIS_MODULE,
216         .au_flavor      = RPC_AUTH_UNIX,          226         .au_flavor      = RPC_AUTH_UNIX,
217         .au_name        = "UNIX",                 227         .au_name        = "UNIX",
218         .create         = unx_create,             228         .create         = unx_create,
219         .destroy        = unx_destroy,            229         .destroy        = unx_destroy,
                                                   >> 230         .hash_cred      = unx_hash_cred,
220         .lookup_cred    = unx_lookup_cred,        231         .lookup_cred    = unx_lookup_cred,
                                                   >> 232         .crcreate       = unx_create_cred,
221 };                                                233 };
222                                                   234 
223 static                                            235 static
224 struct rpc_auth         unix_auth = {             236 struct rpc_auth         unix_auth = {
225         .au_cslack      = UNX_CALLSLACK,          237         .au_cslack      = UNX_CALLSLACK,
226         .au_rslack      = NUL_REPLYSLACK,         238         .au_rslack      = NUL_REPLYSLACK,
227         .au_verfsize    = NUL_REPLYSLACK,      !! 239         .au_flags       = RPCAUTH_AUTH_NO_CRKEY_TIMEOUT,
228         .au_ops         = &authunix_ops,          240         .au_ops         = &authunix_ops,
229         .au_flavor      = RPC_AUTH_UNIX,          241         .au_flavor      = RPC_AUTH_UNIX,
230         .au_count       = REFCOUNT_INIT(1),    !! 242         .au_count       = ATOMIC_INIT(0),
231 };                                                243 };
232                                                   244 
233 static                                            245 static
234 const struct rpc_credops unix_credops = {         246 const struct rpc_credops unix_credops = {
235         .cr_name        = "AUTH_UNIX",            247         .cr_name        = "AUTH_UNIX",
236         .crdestroy      = unx_destroy_cred,       248         .crdestroy      = unx_destroy_cred,
                                                   >> 249         .crbind         = rpcauth_generic_bind_cred,
237         .crmatch        = unx_match,              250         .crmatch        = unx_match,
238         .crmarshal      = unx_marshal,            251         .crmarshal      = unx_marshal,
239         .crwrap_req     = rpcauth_wrap_req_enc << 
240         .crrefresh      = unx_refresh,            252         .crrefresh      = unx_refresh,
241         .crvalidate     = unx_validate,           253         .crvalidate     = unx_validate,
242         .crunwrap_resp  = rpcauth_unwrap_resp_ << 
243 };                                                254 };
244                                                   255 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php