diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index bed490a5a63b..686c64db320f 100644 --- a/sys/fs/smbfs/smbfs_io.c +++ b/sys/fs/smbfs/smbfs_io.c @@ -75,7 +75,7 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) { struct dirent de; struct componentname cn; - struct smb_cred scred; + struct smb_cred *scred; struct smbfs_fctx *ctx; struct vnode *newvp; struct smbnode *np = VTOSMB(vp); @@ -84,11 +84,14 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) np = VTOSMB(vp); SMBVDEBUG("dirname='%s'\n", np->n_name); - smb_makescred(&scred, uio->uio_td, cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, uio->uio_td, cred); offset = uio->uio_offset / DE_SIZE; /* offset in the directory */ limit = uio->uio_resid / DE_SIZE; - if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) - return EINVAL; + if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) { + error = EINVAL; + goto out; + } while (limit && offset < 2) { limit--; bzero((caddr_t)&de, DE_SIZE); @@ -104,40 +107,43 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) de.d_type = DT_DIR; error = uiomove(&de, DE_SIZE, uio); if (error) - return error; + goto out; offset++; uio->uio_offset += DE_SIZE; } - if (limit == 0) - return 0; + if (limit == 0) { + error = 0; + goto out; + } if (offset != np->n_dirofs || np->n_dirseq == NULL) { SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs); if (np->n_dirseq) { - smbfs_findclose(np->n_dirseq, &scred); + smbfs_findclose(np->n_dirseq, scred); np->n_dirseq = NULL; } np->n_dirofs = 2; error = smbfs_findopen(np, "*", 1, SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, - &scred, &ctx); + scred, &ctx); if (error) { SMBVDEBUG("can not open search, error = %d", error); - return error; + goto out; } np->n_dirseq = ctx; } else ctx = np->n_dirseq; while (np->n_dirofs < offset) { - error = smbfs_findnext(ctx, offset - np->n_dirofs++, &scred); + error = smbfs_findnext(ctx, offset - np->n_dirofs++, scred); if (error) { - smbfs_findclose(np->n_dirseq, &scred); + smbfs_findclose(np->n_dirseq, scred); np->n_dirseq = NULL; - return error == ENOENT ? 0 : error; + error = ENOENT ? 0 : error; + goto out; } } error = 0; for (; limit; limit--, offset++) { - error = smbfs_findnext(ctx, limit, &scred); + error = smbfs_findnext(ctx, limit, scred); if (error) break; np->n_dirofs++; @@ -165,6 +171,8 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) if (error == ENOENT) error = 0; uio->uio_offset = offset * DE_SIZE; +out: + smbfs_free_scred(scred); return error; } @@ -175,7 +183,7 @@ smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred) struct smbnode *np = VTOSMB(vp); struct thread *td; struct vattr vattr; - struct smb_cred scred; + struct smb_cred *scred; int error, lks; /* @@ -223,8 +231,11 @@ smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred) np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; } } - smb_makescred(&scred, td, cred); - return smb_read(smp->sm_share, np->n_fid, uiop, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cred); + error = smb_read(smp->sm_share, np->n_fid, uiop, scred); + smbfs_free_scred(scred); + return (error); } int @@ -233,7 +244,7 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop, { struct smbmount *smp = VTOSMBFS(vp); struct smbnode *np = VTOSMB(vp); - struct smb_cred scred; + struct smb_cred *scred; struct thread *td; int error = 0; @@ -272,9 +283,11 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop, if (vn_rlimit_fsize(vp, uiop, td)) return (EFBIG); - - smb_makescred(&scred, td, cred); - error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); + + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cred); + error = smb_write(smp->sm_share, np->n_fid, uiop, scred); + smbfs_free_scred(scred); SMBVDEBUG("after: ofs=%jd,resid=%zd\n", (intmax_t)uiop->uio_offset, uiop->uio_resid); if (!error) { @@ -294,17 +307,19 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td { struct smbmount *smp = VFSTOSMBFS(vp->v_mount); struct smbnode *np = VTOSMB(vp); - struct uio uio, *uiop = &uio; + struct uio *uiop; struct iovec io; - struct smb_cred scred; + struct smb_cred *scred; int error = 0; + uiop = malloc(sizeof(struct uio), M_SMBFSDATA, M_WAITOK); uiop->uio_iov = &io; uiop->uio_iovcnt = 1; uiop->uio_segflg = UIO_SYSSPACE; uiop->uio_td = td; - smb_makescred(&scred, td, cr); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cr); if (bp->b_iocmd == BIO_READ) { io.iov_len = uiop->uio_resid = bp->b_bcount; @@ -313,7 +328,7 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td switch (vp->v_type) { case VREG: uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; - error = smb_read(smp->sm_share, np->n_fid, uiop, &scred); + error = smb_read(smp->sm_share, np->n_fid, uiop, scred); if (error) break; if (uiop->uio_resid) { @@ -340,7 +355,7 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff; io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; uiop->uio_rw = UIO_WRITE; - error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); + error = smb_write(smp->sm_share, np->n_fid, uiop, scred); /* * For an interrupted write, the buffer is still valid @@ -380,11 +395,15 @@ smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td } else { bp->b_resid = 0; bufdone(bp); + free(uiop, M_SMBFSDATA); + smbfs_free_scred(scred); return 0; } } bp->b_resid = uiop->uio_resid; bufdone(bp); + free(uiop, M_SMBFSDATA); + smbfs_free_scred(scred); return error; } @@ -415,7 +434,7 @@ smbfs_getpages(ap) struct ucred *cred; struct smbmount *smp; struct smbnode *np; - struct smb_cred scred; + struct smb_cred *scred; vm_object_t object; vm_page_t *pages, m; @@ -455,7 +474,8 @@ smbfs_getpages(ap) } VM_OBJECT_UNLOCK(object); - smb_makescred(&scred, td, cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cred); bp = getpbuf(&smbfs_pbuf_freecnt); @@ -474,7 +494,8 @@ smbfs_getpages(ap) uio.uio_rw = UIO_READ; uio.uio_td = td; - error = smb_read(smp->sm_share, np->n_fid, &uio, &scred); + error = smb_read(smp->sm_share, np->n_fid, &uio, scred); + smbfs_free_scred(scred); pmap_qremove(kva, npages); relpbuf(bp, &smbfs_pbuf_freecnt); @@ -570,7 +591,7 @@ smbfs_putpages(ap) int *rtvals; struct smbmount *smp; struct smbnode *np; - struct smb_cred scred; + struct smb_cred *scred; vm_page_t *pages; td = curthread; /* XXX */ @@ -606,8 +627,10 @@ smbfs_putpages(ap) SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uio.uio_offset, uio.uio_resid); - smb_makescred(&scred, td, cred); - error = smb_write(smp->sm_share, np->n_fid, &uio, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cred); + error = smb_write(smp->sm_share, np->n_fid, &uio, scred); + smbfs_free_scred(scred); /* VOP_CLOSE(vp, FWRITE, cred, td);*/ SMBVDEBUG("paged write done: %d\n", error); diff --git a/sys/fs/smbfs/smbfs_node.c b/sys/fs/smbfs/smbfs_node.c index 1b727a5ce180..4b2af615da15 100644 --- a/sys/fs/smbfs/smbfs_node.c +++ b/sys/fs/smbfs/smbfs_node.c @@ -349,25 +349,27 @@ smbfs_inactive(ap) struct ucred *cred = td->td_ucred; struct vnode *vp = ap->a_vp; struct smbnode *np = VTOSMB(vp); - struct smb_cred scred; + struct smb_cred *scred; struct vattr va; SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vrefcnt(vp)); if ((np->n_flag & NOPEN) != 0) { - smb_makescred(&scred, td, cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cred); smbfs_vinvalbuf(vp, td); if (vp->v_type == VREG) { VOP_GETATTR(vp, &va, cred); smbfs_smb_close(np->n_mount->sm_share, np->n_fid, - &np->n_mtime, &scred); + &np->n_mtime, scred); } else if (vp->v_type == VDIR) { if (np->n_dirseq != NULL) { - smbfs_findclose(np->n_dirseq, &scred); + smbfs_findclose(np->n_dirseq, scred); np->n_dirseq = NULL; } } np->n_flag &= ~NOPEN; smbfs_attr_cacheremove(vp); + smbfs_free_scred(scred); } if (np->n_flag & NGONE) vrecycle(vp); diff --git a/sys/fs/smbfs/smbfs_smb.c b/sys/fs/smbfs/smbfs_smb.c index 7b84f4bbb3fc..05d482ef6e81 100644 --- a/sys/fs/smbfs/smbfs_smb.c +++ b/sys/fs/smbfs/smbfs_smb.c @@ -87,16 +87,19 @@ smbfs_smb_lockandx(struct smbnode *np, int op, u_int32_t pid, off_t start, off_t struct smb_cred *scred) { struct smb_share *ssp = np->n_mount->sm_share; - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct mbchain *mbp; u_char ltype = 0; int error; if (op == SMB_LOCK_SHARED) ltype |= SMB_LOCKING_ANDX_SHARED_LOCK; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_LOCKING_ANDX, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint8(mbp, 0xff); /* secondary command */ @@ -116,6 +119,7 @@ smbfs_smb_lockandx(struct smbnode *np, int op, u_int32_t pid, off_t start, off_t smb_rq_bend(rqp); error = smb_rq_simple(rqp); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -179,20 +183,24 @@ int smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct mdchain *mdp; u_int16_t units, bpu, bsize, funits; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION_DISK, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_wstart(rqp); smb_rq_wend(rqp); smb_rq_bstart(rqp); smb_rq_bend(rqp); error = smb_rq_simple(rqp); if (error) { + free(rqp, M_SMBFSDATA); smb_rq_done(rqp); return error; } @@ -208,6 +216,7 @@ smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp, sbp->f_files = 0xffff; /* total file nodes in filesystem */ sbp->f_ffree = 0xffff; /* free file nodes in fs */ smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return 0; } @@ -244,16 +253,19 @@ static int smb_smb_flush(struct smbnode *np, struct smb_cred *scred) { struct smb_share *ssp = np->n_mount->sm_share; - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct mbchain *mbp; int error; if ((np->n_flag & NOPEN) == 0 || !SMBTOV(np) || SMBTOV(np)->v_type != VREG) return 0; /* not a regular open file */ + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_FLUSH, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return (error); + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM); @@ -262,6 +274,7 @@ smb_smb_flush(struct smbnode *np, struct smb_cred *scred) smb_rq_bend(rqp); error = smb_rq_simple(rqp); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); if (!error) np->n_flag &= ~NFLUSHWIRE; return (error); @@ -279,7 +292,7 @@ int smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred) { struct smb_share *ssp = np->n_mount->sm_share; - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct mbchain *mbp; int error; @@ -288,9 +301,12 @@ smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred) return (0); } + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_WRITE, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM); @@ -304,6 +320,7 @@ smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred) smb_rq_bend(rqp); error = smb_rq_simple(rqp); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -311,7 +328,7 @@ int smbfs_smb_query_info(struct smbnode *np, const char *name, int len, struct smbfattr *fap, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; struct mdchain *mdp; @@ -320,9 +337,12 @@ smbfs_smb_query_info(struct smbnode *np, const char *name, int len, u_int16_t wattr; u_int32_t lint; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_QUERY_INFORMATION, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); smb_rq_wend(rqp); @@ -357,6 +377,7 @@ smbfs_smb_query_info(struct smbnode *np, const char *name, int len, fap->fa_size = lint; } while(0); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -367,15 +388,18 @@ int smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; u_long time; int error, svtz; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } svtz = SSTOVC(ssp)->vc_sopt.sv_tz; smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); @@ -407,6 +431,7 @@ smbfs_smb_setpattr(struct smbnode *np, u_int16_t attr, struct timespec *mtime, } } while(0); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -523,15 +548,18 @@ int smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime, struct timespec *atime, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; u_int16_t date, time; int error, tzoff; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_SET_INFORMATION2, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } tzoff = SSTOVC(ssp)->vc_sopt.sv_tz; smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); @@ -556,6 +584,7 @@ smbfs_smb_setftime(struct smbnode *np, struct timespec *mtime, error = smb_rq_simple(rqp); SMBSDEBUG("%d\n", error); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -611,7 +640,7 @@ smbfs_smb_setfattrNT(struct smbnode *np, u_int16_t attr, struct timespec *mtime, int smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; struct mdchain *mdp; @@ -619,9 +648,12 @@ smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred) u_int16_t fid, wattr, grantedmode; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint16le(mbp, accmode); @@ -652,6 +684,7 @@ smbfs_smb_open(struct smbnode *np, int accmode, struct smb_cred *scred) */ } while(0); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); if (error) return error; np->n_fid = fid; @@ -664,14 +697,17 @@ int smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct mbchain *mbp; u_long time; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_mem(mbp, (caddr_t)&fid, sizeof(fid), MB_MSYSTEM); @@ -685,6 +721,7 @@ smbfs_smb_close(struct smb_share *ssp, u_int16_t fid, struct timespec *mtime, smb_rq_bend(rqp); error = smb_rq_simple(rqp); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -692,7 +729,7 @@ int smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = dnp->n_mount->sm_share; struct mbchain *mbp; struct mdchain *mdp; @@ -702,9 +739,12 @@ smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen, u_long tm; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint16le(mbp, SMB_FA_ARCHIVE); /* attributes */ @@ -731,20 +771,24 @@ smbfs_smb_create(struct smbnode *dnp, const char *name, int nmlen, if (error) return error; smbfs_smb_close(ssp, fid, &ctime, scred); + free(rqp, M_SMBFSDATA); return error; } int smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN); @@ -757,6 +801,7 @@ smbfs_smb_delete(struct smbnode *np, struct smb_cred *scred) error = smb_rq_simple(rqp); } smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -764,14 +809,17 @@ int smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp, const char *tname, int tnmlen, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = src->n_mount->sm_share; struct mbchain *mbp; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_RENAME, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint16le(mbp, SMB_FA_SYSTEM | SMB_FA_HIDDEN); @@ -790,6 +838,7 @@ smbfs_smb_rename(struct smbnode *src, struct smbnode *tdnp, error = smb_rq_simple(rqp); } while(0); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -797,14 +846,17 @@ int smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp, const char *tname, int tnmlen, u_int16_t flags, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = src->n_mount->sm_share; struct mbchain *mbp; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_MOVE, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint16le(mbp, SMB_TID_UNKNOWN); @@ -825,6 +877,7 @@ smbfs_smb_move(struct smbnode *src, struct smbnode *tdnp, error = smb_rq_simple(rqp); } while(0); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -832,14 +885,17 @@ int smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = dnp->n_mount->sm_share; struct mbchain *mbp; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CREATE_DIRECTORY, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); smb_rq_wend(rqp); @@ -851,20 +907,24 @@ smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int len, error = smb_rq_simple(rqp); } smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } int smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_DELETE_DIRECTORY, scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); smb_rq_wend(rqp); @@ -876,6 +936,7 @@ smbfs_smb_rmdir(struct smbnode *np, struct smb_cred *scred) error = smb_rq_simple(rqp); } smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } @@ -1139,13 +1200,16 @@ smbfs_smb_trans2find2(struct smbfs_fctx *ctx) static int smbfs_smb_findclose2(struct smbfs_fctx *ctx) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct mbchain *mbp; int error; + rqp = malloc(sizeof(struct smb_rq), M_SMBFSDATA, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ctx->f_ssp), SMB_COM_FIND_CLOSE2, ctx->f_scred); - if (error) + if (error) { + free(rqp, M_SMBFSDATA); return error; + } smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_mem(mbp, (caddr_t)&ctx->f_Sid, 2, MB_MSYSTEM); @@ -1154,6 +1218,7 @@ smbfs_smb_findclose2(struct smbfs_fctx *ctx) smb_rq_bend(rqp); error = smb_rq_simple(rqp); smb_rq_done(rqp); + free(rqp, M_SMBFSDATA); return error; } diff --git a/sys/fs/smbfs/smbfs_subr.c b/sys/fs/smbfs/smbfs_subr.c index 51ee4d5b3a46..b95f92bdae86 100644 --- a/sys/fs/smbfs/smbfs_subr.c +++ b/sys/fs/smbfs/smbfs_subr.c @@ -46,6 +46,7 @@ #include MALLOC_DEFINE(M_SMBFSDATA, "smbfs_data", "SMBFS private data"); +MALLOC_DEFINE(M_SMBFSCRED, "smbfs_cred", "SMBFS cred data"); void smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds) @@ -222,3 +223,15 @@ smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int *nmlen, int caseopt) } return error; } + +void * +smbfs_malloc_scred(void) +{ + return (malloc(sizeof(struct smb_cred), M_SMBFSCRED, M_WAITOK)); +} + +void +smbfs_free_scred(void *scred) +{ + free(scred, M_SMBFSCRED); +} diff --git a/sys/fs/smbfs/smbfs_subr.h b/sys/fs/smbfs/smbfs_subr.h index 15112903bd35..0900f0953b46 100644 --- a/sys/fs/smbfs/smbfs_subr.h +++ b/sys/fs/smbfs/smbfs_subr.h @@ -30,6 +30,7 @@ #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_SMBFSDATA); +MALLOC_DECLARE(M_SMBFSCRED); #endif #define SMBFSERR(format, args...) printf("%s: "format, __func__ ,## args) @@ -178,4 +179,6 @@ void smb_time_unix2dos(struct timespec *tsp, int tzoff, u_int16_t *ddp, u_int16_t *dtp, u_int8_t *dhp); void smb_dos2unixtime (u_int dd, u_int dt, u_int dh, int tzoff, struct timespec *tsp); +void *smbfs_malloc_scred(void); +void smbfs_free_scred(void *); #endif /* !_FS_SMBFS_SMBFS_SUBR_H_ */ diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c index 2443001e25e9..c3d5a88fdad8 100644 --- a/sys/fs/smbfs/smbfs_vfsops.c +++ b/sys/fs/smbfs/smbfs_vfsops.c @@ -137,7 +137,7 @@ smbfs_mount(struct mount *mp) struct smb_share *ssp = NULL; struct vnode *vp; struct thread *td; - struct smb_cred scred; + struct smb_cred *scred; int error, v; char *pc, *pe; @@ -150,15 +150,18 @@ smbfs_mount(struct mount *mp) return (EINVAL); } - smb_makescred(&scred, td, td->td_ucred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, td->td_ucred); if (1 != vfs_scanopt(mp->mnt_optnew, "dev", "%d", &v)) { vfs_mount_error(mp, "No dev option"); + smbfs_free_scred(scred); return (EINVAL); } - error = smb_dev2share(v, SMBM_EXEC, &scred, &ssp); + error = smb_dev2share(v, SMBM_EXEC, scred, &ssp); if (error) { printf("invalid device handle %d (%d)\n", v, error); vfs_mount_error(mp, "invalid device handle %d (%d)\n", v, error); + smbfs_free_scred(scred); return error; } vcp = SSTOVC(ssp); @@ -237,6 +240,7 @@ smbfs_mount(struct mount *mp) #ifdef DIAGNOSTIC SMBERROR("mp=%p\n", mp); #endif + smbfs_free_scred(scred); return error; bad: if (smp) { @@ -246,7 +250,8 @@ bad: free(smp, M_SMBFSDATA); } if (ssp) - smb_share_put(ssp, &scred); + smb_share_put(ssp, scred); + smbfs_free_scred(scred); return error; } @@ -256,7 +261,7 @@ smbfs_unmount(struct mount *mp, int mntflags) { struct thread *td; struct smbmount *smp = VFSTOSMBFS(mp); - struct smb_cred scred; + struct smb_cred *scred; int error, flags; SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags); @@ -279,11 +284,12 @@ smbfs_unmount(struct mount *mp, int mntflags) } while (error == EBUSY && smp->sm_didrele != 0); if (error) return error; - smb_makescred(&scred, td, td->td_ucred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, td->td_ucred); error = smb_share_lock(smp->sm_share, LK_EXCLUSIVE); if (error) - return error; - smb_share_put(smp->sm_share, &scred); + goto out; + smb_share_put(smp->sm_share, scred); mp->mnt_data = NULL; if (smp->sm_hash) @@ -293,6 +299,8 @@ smbfs_unmount(struct mount *mp, int mntflags) MNT_ILOCK(mp); mp->mnt_flag &= ~MNT_LOCAL; MNT_IUNLOCK(mp); +out: + smbfs_free_scred(scred); return error; } @@ -308,7 +316,7 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp) struct smbfattr fattr; struct thread *td; struct ucred *cred; - struct smb_cred scred; + struct smb_cred *scred; int error; td = curthread; @@ -323,19 +331,22 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp) *vpp = SMBTOV(smp->sm_root); return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td); } - smb_makescred(&scred, td, cred); - error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cred); + error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, scred); if (error) - return error; + goto out; error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp); if (error) - return error; + goto out; ASSERT_VOP_LOCKED(vp, "smbfs_root"); vp->v_vflag |= VV_ROOT; np = VTOSMB(vp); smp->sm_root = np; *vpp = vp; - return 0; +out: + smbfs_free_scred(scred); + return error; } /* @@ -381,7 +392,7 @@ smbfs_statfs(struct mount *mp, struct statfs *sbp) struct smbmount *smp = VFSTOSMBFS(mp); struct smbnode *np = smp->sm_root; struct smb_share *ssp = smp->sm_share; - struct smb_cred scred; + struct smb_cred *scred; int error = 0; if (np == NULL) { @@ -390,14 +401,18 @@ smbfs_statfs(struct mount *mp, struct statfs *sbp) } sbp->f_iosize = SSTOVC(ssp)->vc_txmax; /* optimal transfer block size */ - smb_makescred(&scred, td, td->td_ucred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, td->td_ucred); if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0) - error = smbfs_smb_statfs2(ssp, sbp, &scred); + error = smbfs_smb_statfs2(ssp, sbp, scred); else - error = smbfs_smb_statfs(ssp, sbp, &scred); - if (error) + error = smbfs_smb_statfs(ssp, sbp, scred); + if (error) { + smbfs_free_scred(scred); return error; + } sbp->f_flags = 0; /* copy of mount exported flags */ + smbfs_free_scred(scred); return 0; } diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c index c8a4d3e61484..cc1e4d02d6d9 100644 --- a/sys/fs/smbfs/smbfs_vnops.c +++ b/sys/fs/smbfs/smbfs_vnops.c @@ -153,7 +153,7 @@ smbfs_open(ap) { struct vnode *vp = ap->a_vp; struct smbnode *np = VTOSMB(vp); - struct smb_cred scred; + struct smb_cred *scred; struct vattr vattr; int mode = ap->a_mode; int error, accmode; @@ -197,14 +197,15 @@ smbfs_open(ap) accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD; if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW; - smb_makescred(&scred, ap->a_td, ap->a_cred); - error = smbfs_smb_open(np, accmode, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, ap->a_td, ap->a_cred); + error = smbfs_smb_open(np, accmode, scred); if (error) { if (mode & FWRITE) return EACCES; else if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD; - error = smbfs_smb_open(np, accmode, &scred); + error = smbfs_smb_open(np, accmode, scred); } } if (error == 0) { @@ -212,6 +213,7 @@ smbfs_open(ap) vnode_create_vobject(ap->a_vp, vattr.va_size, ap->a_td); } smbfs_attr_cacheremove(vp); + smbfs_free_scred(scred); return error; } @@ -228,12 +230,14 @@ smbfs_close(ap) struct vnode *vp = ap->a_vp; struct thread *td = ap->a_td; struct smbnode *np = VTOSMB(vp); - struct smb_cred scred; + struct smb_cred *scred; if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 && np->n_dirseq != NULL) { - smb_makescred(&scred, td, ap->a_cred); - smbfs_findclose(np->n_dirseq, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, ap->a_cred); + smbfs_findclose(np->n_dirseq, scred); + smbfs_free_scred(scred); np->n_dirseq = NULL; } return 0; @@ -254,7 +258,7 @@ smbfs_getattr(ap) struct smbnode *np = VTOSMB(vp); struct vattr *va=ap->a_vap; struct smbfattr fattr; - struct smb_cred scred; + struct smb_cred *scred; u_quad_t oldsize; int error; @@ -263,17 +267,20 @@ smbfs_getattr(ap) if (!error) return 0; SMBVDEBUG("not in the cache\n"); - smb_makescred(&scred, curthread, ap->a_cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, curthread, ap->a_cred); oldsize = np->n_size; - error = smbfs_smb_lookup(np, NULL, 0, &fattr, &scred); + error = smbfs_smb_lookup(np, NULL, 0, &fattr, scred); if (error) { SMBVDEBUG("error %d\n", error); + smbfs_free_scred(scred); return error; } smbfs_attr_cacheenter(vp, &fattr); smbfs_attr_cachelookup(vp, va); if (np->n_flag & NOPEN) np->n_size = oldsize; + smbfs_free_scred(scred); return 0; } @@ -289,7 +296,7 @@ smbfs_setattr(ap) struct smbnode *np = VTOSMB(vp); struct vattr *vap = ap->a_vap; struct timespec *mtime, *atime; - struct smb_cred scred; + struct smb_cred *scred; struct smb_share *ssp = np->n_mount->sm_share; struct smb_vc *vcp = SSTOVC(ssp); struct thread *td = curthread; @@ -308,18 +315,23 @@ smbfs_setattr(ap) vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && isreadonly) return EROFS; - smb_makescred(&scred, td, ap->a_cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, ap->a_cred); if (vap->va_size != VNOVAL) { switch (vp->v_type) { case VDIR: - return EISDIR; + error = EISDIR; + goto out; case VREG: break; default: - return EINVAL; + error = EINVAL; + goto out; }; - if (isreadonly) - return EROFS; + if (isreadonly) { + error = EROFS; + goto out; + } doclose = 0; vnode_pager_setsize(vp, (u_long)vap->va_size); tsize = np->n_size; @@ -327,18 +339,18 @@ smbfs_setattr(ap) if ((np->n_flag & NOPEN) == 0) { error = smbfs_smb_open(np, SMB_SM_DENYNONE|SMB_AM_OPENRW, - &scred); + scred); if (error == 0) doclose = 1; } if (error == 0) - error = smbfs_smb_setfsize(np, vap->va_size, &scred); + error = smbfs_smb_setfsize(np, vap->va_size, scred); if (doclose) - smbfs_smb_close(ssp, np->n_fid, NULL, &scred); + smbfs_smb_close(ssp, np->n_fid, NULL, scred); if (error) { np->n_size = tsize; vnode_pager_setsize(vp, (u_long)tsize); - return error; + goto out; } } if (vap->va_mode != (mode_t)VNOVAL) { @@ -348,9 +360,9 @@ smbfs_setattr(ap) else np->n_dosattr |= SMB_FA_RDONLY; if (np->n_dosattr != old_n_dosattr) { - error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, &scred); + error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, scred); if (error) - return error; + goto out; } } mtime = atime = NULL; @@ -381,25 +393,25 @@ smbfs_setattr(ap) NULL); if (!error) { /* error = smbfs_smb_setfattrNT(np, 0, - mtime, atime, &scred); + mtime, atime, scred); VOP_GETATTR(vp, &vattr, ap->a_cred); */ if (mtime) np->n_mtime = *mtime; VOP_CLOSE(vp, FWRITE, ap->a_cred, td); } } else if ((vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS)) { - error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred); -/* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, &scred);*/ + error = smbfs_smb_setptime2(np, mtime, atime, 0, scred); +/* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, scred);*/ } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) { - error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred); + error = smbfs_smb_setptime2(np, mtime, atime, 0, scred); } else { - error = smbfs_smb_setpattr(np, 0, mtime, &scred); + error = smbfs_smb_setpattr(np, 0, mtime, scred); } } else { if (vcp->vc_sopt.sv_caps & SMB_CAP_NT_SMBS) { - error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred); + error = smbfs_smb_setfattrNT(np, 0, mtime, atime, scred); } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) { - error = smbfs_smb_setftime(np, mtime, atime, &scred); + error = smbfs_smb_setftime(np, mtime, atime, scred); } else { /* * I have no idea how to handle this for core @@ -417,6 +429,8 @@ smbfs_setattr(ap) smbfs_attr_cacheremove(vp); /* invalidate cache */ VOP_GETATTR(vp, vap, ap->a_cred); np->n_mtime.tv_sec = vap->va_mtime.tv_sec; +out: + smbfs_free_scred(scred); return error; } /* @@ -482,7 +496,7 @@ smbfs_create(ap) struct vnode *vp; struct vattr vattr; struct smbfattr fattr; - struct smb_cred scred; + struct smb_cred *scred; char *name = cnp->cn_nameptr; int nmlen = cnp->cn_namelen; int error; @@ -494,20 +508,23 @@ smbfs_create(ap) return EOPNOTSUPP; if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred))) return error; - smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, cnp->cn_thread, cnp->cn_cred); - error = smbfs_smb_create(dnp, name, nmlen, &scred); + error = smbfs_smb_create(dnp, name, nmlen, scred); if (error) - return error; - error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred); + goto out; + error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, scred); if (error) - return error; + goto out; error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, &vp); if (error) - return error; + goto out; *vpp = vp; if (cnp->cn_flags & MAKEENTRY) cache_enter(dvp, vp, cnp); +out: + smbfs_free_scred(scred); return error; } @@ -524,16 +541,18 @@ smbfs_remove(ap) /* struct vnode *dvp = ap->a_dvp;*/ struct componentname *cnp = ap->a_cnp; struct smbnode *np = VTOSMB(vp); - struct smb_cred scred; + struct smb_cred *scred; int error; if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 || vrefcnt(vp) != 1) return EPERM; - smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); - error = smbfs_smb_delete(np, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, cnp->cn_thread, cnp->cn_cred); + error = smbfs_smb_delete(np, scred); if (error == 0) np->n_flag |= NGONE; cache_purge(vp); + smbfs_free_scred(scred); return error; } @@ -557,19 +576,19 @@ smbfs_rename(ap) struct vnode *tdvp = ap->a_tdvp; struct componentname *tcnp = ap->a_tcnp; /* struct componentname *fcnp = ap->a_fcnp;*/ - struct smb_cred scred; + struct smb_cred *scred; u_int16_t flags = 6; int error=0; /* Check for cross-device rename */ if ((fvp->v_mount != tdvp->v_mount) || (tvp && (fvp->v_mount != tvp->v_mount))) { - error = EXDEV; + return EXDEV; goto out; } if (tvp && vrefcnt(tvp) > 1) { - error = EBUSY; + return EBUSY; goto out; } flags = 0x10; /* verify all writes */ @@ -578,17 +597,17 @@ smbfs_rename(ap) } else if (fvp->v_type == VREG) { flags |= 1; } else { - error = EINVAL; - goto out; + return EINVAL; } - smb_makescred(&scred, tcnp->cn_thread, tcnp->cn_cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, tcnp->cn_thread, tcnp->cn_cred); /* * It seems that Samba doesn't implement SMB_COM_MOVE call... */ #ifdef notnow if (SMB_DIALECT(SSTOCN(smp->sm_share)) >= SMB_DIALECT_LANMAN1_0) { error = smbfs_smb_move(VTOSMB(fvp), VTOSMB(tdvp), - tcnp->cn_nameptr, tcnp->cn_namelen, flags, &scred); + tcnp->cn_nameptr, tcnp->cn_namelen, flags, scred); } else #endif { @@ -596,13 +615,13 @@ smbfs_rename(ap) * We have to do the work atomicaly */ if (tvp && tvp != fvp) { - error = smbfs_smb_delete(VTOSMB(tvp), &scred); + error = smbfs_smb_delete(VTOSMB(tvp), scred); if (error) goto out_cacherem; VTOSMB(fvp)->n_flag |= NGONE; } error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp), - tcnp->cn_nameptr, tcnp->cn_namelen, &scred); + tcnp->cn_nameptr, tcnp->cn_namelen, scred); } if (fvp->v_type == VDIR) { @@ -615,6 +634,7 @@ out_cacherem: smbfs_attr_cacheremove(fdvp); smbfs_attr_cacheremove(tdvp); out: + smbfs_free_scred(scred); if (tdvp == tvp) vrele(tdvp); else @@ -685,7 +705,7 @@ smbfs_mkdir(ap) struct componentname *cnp = ap->a_cnp; struct smbnode *dnp = VTOSMB(dvp); struct vattr vattr; - struct smb_cred scred; + struct smb_cred *scred; struct smbfattr fattr; char *name = cnp->cn_nameptr; int len = cnp->cn_namelen; @@ -696,17 +716,20 @@ smbfs_mkdir(ap) } if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.')))) return EEXIST; - smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); - error = smbfs_smb_mkdir(dnp, name, len, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, cnp->cn_thread, cnp->cn_cred); + error = smbfs_smb_mkdir(dnp, name, len, scred); if (error) - return error; - error = smbfs_smb_lookup(dnp, name, len, &fattr, &scred); + goto out; + error = smbfs_smb_lookup(dnp, name, len, &fattr, scred); if (error) - return error; + goto out; error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp); if (error) - return error; + goto out; *ap->a_vpp = vp; +out: + smbfs_free_scred(scred); return 0; } @@ -727,20 +750,22 @@ smbfs_rmdir(ap) /* struct smbmount *smp = VTOSMBFS(vp);*/ struct smbnode *dnp = VTOSMB(dvp); struct smbnode *np = VTOSMB(vp); - struct smb_cred scred; + struct smb_cred *scred; int error; if (dvp == vp) return EINVAL; - smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred); - error = smbfs_smb_rmdir(np, &scred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, cnp->cn_thread, cnp->cn_cred); + error = smbfs_smb_rmdir(np, scred); if (error == 0) np->n_flag |= NGONE; dnp->n_flag |= NMODIFIED; smbfs_attr_cacheremove(dvp); /* cache_purge(dvp);*/ cache_purge(vp); + smbfs_free_scred(scred); return error; } @@ -936,7 +961,7 @@ smbfs_advlock(ap) caddr_t id = (caddr_t)1 /* ap->a_id */; /* int flags = ap->a_flags;*/ struct thread *td = curthread; - struct smb_cred scred; + struct smb_cred *scred; u_quad_t size; off_t start, end, oadd; int error, lkop; @@ -986,7 +1011,8 @@ smbfs_advlock(ap) return EOVERFLOW; end = start + oadd; } - smb_makescred(&scred, td, td->td_ucred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, td->td_ucred); switch (ap->a_op) { case F_SETLK: switch (fl->l_type) { @@ -1000,13 +1026,14 @@ smbfs_advlock(ap) lkop = SMB_LOCK_RELEASE; break; default: + smbfs_free_scred(scred); return EINVAL; } error = lf_advlock(ap, &vp->v_lockf, size); if (error) break; lkop = SMB_LOCK_EXCL; - error = smbfs_smb_lock(np, lkop, id, start, end, &scred); + error = smbfs_smb_lock(np, lkop, id, start, end, scred); if (error) { int oldtype = fl->l_type; fl->l_type = F_UNLCK; @@ -1017,14 +1044,16 @@ smbfs_advlock(ap) break; case F_UNLCK: lf_advlock(ap, &vp->v_lockf, size); - error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, id, start, end, &scred); + error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, id, start, end, scred); break; case F_GETLK: error = lf_advlock(ap, &vp->v_lockf, size); break; default: + smbfs_free_scred(scred); return EINVAL; } + smbfs_free_scred(scred); return error; } @@ -1091,7 +1120,7 @@ smbfs_lookup(ap) struct mount *mp = dvp->v_mount; struct smbnode *dnp; struct smbfattr fattr, *fap; - struct smb_cred scred; + struct smb_cred *scred; char *name = cnp->cn_nameptr; int flags = cnp->cn_flags; int nameiop = cnp->cn_nameiop; @@ -1182,20 +1211,21 @@ smbfs_lookup(ap) */ error = 0; *vpp = NULLVP; - smb_makescred(&scred, td, cnp->cn_cred); + scred = smbfs_malloc_scred(); + smb_makescred(scred, td, cnp->cn_cred); fap = &fattr; if (flags & ISDOTDOT) { error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap, - &scred); + scred); SMBVDEBUG("result of dotdot lookup: %d\n", error); } else { fap = &fattr; - error = smbfs_smb_lookup(dnp, name, nmlen, fap, &scred); + error = smbfs_smb_lookup(dnp, name, nmlen, fap, scred); /* if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')*/ SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error); } if (error && error != ENOENT) - return error; + goto out; if (error) { /* entry not found */ /* * Handle RENAME or CREATE case... @@ -1203,11 +1233,13 @@ smbfs_lookup(ap) if ((nameiop == CREATE || nameiop == RENAME) && islastcn) { error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); if (error) - return error; + goto out; cnp->cn_flags |= SAVENAME; - return (EJUSTRETURN); + error = EJUSTRETURN; + goto out; } - return ENOENT; + error = ENOENT; + goto out; }/* else { SMBVDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum); }*/ @@ -1217,38 +1249,40 @@ smbfs_lookup(ap) if (nameiop == DELETE && islastcn) { /* delete last component */ error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); if (error) - return error; + goto out; if (isdot) { VREF(dvp); *vpp = dvp; - return 0; + goto out; } error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp); if (error) - return error; + goto out; *vpp = vp; cnp->cn_flags |= SAVENAME; - return 0; + goto out; } if (nameiop == RENAME && islastcn) { error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); if (error) - return error; - if (isdot) - return EISDIR; + goto out; + if (isdot) { + error = EISDIR; + goto out; + } error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp); if (error) - return error; + goto out; *vpp = vp; cnp->cn_flags |= SAVENAME; - return 0; + goto out; } if (flags & ISDOTDOT) { VOP_UNLOCK(dvp, 0); error = smbfs_nget(mp, dvp, name, nmlen, NULL, &vp); vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); if (error) - return error; + goto out; *vpp = vp; } else if (isdot) { vref(dvp); @@ -1256,7 +1290,7 @@ smbfs_lookup(ap) } else { error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp); if (error) - return error; + goto out; *vpp = vp; SMBVDEBUG("lookup: getnewvp!\n"); } @@ -1264,5 +1298,7 @@ smbfs_lookup(ap) /* VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_vattr.va_ctime.tv_sec;*/ cache_enter(dvp, *vpp, cnp); } - return 0; +out: + smbfs_free_scred(scred); + return (error); } diff --git a/sys/netsmb/smb_conn.c b/sys/netsmb/smb_conn.c index 2ee851bd4aec..aee090f915b6 100644 --- a/sys/netsmb/smb_conn.c +++ b/sys/netsmb/smb_conn.c @@ -868,8 +868,6 @@ smb_share_getinfo(struct smb_share *ssp, struct smb_share_info *sip) static int smb_sysctl_treedump(SYSCTL_HANDLER_ARGS) { - struct thread *td = req->td; - struct smb_cred scred; struct smb_connobj *scp1, *scp2; struct smb_vc *vcp; struct smb_share *ssp; @@ -877,7 +875,6 @@ smb_sysctl_treedump(SYSCTL_HANDLER_ARGS) struct smb_share_info ssi; int error, itype; - smb_makescred(&scred, td, td->td_ucred); error = sysctl_wire_old_buffer(req, 0); if (error) return (error); diff --git a/sys/netsmb/smb_dev.c b/sys/netsmb/smb_dev.c index 86b27533f213..dfedd8898a27 100644 --- a/sys/netsmb/smb_dev.c +++ b/sys/netsmb/smb_dev.c @@ -157,22 +157,24 @@ nsmb_dev_close(struct cdev *dev, int flag, int fmt, struct thread *td) struct smb_dev *sdp; struct smb_vc *vcp; struct smb_share *ssp; - struct smb_cred scred; + struct smb_cred *scred; int s; + scred = malloc(sizeof(struct smb_cred), M_NSMBDEV, M_WAITOK); SMB_CHECKMINOR(dev); s = splimp(); if ((sdp->sd_flags & NSMBFL_OPEN) == 0) { splx(s); + free(scred, M_NSMBDEV); return EBADF; } - smb_makescred(&scred, td, NULL); + smb_makescred(scred, td, NULL); ssp = sdp->sd_share; if (ssp != NULL) - smb_share_rele(ssp, &scred); + smb_share_rele(ssp, scred); vcp = sdp->sd_vc; if (vcp != NULL) - smb_vc_rele(vcp, &scred); + smb_vc_rele(vcp, scred); /* smb_flushq(&sdp->sd_rqlist); smb_flushq(&sdp->sd_rplist); @@ -181,6 +183,7 @@ nsmb_dev_close(struct cdev *dev, int flag, int fmt, struct thread *td) free(sdp, M_NSMBDEV); destroy_dev_sched(dev); splx(s); + free(scred, M_NSMBDEV); return 0; } @@ -191,20 +194,23 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre struct smb_dev *sdp; struct smb_vc *vcp; struct smb_share *ssp; - struct smb_cred scred; + struct smb_cred *scred; int error = 0; SMB_CHECKMINOR(dev); if ((sdp->sd_flags & NSMBFL_OPEN) == 0) return EBADF; - smb_makescred(&scred, td, NULL); + scred = malloc(sizeof(struct smb_cred), M_NSMBDEV, M_WAITOK); + smb_makescred(scred, td, NULL); switch (cmd) { case SMBIOC_OPENSESSION: - if (sdp->sd_vc) - return EISCONN; + if (sdp->sd_vc) { + error = EISCONN; + goto out; + } error = smb_usr_opensession((struct smbioc_ossn*)data, - &scred, &vcp); + scred, &vcp); if (error) break; sdp->sd_vc = vcp; @@ -212,12 +218,16 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre sdp->sd_level = SMBL_VC; break; case SMBIOC_OPENSHARE: - if (sdp->sd_share) - return EISCONN; - if (sdp->sd_vc == NULL) - return ENOTCONN; + if (sdp->sd_share) { + error = EISCONN; + goto out; + } + if (sdp->sd_vc == NULL) { + error = ENOTCONN; + goto out; + } error = smb_usr_openshare(sdp->sd_vc, - (struct smbioc_oshare*)data, &scred, &ssp); + (struct smbioc_oshare*)data, scred, &ssp); if (error) break; sdp->sd_share = ssp; @@ -225,16 +235,20 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre sdp->sd_level = SMBL_SHARE; break; case SMBIOC_REQUEST: - if (sdp->sd_share == NULL) - return ENOTCONN; + if (sdp->sd_share == NULL) { + error = ENOTCONN; + goto out; + } error = smb_usr_simplerequest(sdp->sd_share, - (struct smbioc_rq*)data, &scred); + (struct smbioc_rq*)data, scred); break; case SMBIOC_T2RQ: - if (sdp->sd_share == NULL) - return ENOTCONN; + if (sdp->sd_share == NULL) { + error = ENOTCONN; + goto out; + } error = smb_usr_t2request(sdp->sd_share, - (struct smbioc_t2rq*)data, &scred); + (struct smbioc_t2rq*)data, scred); break; case SMBIOC_SETFLAGS: { struct smbioc_flags *fl = (struct smbioc_flags*)data; @@ -243,9 +257,11 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre if (fl->ioc_level == SMBL_VC) { if (fl->ioc_mask & SMBV_PERMANENT) { on = fl->ioc_flags & SMBV_PERMANENT; - if ((vcp = sdp->sd_vc) == NULL) - return ENOTCONN; - error = smb_vc_get(vcp, LK_EXCLUSIVE, &scred); + if ((vcp = sdp->sd_vc) == NULL) { + error = ENOTCONN; + goto out; + } + error = smb_vc_get(vcp, LK_EXCLUSIVE, scred); if (error) break; if (on && (vcp->obj.co_flags & SMBV_PERMANENT) == 0) { @@ -253,17 +269,19 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre smb_vc_ref(vcp); } else if (!on && (vcp->obj.co_flags & SMBV_PERMANENT)) { vcp->obj.co_flags &= ~SMBV_PERMANENT; - smb_vc_rele(vcp, &scred); + smb_vc_rele(vcp, scred); } - smb_vc_put(vcp, &scred); + smb_vc_put(vcp, scred); } else error = EINVAL; } else if (fl->ioc_level == SMBL_SHARE) { if (fl->ioc_mask & SMBS_PERMANENT) { on = fl->ioc_flags & SMBS_PERMANENT; - if ((ssp = sdp->sd_share) == NULL) - return ENOTCONN; - error = smb_share_get(ssp, LK_EXCLUSIVE, &scred); + if ((ssp = sdp->sd_share) == NULL) { + error = ENOTCONN; + goto out; + } + error = smb_share_get(ssp, LK_EXCLUSIVE, scred); if (error) break; if (on && (ssp->obj.co_flags & SMBS_PERMANENT) == 0) { @@ -271,9 +289,9 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre smb_share_ref(ssp); } else if (!on && (ssp->obj.co_flags & SMBS_PERMANENT)) { ssp->obj.co_flags &= ~SMBS_PERMANENT; - smb_share_rele(ssp, &scred); + smb_share_rele(ssp, scred); } - smb_share_put(ssp, &scred); + smb_share_put(ssp, scred); } else error = EINVAL; break; @@ -282,11 +300,13 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre break; } case SMBIOC_LOOKUP: - if (sdp->sd_vc || sdp->sd_share) - return EISCONN; + if (sdp->sd_vc || sdp->sd_share) { + error = EISCONN; + goto out; + } vcp = NULL; ssp = NULL; - error = smb_usr_lookup((struct smbioc_lookup*)data, &scred, &vcp, &ssp); + error = smb_usr_lookup((struct smbioc_lookup*)data, scred, &vcp, &ssp); if (error) break; if (vcp) { @@ -305,8 +325,10 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre struct uio auio; struct iovec iov; - if ((ssp = sdp->sd_share) == NULL) - return ENOTCONN; + if ((ssp = sdp->sd_share) == NULL) { + error = ENOTCONN; + goto out; + } iov.iov_base = rwrq->ioc_base; iov.iov_len = rwrq->ioc_cnt; auio.uio_iov = &iov; @@ -317,15 +339,17 @@ nsmb_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thre auio.uio_rw = (cmd == SMBIOC_READ) ? UIO_READ : UIO_WRITE; auio.uio_td = td; if (cmd == SMBIOC_READ) - error = smb_read(ssp, rwrq->ioc_fh, &auio, &scred); + error = smb_read(ssp, rwrq->ioc_fh, &auio, scred); else - error = smb_write(ssp, rwrq->ioc_fh, &auio, &scred); + error = smb_write(ssp, rwrq->ioc_fh, &auio, scred); rwrq->ioc_cnt -= auio.uio_resid; break; } default: error = ENODEV; } +out: + free(scred, M_NSMBDEV); return error; } diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c index ce52544da62c..a7c7e05b351d 100644 --- a/sys/netsmb/smb_trantcp.c +++ b/sys/netsmb/smb_trantcp.c @@ -192,8 +192,8 @@ bad: static int nbssn_rq_request(struct nbpcb *nbp, struct thread *td) { - struct mbchain mb, *mbp = &mb; - struct mdchain md, *mdp = &md; + struct mbchain *mbp; + struct mdchain *mdp; struct mbuf *m0; struct timeval tv; struct sockaddr_in sin; @@ -201,9 +201,14 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td) u_int8_t rpcode; int error, rplen; + mbp = malloc(sizeof(struct mbchain), M_NBDATA, M_WAITOK); + mdp = malloc(sizeof(struct mbchain), M_NBDATA, M_WAITOK); error = mb_init(mbp); - if (error) + if (error) { + free(mbp, M_NBDATA); + free(mdp, M_NBDATA); return error; + } mb_put_uint32le(mbp, 0); nb_put_name(mbp, nbp->nbp_paddr); nb_put_name(mbp, nbp->nbp_laddr); @@ -214,19 +219,26 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td) } mb_detach(mbp); mb_done(mbp); - if (error) + free(mbp, M_NBDATA); + if (error) { + free(mdp, M_NBDATA); return error; + } TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo); error = selsocket(nbp->nbp_tso, POLLIN, &tv, td); if (error == EWOULDBLOCK) { /* Timeout */ NBDEBUG("initial request timeout\n"); + free(mdp, M_NBDATA); return ETIMEDOUT; } - if (error) /* restart or interrupt */ + if (error) { /* restart or interrupt */ + free(mdp, M_NBDATA); return error; + } error = nbssn_recv(nbp, &m0, &rplen, &rpcode, td); if (error) { NBDEBUG("recv() error %d\n", error); + free(mdp, M_NBDATA); return error; } /* @@ -264,6 +276,7 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td) } while(0); if (m0) md_done(mdp); + free(mdp, M_NBDATA); return error; } diff --git a/sys/netsmb/smb_usr.c b/sys/netsmb/smb_usr.c index b5388079052c..6c3e6b1f8358 100644 --- a/sys/netsmb/smb_usr.c +++ b/sys/netsmb/smb_usr.c @@ -127,8 +127,8 @@ smb_usr_lookup(struct smbioc_lookup *dp, struct smb_cred *scred, struct smb_vc **vcpp, struct smb_share **sspp) { struct smb_vc *vcp = NULL; - struct smb_vcspec vspec; - struct smb_sharespec sspec, *sspecp = NULL; + struct smb_vcspec vspec; /* XXX */ + struct smb_sharespec sspec, *sspecp = NULL; /* XXX */ int error; if (dp->ioc_level < SMBL_VC || dp->ioc_level > SMBL_SHARE) @@ -212,7 +212,7 @@ int smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp, struct smb_cred *scred) { - struct smb_rq rq, *rqp = &rq; + struct smb_rq *rqp; struct mbchain *mbp; struct mdchain *mdp; u_int8_t wc; @@ -231,9 +231,12 @@ smb_usr_simplerequest(struct smb_share *ssp, struct smbioc_rq *dp, case SMB_COM_TREE_CONNECT_ANDX: return EPERM; } + rqp = malloc(sizeof(struct smb_rq), M_SMBTEMP, M_WAITOK); error = smb_rq_init(rqp, SSTOCP(ssp), dp->ioc_cmd, scred); - if (error) + if (error) { + free(rqp, M_SMBTEMP); return error; + } mbp = &rqp->sr_rq; smb_rq_wstart(rqp); error = mb_put_mem(mbp, dp->ioc_twords, dp->ioc_twc * 2, MB_MUSER); @@ -271,6 +274,7 @@ bad: dp->ioc_serror = rqp->sr_serror; dp->ioc_error = rqp->sr_error; smb_rq_done(rqp); + free(rqp, M_SMBTEMP); return error; } @@ -292,15 +296,18 @@ int smb_usr_t2request(struct smb_share *ssp, struct smbioc_t2rq *dp, struct smb_cred *scred) { - struct smb_t2rq t2, *t2p = &t2; + struct smb_t2rq *t2p; struct mdchain *mdp; int error, len; if (dp->ioc_setupcnt > 3) return EINVAL; + t2p = malloc(sizeof(struct smb_t2rq), M_SMBTEMP, M_WAITOK); error = smb_t2_init(t2p, SSTOCP(ssp), dp->ioc_setup[0], scred); - if (error) + if (error) { + free(t2p, M_SMBTEMP); return error; + } len = t2p->t2_setupcount = dp->ioc_setupcnt; if (len > 1) t2p->t2_setupdata = dp->ioc_setup; @@ -351,5 +358,6 @@ bad: if (t2p->t_name) smb_strfree(t2p->t_name); smb_t2_done(t2p); + free(t2p, M_SMBTEMP); return error; }