diff options
author | rwatson <rwatson@FreeBSD.org> | 2001-12-31 17:45:16 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2001-12-31 17:45:16 +0000 |
commit | 5eea21cccab61c0a7e31c0025f3f57feeb99870a (patch) | |
tree | 7c8b2985310180ddd6c0718cf693e5b928d63555 | |
parent | 25ebb0c5b897fa6d9c618e7d9ced3a63510278d1 (diff) | |
download | FreeBSD-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.c | 3 | ||||
-rw-r--r-- | sys/fs/fifofs/fifo_vnops.c | 6 | ||||
-rw-r--r-- | sys/fs/portalfs/portal_vnops.c | 3 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 5 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 9 | ||||
-rw-r--r-- | sys/netgraph/ng_ksocket.c | 3 | ||||
-rw-r--r-- | sys/netsmb/smb_trantcp.c | 3 | ||||
-rw-r--r-- | sys/nfsclient/bootp_subr.c | 6 | ||||
-rw-r--r-- | sys/nfsclient/krpc_subr.c | 3 | ||||
-rw-r--r-- | sys/nfsclient/nfs_socket.c | 2 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vfsops.c | 17 | ||||
-rw-r--r-- | sys/nfsclient/nfsmount.h | 1 | ||||
-rw-r--r-- | sys/sys/socketvar.h | 2 |
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)); |