From bf6c13352abf39e53e723e60aae11d6e246c0cfd Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 11 Sep 2007 06:02:42 +0000 Subject: [PATCH] windows-prefetch-executables-20070911 avoid prefetch race condition in CreateX functions do not permit reference underflow when ending background prefetch ops --- src/WINNT/afsd/cm_dcache.c | 11 +++++++++-- src/WINNT/afsd/smb3.c | 18 +++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 458267818..91fb7d46a 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -702,8 +702,10 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af if (code || (bp->cmFlags & CM_BUF_CMFETCHING)) { code = 0; - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } break; } @@ -719,8 +721,10 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af cm_ClearPrefetchFlag(LargeIntegerGreaterThanZero(fetched) ? 0 : code, scp, &base, &fetched); lock_ReleaseMutex(&scp->mx); - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } osi_Log4(afsd_logp, "Ending BKG prefetch scp 0x%p, code %d bytes 0x%x:%x", scp, code, fetched.HighPart, fetched.LowPart); @@ -830,6 +834,7 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, if (code) { lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + bufp = NULL; buf_UnreserveBuffers(cm_chunkSize / cm_data.buf_blockSize); return code; } @@ -1093,6 +1098,7 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, } buf_Release(tbp); + tbp = NULL; pageBase = LargeIntegerAdd(tblocksize, pageBase); collected += cm_data.buf_blockSize; @@ -1214,6 +1220,7 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, &qdp->q); osi_QDFree(qdp); buf_Release(tbp); + tbp = NULL; } /* Caller expects this */ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index f9f9301ba..767176574 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -2775,8 +2775,10 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t code = CM_ERROR_NOSUCHFILE; else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { cm_buf_t *bp = buf_Find(dscp, &hzero); - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } else code = CM_ERROR_NOSUCHFILE; } @@ -3043,8 +3045,10 @@ long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet code = CM_ERROR_NOSUCHFILE; else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { cm_buf_t *bp = buf_Find(dscp, &hzero); - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } else code = CM_ERROR_NOSUCHFILE; } @@ -7209,15 +7213,16 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) (scp->fileType == CM_SCACHETYPE_DIRECTORY || scp->fileType == CM_SCACHETYPE_MOUNTPOINT || scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); /* is a dir? */ - lock_ReleaseMutex(&scp->mx); smb_SetSMBDataLength(outp, 0); if ((fidp->flags & SMB_FID_EXECUTABLE) && - LargeIntegerGreaterThanZero(fidp->scp->length)) { + LargeIntegerGreaterThanZero(fidp->scp->length) && + !(scp->flags & CM_SCACHEFLAG_PREFETCHING)) { cm_QueueBKGRequest(fidp->scp, cm_BkgPrefetch, 0, 0, fidp->scp->length.LowPart, fidp->scp->length.HighPart, userp); } + lock_ReleaseMutex(&scp->mx); osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid, osi_LogSaveString(smb_logp, realPathp)); @@ -7945,12 +7950,15 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out lock_ReleaseMutex(&scp->mx); } + lock_ObtainMutex(&scp->mx); if ((fidp->flags & SMB_FID_EXECUTABLE) && - LargeIntegerGreaterThanZero(fidp->scp->length)) { + LargeIntegerGreaterThanZero(fidp->scp->length) && + !(scp->flags & CM_SCACHEFLAG_PREFETCHING)) { cm_QueueBKGRequest(fidp->scp, cm_BkgPrefetch, 0, 0, fidp->scp->length.LowPart, fidp->scp->length.HighPart, userp); } + lock_ReleaseMutex(&scp->mx); osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid); -- 2.39.5