summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2001-12-31 17:45:16 +0000
committerrwatson <rwatson@FreeBSD.org>2001-12-31 17:45:16 +0000
commit5eea21cccab61c0a7e31c0025f3f57feeb99870a (patch)
tree7c8b2985310180ddd6c0718cf693e5b928d63555
parent25ebb0c5b897fa6d9c618e7d9ced3a63510278d1 (diff)
downloadFreeBSD-src-5eea21cccab61c0a7e31c0025f3f57feeb99870a.zip
FreeBSD-src-5eea21cccab61c0a7e31c0025f3f57feeb99870a.tar.gz
o Make the credential used by socreate() an explicit argument to
socreate(), rather than getting it implicitly from the thread argument. o Make NFS cache the credential provided at mount-time, and use the cached credential (nfsmount->nm_cred) when making calls to socreate() on initially connecting, or reconnecting the socket. This fixes bugs involving NFS over TCP and ipfw uid/gid rules, as well as bugs involving NFS and mandatory access control implementations. Reviewed by: freebsd-arch
-rw-r--r--sys/dev/streams/streams.c3
-rw-r--r--sys/fs/fifofs/fifo_vnops.c6
-rw-r--r--sys/fs/portalfs/portal_vnops.c3
-rw-r--r--sys/kern/uipc_socket.c5
-rw-r--r--sys/kern/uipc_syscalls.c9
-rw-r--r--sys/netgraph/ng_ksocket.c3
-rw-r--r--sys/netsmb/smb_trantcp.c3
-rw-r--r--sys/nfsclient/bootp_subr.c6
-rw-r--r--sys/nfsclient/krpc_subr.c3
-rw-r--r--sys/nfsclient/nfs_socket.c2
-rw-r--r--sys/nfsclient/nfs_vfsops.c17
-rw-r--r--sys/nfsclient/nfsmount.h1
-rw-r--r--sys/sys/socketvar.h2
13 files changed, 42 insertions, 21 deletions
diff --git a/sys/dev/streams/streams.c b/sys/dev/streams/streams.c
index 3fc97c6..1e3a708 100644
--- a/sys/dev/streams/streams.c
+++ b/sys/dev/streams/streams.c
@@ -264,7 +264,8 @@ streamsopen(dev_t dev, int oflags, int devtype, struct thread *td)
if ((error = falloc(td, &fp, &fd)) != 0)
return error;
- if ((error = socreate(family, &so, type, protocol, td)) != 0) {
+ if ((error = socreate(family, &so, type, protocol,
+ td->td_proc->p_ucred, td)) != 0) {
p->p_fd->fd_ofiles[fd] = 0;
ffree(fp);
return error;
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index 9448f5e..461f7c4 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -174,14 +174,16 @@ fifo_open(ap)
if ((fip = vp->v_fifoinfo) == NULL) {
MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
vp->v_fifoinfo = fip;
- error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, ap->a_td);
+ error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0,
+ ap->a_td->td_proc->p_ucred, ap->a_td);
if (error) {
free(fip, M_VNODE);
vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_readsock = rso;
- error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, ap->a_td);
+ error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0,
+ ap->a_td->td_proc->p_ucred, ap->a_td);
if (error) {
(void)soclose(rso);
free(fip, M_VNODE);
diff --git a/sys/fs/portalfs/portal_vnops.c b/sys/fs/portalfs/portal_vnops.c
index 0e20d13..dd90516 100644
--- a/sys/fs/portalfs/portal_vnops.c
+++ b/sys/fs/portalfs/portal_vnops.c
@@ -246,7 +246,8 @@ portal_open(ap)
/*
* Create a new socket.
*/
- error = socreate(AF_UNIX, &so, SOCK_STREAM, 0, ap->a_td);
+ error = socreate(AF_UNIX, &so, SOCK_STREAM, 0,
+ ap->a_td->td_proc->p_ucred, ap->a_td);
if (error)
goto bad;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index caae630c..114aae6 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -137,11 +137,12 @@ soalloc(waitok)
* closed with soclose().
*/
int
-socreate(dom, aso, type, proto, td)
+socreate(dom, aso, type, proto, cred, td)
int dom;
struct socket **aso;
register int type;
int proto;
+ struct ucred *cred;
struct thread *td;
{
register struct protosw *prp;
@@ -172,7 +173,7 @@ socreate(dom, aso, type, proto, td)
TAILQ_INIT(&so->so_incomp);
TAILQ_INIT(&so->so_comp);
so->so_type = type;
- so->so_cred = crhold(td->td_proc->p_ucred);
+ so->so_cred = crhold(cred);
so->so_proto = prp;
soref(so);
error = (*prp->pr_usrreqs->pru_attach)(so, proto, td);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index ee68cfe..07c00e8 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -132,7 +132,8 @@ socket(td, uap)
if (error)
goto done2;
fhold(fp);
- error = socreate(uap->domain, &so, uap->type, uap->protocol, td);
+ error = socreate(uap->domain, &so, uap->type, uap->protocol,
+ td->td_proc->p_ucred, td);
if (error) {
if (fdp->fd_ofiles[fd] == fp) {
fdp->fd_ofiles[fd] = NULL;
@@ -478,10 +479,12 @@ socketpair(td, uap)
int fd, error, sv[2];
mtx_lock(&Giant);
- error = socreate(uap->domain, &so1, uap->type, uap->protocol, td);
+ error = socreate(uap->domain, &so1, uap->type, uap->protocol,
+ td->td_proc->p_ucred, td);
if (error)
goto done2;
- error = socreate(uap->domain, &so2, uap->type, uap->protocol, td);
+ error = socreate(uap->domain, &so2, uap->type, uap->protocol,
+ td->td_proc->p_ucred, td);
if (error)
goto free1;
error = falloc(td, &fp1, &fd);
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
index f945f6a..31cf0b9 100644
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -586,7 +586,8 @@ ng_ksocket_newhook(node_p node, hook_p hook, const char *name0)
return (EINVAL);
/* Create the socket */
- error = socreate(family, &priv->so, type, protocol, td);
+ error = socreate(family, &priv->so, type, protocol,
+ td->td_proc->p_ucred, td);
if (error != 0)
return (error);
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c
index 7c4d74b..567556e 100644
--- a/sys/netsmb/smb_trantcp.c
+++ b/sys/netsmb/smb_trantcp.c
@@ -226,7 +226,8 @@ nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct thread *td)
struct socket *so;
int error, s;
- error = socreate(AF_INET, &so, SOCK_STREAM, IPPROTO_TCP, td);
+ error = socreate(AF_INET, &so, SOCK_STREAM, IPPROTO_TCP,
+ td->td_proc->p_ucred, td);
if (error)
return error;
nbp->nbp_tso = so;
diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c
index 1221135..ff7c256 100644
--- a/sys/nfsclient/bootp_subr.c
+++ b/sys/nfsclient/bootp_subr.c
@@ -586,7 +586,8 @@ bootpc_call(struct bootpc_globalcontext *gctx, struct thread *td)
/*
* Create socket and set its recieve timeout.
*/
- error = socreate(AF_INET, &so, SOCK_DGRAM, 0, td);
+ error = socreate(AF_INET, &so, SOCK_DGRAM, 0, td->td_proc->p_ucred,
+ td);
if (error != 0)
goto out;
@@ -971,7 +972,8 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx,
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
- error = socreate(AF_INET, &ifctx->so, SOCK_DGRAM, 0, td);
+ error = socreate(AF_INET, &ifctx->so, SOCK_DGRAM, 0,
+ td->td_proc->p_ucred, td);
if (error != 0)
panic("nfs_boot: socreate, error=%d", error);
diff --git a/sys/nfsclient/krpc_subr.c b/sys/nfsclient/krpc_subr.c
index 06b9c81..a93bb33 100644
--- a/sys/nfsclient/krpc_subr.c
+++ b/sys/nfsclient/krpc_subr.c
@@ -215,7 +215,8 @@ krpc_call(struct sockaddr_in *sa, u_int prog, u_int vers, u_int func,
/*
* Create socket and set its recieve timeout.
*/
- if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, td)))
+ if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,
+ td->td_proc->p_ucred, td)))
goto out;
tv.tv_sec = 1;
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c
index 62a7b23..b34f739 100644
--- a/sys/nfsclient/nfs_socket.c
+++ b/sys/nfsclient/nfs_socket.c
@@ -163,7 +163,7 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
nmp->nm_so = (struct socket *)0;
saddr = nmp->nm_nam;
error = socreate(saddr->sa_family, &nmp->nm_so, nmp->nm_sotype,
- nmp->nm_soproto, td);
+ nmp->nm_soproto, nmp->nm_cred, td);
if (error)
goto bad;
so = nmp->nm_so;
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index f441c1b1..a3b79ae 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -92,7 +92,8 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, "");
static int nfs_iosize(struct nfsmount *nmp);
static void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp);
static int mountnfs(struct nfs_args *, struct mount *,
- struct sockaddr *, char *, char *, struct vnode **);
+ struct sockaddr *, char *, char *, struct vnode **,
+ struct ucred *cred);
static int nfs_mount(struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct thread *td);
static int nfs_unmount(struct mount *mp, int mntflags, struct thread *td);
@@ -377,6 +378,7 @@ int
nfs_mountroot(struct mount *mp)
{
struct mount *swap_mp;
+ struct nfsmount *nmp = VFSTONFS(mp);
struct nfsv3_diskless *nd = &nfsv3_diskless;
struct socket *so;
struct vnode *vp;
@@ -419,7 +421,8 @@ nfs_mountroot(struct mount *mp)
* Do enough of ifconfig(8) so that the critical net interface can
* talk to the server.
*/
- error = socreate(nd->myif.ifra_addr.sa_family, &so, SOCK_DGRAM, 0, td);
+ error = socreate(nd->myif.ifra_addr.sa_family, &so, SOCK_DGRAM, 0,
+ nmp->nm_cred, td);
if (error)
panic("nfs_mountroot: socreate(%04x): %d",
nd->myif.ifra_addr.sa_family, error);
@@ -557,7 +560,8 @@ nfs_mountdiskless(char *path, char *which, int mountflag,
mp->mnt_kern_flag = 0;
mp->mnt_flag = mountflag;
nam = dup_sockaddr((struct sockaddr *)sin, 1);
- if ((error = mountnfs(args, mp, nam, which, path, vpp)) != 0) {
+ if ((error = mountnfs(args, mp, nam, which, path, vpp, td->td_ucred))
+ != 0) {
printf("nfs_mountroot: mount %s on %s: %d", path, which, error);
mp->mnt_vfc->vfc_refcount--;
vfs_unbusy(mp, td);
@@ -785,7 +789,7 @@ nfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
if (error)
return (error);
args.fh = nfh;
- error = mountnfs(&args, mp, nam, path, hst, &vp);
+ error = mountnfs(&args, mp, nam, path, hst, &vp, td->td_ucred);
return (error);
}
@@ -794,7 +798,7 @@ nfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
*/
static int
mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
- char *pth, char *hst, struct vnode **vpp)
+ char *pth, char *hst, struct vnode **vpp, struct ucred *cred)
{
struct nfsmount *nmp;
struct nfsnode *np;
@@ -814,6 +818,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
+ nmp->nm_cred = crhold(cred);
/*
* V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
@@ -891,6 +896,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
return (0);
bad:
nfs_disconnect(nmp);
+ crfree(nmp->nm_cred);
zfree(nfsmount_zone, nmp);
FREE(nam, M_SONAME);
return (error);
@@ -925,6 +931,7 @@ nfs_unmount(struct mount *mp, int mntflags, struct thread *td)
nfs_disconnect(nmp);
FREE(nmp->nm_nam, M_SONAME);
+ crfree(nmp->nm_cred);
zfree(nfsmount_zone, nmp);
return (0);
}
diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h
index 8c531cb..09ac7f8 100644
--- a/sys/nfsclient/nfsmount.h
+++ b/sys/nfsclient/nfsmount.h
@@ -53,6 +53,7 @@ struct nfsmount {
u_char nm_fh[NFSX_V3FHMAX]; /* File handle of root dir */
int nm_fhsize; /* Size of root file handle */
struct socket *nm_so; /* Rpc socket */
+ struct ucred *nm_cred; /* Cached mount-time credential */
int nm_sotype; /* Type of socket */
int nm_soproto; /* and protocol */
int nm_soflags; /* pr_flags for socket protocol */
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index a5cc701..5fdea26 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -383,7 +383,7 @@ int soclose __P((struct socket *so));
int soconnect __P((struct socket *so, struct sockaddr *nam, struct thread *td));
int soconnect2 __P((struct socket *so1, struct socket *so2));
int socreate __P((int dom, struct socket **aso, int type, int proto,
- struct thread *td));
+ struct ucred *cred, struct thread *td));
int sodisconnect __P((struct socket *so));
void sofree __P((struct socket *so));
int sogetopt __P((struct socket *so, struct sockopt *sopt));
OpenPOWER on IntegriCloud