aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/svc.c3
-rw-r--r--fs/nfs/callback.c7
-rw-r--r--fs/nfsd/nfsctl.c16
-rw-r--r--fs/nfsd/nfsd.h2
-rw-r--r--fs/nfsd/nfssvc.c14
-rw-r--r--include/linux/sunrpc/svc_xprt.h4
-rw-r--r--include/linux/sunrpc/svcsock.h3
-rw-r--r--net/sunrpc/svc_xprt.c12
-rw-r--r--net/sunrpc/svcsock.c4
9 files changed, 39 insertions, 26 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 96bb74c919f9..82aa0f35e43d 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -190,12 +190,13 @@ static int create_lockd_listener(struct svc_serv *serv, const char *name,
190 struct net *net, const int family, 190 struct net *net, const int family,
191 const unsigned short port) 191 const unsigned short port)
192{ 192{
193 const struct cred *cred = current_cred();
193 struct svc_xprt *xprt; 194 struct svc_xprt *xprt;
194 195
195 xprt = svc_find_xprt(serv, name, net, family, 0); 196 xprt = svc_find_xprt(serv, name, net, family, 0);
196 if (xprt == NULL) 197 if (xprt == NULL)
197 return svc_create_xprt(serv, name, net, family, port, 198 return svc_create_xprt(serv, name, net, family, port,
198 SVC_SOCK_DEFAULTS); 199 SVC_SOCK_DEFAULTS, cred);
199 svc_xprt_put(xprt); 200 svc_xprt_put(xprt);
200 return 0; 201 return 0;
201} 202}
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 15c9575e0e7a..7817ad94a6ba 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -41,11 +41,13 @@ static struct svc_program nfs4_callback_program;
41 41
42static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net) 42static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net)
43{ 43{
44 const struct cred *cred = current_cred();
44 int ret; 45 int ret;
45 struct nfs_net *nn = net_generic(net, nfs_net_id); 46 struct nfs_net *nn = net_generic(net, nfs_net_id);
46 47
47 ret = svc_create_xprt(serv, "tcp", net, PF_INET, 48 ret = svc_create_xprt(serv, "tcp", net, PF_INET,
48 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); 49 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS,
50 cred);
49 if (ret <= 0) 51 if (ret <= 0)
50 goto out_err; 52 goto out_err;
51 nn->nfs_callback_tcpport = ret; 53 nn->nfs_callback_tcpport = ret;
@@ -53,7 +55,8 @@ static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net)
53 nn->nfs_callback_tcpport, PF_INET, net->ns.inum); 55 nn->nfs_callback_tcpport, PF_INET, net->ns.inum);
54 56
55 ret = svc_create_xprt(serv, "tcp", net, PF_INET6, 57 ret = svc_create_xprt(serv, "tcp", net, PF_INET6,
56 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); 58 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS,
59 cred);
57 if (ret > 0) { 60 if (ret > 0) {
58 nn->nfs_callback_tcpport6 = ret; 61 nn->nfs_callback_tcpport6 = ret;
59 dprintk("NFS: Callback listener port = %u (af %u, net %x)\n", 62 dprintk("NFS: Callback listener port = %u (af %u, net %x)\n",
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 630d629090be..90972e1fd785 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -439,7 +439,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
439 return rv; 439 return rv;
440 if (newthreads < 0) 440 if (newthreads < 0)
441 return -EINVAL; 441 return -EINVAL;
442 rv = nfsd_svc(newthreads, net); 442 rv = nfsd_svc(newthreads, net, file->f_cred);
443 if (rv < 0) 443 if (rv < 0)
444 return rv; 444 return rv;
445 } else 445 } else
@@ -717,7 +717,7 @@ static ssize_t __write_ports_names(char *buf, struct net *net)
717 * a socket of a supported family/protocol, and we use it as an 717 * a socket of a supported family/protocol, and we use it as an
718 * nfsd listener. 718 * nfsd listener.
719 */ 719 */
720static ssize_t __write_ports_addfd(char *buf, struct net *net) 720static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred *cred)
721{ 721{
722 char *mesg = buf; 722 char *mesg = buf;
723 int fd, err; 723 int fd, err;
@@ -736,7 +736,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net)
736 if (err != 0) 736 if (err != 0)
737 return err; 737 return err;
738 738
739 err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 739 err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
740 if (err < 0) { 740 if (err < 0) {
741 nfsd_destroy(net); 741 nfsd_destroy(net);
742 return err; 742 return err;
@@ -751,7 +751,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net)
751 * A transport listener is added by writing it's transport name and 751 * A transport listener is added by writing it's transport name and
752 * a port number. 752 * a port number.
753 */ 753 */
754static ssize_t __write_ports_addxprt(char *buf, struct net *net) 754static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cred *cred)
755{ 755{
756 char transport[16]; 756 char transport[16];
757 struct svc_xprt *xprt; 757 struct svc_xprt *xprt;
@@ -769,12 +769,12 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net)
769 return err; 769 return err;
770 770
771 err = svc_create_xprt(nn->nfsd_serv, transport, net, 771 err = svc_create_xprt(nn->nfsd_serv, transport, net,
772 PF_INET, port, SVC_SOCK_ANONYMOUS); 772 PF_INET, port, SVC_SOCK_ANONYMOUS, cred);
773 if (err < 0) 773 if (err < 0)
774 goto out_err; 774 goto out_err;
775 775
776 err = svc_create_xprt(nn->nfsd_serv, transport, net, 776 err = svc_create_xprt(nn->nfsd_serv, transport, net,
777 PF_INET6, port, SVC_SOCK_ANONYMOUS); 777 PF_INET6, port, SVC_SOCK_ANONYMOUS, cred);
778 if (err < 0 && err != -EAFNOSUPPORT) 778 if (err < 0 && err != -EAFNOSUPPORT)
779 goto out_close; 779 goto out_close;
780 780
@@ -799,10 +799,10 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size,
799 return __write_ports_names(buf, net); 799 return __write_ports_names(buf, net);
800 800
801 if (isdigit(buf[0])) 801 if (isdigit(buf[0]))
802 return __write_ports_addfd(buf, net); 802 return __write_ports_addfd(buf, net, file->f_cred);
803 803
804 if (isalpha(buf[0])) 804 if (isalpha(buf[0]))
805 return __write_ports_addxprt(buf, net); 805 return __write_ports_addxprt(buf, net, file->f_cred);
806 806
807 return -EINVAL; 807 return -EINVAL;
808} 808}
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 6bae2554b2b2..d200c8680259 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -73,7 +73,7 @@ extern const struct seq_operations nfs_exports_op;
73/* 73/*
74 * Function prototypes. 74 * Function prototypes.
75 */ 75 */
76int nfsd_svc(int nrservs, struct net *net); 76int nfsd_svc(int nrservs, struct net *net, const struct cred *cred);
77int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); 77int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
78 78
79int nfsd_nrthreads(struct net *); 79int nfsd_nrthreads(struct net *);
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 520757774614..32e4d8a334e3 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -283,7 +283,7 @@ int nfsd_nrthreads(struct net *net)
283 return rv; 283 return rv;
284} 284}
285 285
286static int nfsd_init_socks(struct net *net) 286static int nfsd_init_socks(struct net *net, const struct cred *cred)
287{ 287{
288 int error; 288 int error;
289 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 289 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
@@ -292,12 +292,12 @@ static int nfsd_init_socks(struct net *net)
292 return 0; 292 return 0;
293 293
294 error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT, 294 error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT,
295 SVC_SOCK_DEFAULTS); 295 SVC_SOCK_DEFAULTS, cred);
296 if (error < 0) 296 if (error < 0)
297 return error; 297 return error;
298 298
299 error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT, 299 error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT,
300 SVC_SOCK_DEFAULTS); 300 SVC_SOCK_DEFAULTS, cred);
301 if (error < 0) 301 if (error < 0)
302 return error; 302 return error;
303 303
@@ -348,7 +348,7 @@ static bool nfsd_needs_lockd(struct nfsd_net *nn)
348 return nfsd_vers(nn, 2, NFSD_TEST) || nfsd_vers(nn, 3, NFSD_TEST); 348 return nfsd_vers(nn, 2, NFSD_TEST) || nfsd_vers(nn, 3, NFSD_TEST);
349} 349}
350 350
351static int nfsd_startup_net(int nrservs, struct net *net) 351static int nfsd_startup_net(int nrservs, struct net *net, const struct cred *cred)
352{ 352{
353 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 353 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
354 int ret; 354 int ret;
@@ -359,7 +359,7 @@ static int nfsd_startup_net(int nrservs, struct net *net)
359 ret = nfsd_startup_generic(nrservs); 359 ret = nfsd_startup_generic(nrservs);
360 if (ret) 360 if (ret)
361 return ret; 361 return ret;
362 ret = nfsd_init_socks(net); 362 ret = nfsd_init_socks(net, cred);
363 if (ret) 363 if (ret)
364 goto out_socks; 364 goto out_socks;
365 365
@@ -697,7 +697,7 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
697 * this is the first time nrservs is nonzero. 697 * this is the first time nrservs is nonzero.
698 */ 698 */
699int 699int
700nfsd_svc(int nrservs, struct net *net) 700nfsd_svc(int nrservs, struct net *net, const struct cred *cred)
701{ 701{
702 int error; 702 int error;
703 bool nfsd_up_before; 703 bool nfsd_up_before;
@@ -719,7 +719,7 @@ nfsd_svc(int nrservs, struct net *net)
719 719
720 nfsd_up_before = nn->nfsd_net_up; 720 nfsd_up_before = nn->nfsd_net_up;
721 721
722 error = nfsd_startup_net(nrservs, net); 722 error = nfsd_startup_net(nrservs, net, cred);
723 if (error) 723 if (error)
724 goto out_destroy; 724 goto out_destroy;
725 error = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv, 725 error = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index b3f9577e17d6..ea6f46be9cb7 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -86,6 +86,7 @@ struct svc_xprt {
86 struct list_head xpt_users; /* callbacks on free */ 86 struct list_head xpt_users; /* callbacks on free */
87 87
88 struct net *xpt_net; 88 struct net *xpt_net;
89 const struct cred *xpt_cred;
89 struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */ 90 struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */
90 struct rpc_xprt_switch *xpt_bc_xps; /* NFSv4.1 backchannel */ 91 struct rpc_xprt_switch *xpt_bc_xps; /* NFSv4.1 backchannel */
91}; 92};
@@ -119,7 +120,8 @@ void svc_unreg_xprt_class(struct svc_xprt_class *);
119void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *, 120void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
120 struct svc_serv *); 121 struct svc_serv *);
121int svc_create_xprt(struct svc_serv *, const char *, struct net *, 122int svc_create_xprt(struct svc_serv *, const char *, struct net *,
122 const int, const unsigned short, int); 123 const int, const unsigned short, int,
124 const struct cred *);
123void svc_xprt_do_enqueue(struct svc_xprt *xprt); 125void svc_xprt_do_enqueue(struct svc_xprt *xprt);
124void svc_xprt_enqueue(struct svc_xprt *xprt); 126void svc_xprt_enqueue(struct svc_xprt *xprt);
125void svc_xprt_put(struct svc_xprt *xprt); 127void svc_xprt_put(struct svc_xprt *xprt);
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 119718a922f2..771baadaee9d 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -59,7 +59,8 @@ void svc_drop(struct svc_rqst *);
59void svc_sock_update_bufs(struct svc_serv *serv); 59void svc_sock_update_bufs(struct svc_serv *serv);
60bool svc_alien_sock(struct net *net, int fd); 60bool svc_alien_sock(struct net *net, int fd);
61int svc_addsock(struct svc_serv *serv, const int fd, 61int svc_addsock(struct svc_serv *serv, const int fd,
62 char *name_return, const size_t len); 62 char *name_return, const size_t len,
63 const struct cred *cred);
63void svc_init_xprt_sock(void); 64void svc_init_xprt_sock(void);
64void svc_cleanup_xprt_sock(void); 65void svc_cleanup_xprt_sock(void);
65struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot); 66struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 61530b1b7754..b76ee83d4d43 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -136,6 +136,7 @@ static void svc_xprt_free(struct kref *kref)
136 struct module *owner = xprt->xpt_class->xcl_owner; 136 struct module *owner = xprt->xpt_class->xcl_owner;
137 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) 137 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags))
138 svcauth_unix_info_release(xprt); 138 svcauth_unix_info_release(xprt);
139 put_cred(xprt->xpt_cred);
139 put_net(xprt->xpt_net); 140 put_net(xprt->xpt_net);
140 /* See comment on corresponding get in xs_setup_bc_tcp(): */ 141 /* See comment on corresponding get in xs_setup_bc_tcp(): */
141 if (xprt->xpt_bc_xprt) 142 if (xprt->xpt_bc_xprt)
@@ -252,7 +253,8 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new)
252 253
253static int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name, 254static int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
254 struct net *net, const int family, 255 struct net *net, const int family,
255 const unsigned short port, int flags) 256 const unsigned short port, int flags,
257 const struct cred *cred)
256{ 258{
257 struct svc_xprt_class *xcl; 259 struct svc_xprt_class *xcl;
258 260
@@ -273,6 +275,7 @@ static int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
273 module_put(xcl->xcl_owner); 275 module_put(xcl->xcl_owner);
274 return PTR_ERR(newxprt); 276 return PTR_ERR(newxprt);
275 } 277 }
278 newxprt->xpt_cred = get_cred(cred);
276 svc_add_new_perm_xprt(serv, newxprt); 279 svc_add_new_perm_xprt(serv, newxprt);
277 newport = svc_xprt_local_port(newxprt); 280 newport = svc_xprt_local_port(newxprt);
278 return newport; 281 return newport;
@@ -286,15 +289,16 @@ static int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
286 289
287int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, 290int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
288 struct net *net, const int family, 291 struct net *net, const int family,
289 const unsigned short port, int flags) 292 const unsigned short port, int flags,
293 const struct cred *cred)
290{ 294{
291 int err; 295 int err;
292 296
293 dprintk("svc: creating transport %s[%d]\n", xprt_name, port); 297 dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
294 err = _svc_create_xprt(serv, xprt_name, net, family, port, flags); 298 err = _svc_create_xprt(serv, xprt_name, net, family, port, flags, cred);
295 if (err == -EPROTONOSUPPORT) { 299 if (err == -EPROTONOSUPPORT) {
296 request_module("svc%s", xprt_name); 300 request_module("svc%s", xprt_name);
297 err = _svc_create_xprt(serv, xprt_name, net, family, port, flags); 301 err = _svc_create_xprt(serv, xprt_name, net, family, port, flags, cred);
298 } 302 }
299 if (err < 0) 303 if (err < 0)
300 dprintk("svc: transport %s not found, err %d\n", 304 dprintk("svc: transport %s not found, err %d\n",
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 43590a968b73..540fde2804d0 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1332,13 +1332,14 @@ EXPORT_SYMBOL_GPL(svc_alien_sock);
1332 * @fd: file descriptor of the new listener 1332 * @fd: file descriptor of the new listener
1333 * @name_return: pointer to buffer to fill in with name of listener 1333 * @name_return: pointer to buffer to fill in with name of listener
1334 * @len: size of the buffer 1334 * @len: size of the buffer
1335 * @cred: credential
1335 * 1336 *
1336 * Fills in socket name and returns positive length of name if successful. 1337 * Fills in socket name and returns positive length of name if successful.
1337 * Name is terminated with '\n'. On error, returns a negative errno 1338 * Name is terminated with '\n'. On error, returns a negative errno
1338 * value. 1339 * value.
1339 */ 1340 */
1340int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, 1341int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
1341 const size_t len) 1342 const size_t len, const struct cred *cred)
1342{ 1343{
1343 int err = 0; 1344 int err = 0;
1344 struct socket *so = sockfd_lookup(fd, &err); 1345 struct socket *so = sockfd_lookup(fd, &err);
@@ -1371,6 +1372,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
1371 salen = kernel_getsockname(svsk->sk_sock, sin); 1372 salen = kernel_getsockname(svsk->sk_sock, sin);
1372 if (salen >= 0) 1373 if (salen >= 0)
1373 svc_xprt_set_local(&svsk->sk_xprt, sin, salen); 1374 svc_xprt_set_local(&svsk->sk_xprt, sin, salen);
1375 svsk->sk_xprt.xpt_cred = get_cred(cred);
1374 svc_add_new_perm_xprt(serv, &svsk->sk_xprt); 1376 svc_add_new_perm_xprt(serv, &svsk->sk_xprt);
1375 return svc_one_sock_name(svsk, name_return, len); 1377 return svc_one_sock_name(svsk, name_return, len);
1376out: 1378out: