From 5dee9ac3468f9d5a929f9b42bd671411e38092fb Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 29 Jun 2013 00:26:52 -0400 Subject: [PATCH] Windows: validate pointer consistency When cm_ValidateCache() is executed validate pointers to ensure that they are in the valid range for the class of pointer. Change-Id: I151489010430919999af85843079f81143359739 Reviewed-on: http://gerrit.openafs.org/10040 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_aclent.c | 48 ++++++++++++++++++++++++++++++ src/WINNT/afsd/cm_buf.c | 40 +++++++++++++++++++++++++ src/WINNT/afsd/cm_cell.c | 16 ++++++++++ src/WINNT/afsd/cm_scache.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++ src/WINNT/afsd/cm_volume.c | 25 ++++++++++++++++ 5 files changed, 202 insertions(+) diff --git a/src/WINNT/afsd/cm_aclent.c b/src/WINNT/afsd/cm_aclent.c index 2a67053..52c541b 100644 --- a/src/WINNT/afsd/cm_aclent.c +++ b/src/WINNT/afsd/cm_aclent.c @@ -249,16 +249,40 @@ long cm_ValidateACLCache(void) for ( aclp = cm_data.aclLRUp, count = 0; aclp; aclp = (cm_aclent_t *) osi_QNext(&aclp->q), count++ ) { + + if ( aclp < (cm_aclent_t *)cm_data.aclBaseAddress || + aclp >= (cm_aclent_t *)cm_data.scacheBaseAddress) { + afsi_log("cm_ValidateACLCache failure: out of range cm_aclent_t pointers"); + fprintf(stderr, "cm_ValidateACLCache failure: out of range cm_aclent_t pointers\n"); + return -10; + } + if (aclp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: acpl->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: acpl->magic != CM_ACLENT_MAGIC\n"); return -1; } + + if ( aclp->nextp < (cm_aclent_t *)cm_data.aclBaseAddress || + aclp->nextp >= (cm_aclent_t *)cm_data.scacheBaseAddress) { + afsi_log("cm_ValidateACLCache failure: out of range cm_aclent_t pointers"); + fprintf(stderr, "cm_ValidateACLCache failure: out of range cm_aclent_t pointers\n"); + return -11; + } + if (aclp->nextp && aclp->nextp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: acpl->nextp->magic != CM_ACLENT_MAGIC"); fprintf(stderr,"cm_ValidateACLCache failure: acpl->nextp->magic != CM_ACLENT_MAGIC\n"); return -2; } + + if ( aclp->backp < (cm_scache_t *)cm_data.scacheBaseAddress || + aclp->backp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateACLCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateACLCache failure: out of range cm_scache_t pointers\n"); + return -12; + } + if (aclp->backp && aclp->backp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateACLCache failure: acpl->backp->magic != CM_SCACHE_MAGIC"); fprintf(stderr,"cm_ValidateACLCache failure: acpl->backp->magic != CM_SCACHE_MAGIC\n"); @@ -273,16 +297,40 @@ long cm_ValidateACLCache(void) for ( aclp = cm_data.aclLRUEndp, count = 0; aclp; aclp = (cm_aclent_t *) osi_QPrev(&aclp->q), count++ ) { + + if ( aclp < (cm_aclent_t *)cm_data.aclBaseAddress || + aclp >= (cm_aclent_t *)cm_data.scacheBaseAddress) { + afsi_log("cm_ValidateACLCache failure: out of range cm_aclent_t pointers"); + fprintf(stderr, "cm_ValidateACLCache failure: out of range cm_aclent_t pointers\n"); + return -13; + } + if (aclp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: aclp->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: aclp->magic != CM_ACLENT_MAGIC\n"); return -5; } + + if ( aclp->nextp < (cm_aclent_t *)cm_data.aclBaseAddress || + aclp->nextp >= (cm_aclent_t *)cm_data.scacheBaseAddress) { + afsi_log("cm_ValidateACLCache failure: out of range cm_aclent_t pointers"); + fprintf(stderr, "cm_ValidateACLCache failure: out of range cm_aclent_t pointers\n"); + return -14; + } + if (aclp->nextp && aclp->nextp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: aclp->nextp->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: aclp->nextp->magic != CM_ACLENT_MAGIC\n"); return -6; } + + if ( aclp->backp < (cm_scache_t *)cm_data.scacheBaseAddress || + aclp->backp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateACLCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateACLCache failure: out of range cm_scache_t pointers\n"); + return -15; + } + if (aclp->backp && aclp->backp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateACLCache failure: aclp->backp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: aclp->backp->magic != CM_SCACHE_MAGIC\n"); diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 418146e..184ced3 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -348,6 +348,14 @@ buf_ValidateBuffers(void) } for (bp = cm_data.buf_freeListEndp; bp; bp=(cm_buf_t *) osi_QPrev(&bp->q)) { + + if ( bp < (cm_buf_t *)cm_data.bufHeaderBaseAddress || + bp >= (cm_buf_t *)cm_data.bufDataBaseAddress) { + afsi_log("cm_ValidateBuffers failure: out of range cm_buf_t pointers"); + fprintf(stderr, "cm_ValidateBuffers failure: out of range cm_buf_t pointers\n"); + return -11; + } + if (bp->magic != CM_BUF_MAGIC) { afsi_log("cm_ValidateBuffers failure: bp->magic != CM_BUF_MAGIC"); fprintf(stderr, "cm_ValidateBuffers failure: bp->magic != CM_BUF_MAGIC\n"); @@ -364,6 +372,14 @@ buf_ValidateBuffers(void) } for (bp = cm_data.buf_freeListp; bp; bp=(cm_buf_t *) osi_QNext(&bp->q)) { + + if ( bp < (cm_buf_t *)cm_data.bufHeaderBaseAddress || + bp >= (cm_buf_t *)cm_data.bufDataBaseAddress) { + afsi_log("cm_ValidateBuffers failure: out of range cm_buf_t pointers"); + fprintf(stderr, "cm_ValidateBuffers failure: out of range cm_buf_t pointers\n"); + return -12; + } + if (bp->magic != CM_BUF_MAGIC) { afsi_log("cm_ValidateBuffers failure: bp->magic != CM_BUF_MAGIC"); fprintf(stderr, "cm_ValidateBuffers failure: bp->magic != CM_BUF_MAGIC\n"); @@ -380,6 +396,14 @@ buf_ValidateBuffers(void) } for ( bp = cm_data.buf_redirListp; bp; bp = (cm_buf_t *) osi_QNext(&bp->q)) { + + if ( bp < (cm_buf_t *)cm_data.bufHeaderBaseAddress || + bp >= (cm_buf_t *)cm_data.bufDataBaseAddress) { + afsi_log("cm_ValidateBuffers failure: out of range cm_buf_t pointers"); + fprintf(stderr, "cm_ValidateBuffers failure: out of range cm_buf_t pointers\n"); + return -13; + } + if (!(bp->qFlags & CM_BUF_QREDIR)) { afsi_log("CM_BUF_QREDIR not set on cm_buf_t in buf_redirListp"); fprintf(stderr, "CM_BUF_QREDIR not set on cm_buf_t in buf_redirListp"); @@ -394,11 +418,27 @@ buf_ValidateBuffers(void) } for (bp = cm_data.buf_allp; bp; bp=bp->allp) { + + if ( bp < (cm_buf_t *)cm_data.bufHeaderBaseAddress || + bp >= (cm_buf_t *)cm_data.bufDataBaseAddress) { + afsi_log("cm_ValidateBuffers failure: out of range cm_buf_t pointers"); + fprintf(stderr, "cm_ValidateBuffers failure: out of range cm_buf_t pointers\n"); + return -14; + } + if (bp->magic != CM_BUF_MAGIC) { afsi_log("cm_ValidateBuffers failure: bp->magic != CM_BUF_MAGIC"); fprintf(stderr, "cm_ValidateBuffers failure: bp->magic != CM_BUF_MAGIC\n"); return -3; } + + if ( bp->datap < cm_data.bufDataBaseAddress || + bp->datap >= cm_data.bufEndOfData) { + afsi_log("cm_ValidateBuffers failure: out of range data pointers"); + fprintf(stderr, "cm_ValidateBuffers failure: out of range data pointers\n"); + return -15; + } + counta++; bpa = bp; diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index 2fd0237..df7dc64 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -469,6 +469,14 @@ cm_ValidateCell(void) afs_uint32 count1, count2; for (cellp = cm_data.allCellsp, count1 = 0; cellp; cellp=cellp->allNextp, count1++) { + + if ( cellp < (cm_cell_t *)cm_data.cellBaseAddress || + cellp >= (cm_cell_t *)cm_data.aclBaseAddress) { + afsi_log("cm_ValidateCell failure: out of range cm_cell_t pointers"); + fprintf(stderr, "cm_ValidateCell failure: out of range cm_cell_t pointers\n"); + return -10; + } + if ( cellp->magic != CM_CELL_MAGIC ) { afsi_log("cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC"); fprintf(stderr, "cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC\n"); @@ -483,6 +491,14 @@ cm_ValidateCell(void) } for (cellp = cm_data.freeCellsp, count2 = 0; cellp; cellp=cellp->freeNextp, count2++) { + + if ( cellp < (cm_cell_t *)cm_data.cellBaseAddress || + cellp >= (cm_cell_t *)cm_data.aclBaseAddress) { + afsi_log("cm_ValidateCell failure: out of range cm_cell_t pointers"); + fprintf(stderr, "cm_ValidateCell failure: out of range cm_cell_t pointers\n"); + return -11; + } + if ( count2 != 0 && cellp == cm_data.freeCellsp || count2 > cm_data.maxCells ) { afsi_log("cm_ValidateCell failure: cm_data.freeCellsp infinite loop"); diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index caa2d24..a2b7be5 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -484,16 +484,40 @@ cm_ValidateSCache(void) for ( scp = cm_data.scacheLRUFirstp, lscp = NULL, i = 0; scp; lscp = scp, scp = (cm_scache_t *) osi_QNext(&scp->q), i++ ) { + + if ( scp < (cm_scache_t *)cm_data.scacheBaseAddress || + scp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n"); + return -18; + } + if (scp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n"); return -1; } + + if ( scp->nextp < (cm_scache_t *)cm_data.scacheBaseAddress || + scp->nextp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n"); + return -21; + } + if (scp->nextp && scp->nextp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC\n"); return -2; } + + if ( scp->randomACLp < (cm_aclent_t *)cm_data.aclBaseAddress || + scp->randomACLp >= (cm_aclent_t *)cm_data.scacheBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_aclent_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_aclent_t pointers\n"); + return -32; + } + if (scp->randomACLp && scp->randomACLp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n"); @@ -513,16 +537,40 @@ cm_ValidateSCache(void) for ( scp = cm_data.scacheLRULastp, lscp = NULL, i = 0; scp; lscp = scp, scp = (cm_scache_t *) osi_QPrev(&scp->q), i++ ) { + + if ( scp < (cm_scache_t *)cm_data.scacheBaseAddress || + scp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n"); + return -19; + } + if (scp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n"); return -5; } + + if ( scp->nextp < (cm_scache_t *)cm_data.scacheBaseAddress || + scp->nextp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n"); + return -22; + } + if (scp->nextp && scp->nextp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC\n"); return -6; } + + if ( scp->randomACLp < (cm_aclent_t *)cm_data.aclBaseAddress || + scp->randomACLp >= (cm_aclent_t *)cm_data.scacheBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_aclent_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_aclent_t pointers\n"); + return -31; + } + if (scp->randomACLp && scp->randomACLp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n"); @@ -543,17 +591,42 @@ cm_ValidateSCache(void) for ( i=0; i < cm_data.scacheHashTableSize; i++ ) { for ( scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp ) { afs_uint32 hash; + + if ( scp < (cm_scache_t *)cm_data.scacheBaseAddress || + scp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n"); + return -20; + } + hash = CM_SCACHE_HASH(&scp->fid); + if (scp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n"); return -9; } + + if ( scp->nextp < (cm_scache_t *)cm_data.scacheBaseAddress || + scp->nextp >= (cm_scache_t *)cm_data.dnlcBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n"); + return -23; + } + if (scp->nextp && scp->nextp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC\n"); return -10; } + + if ( scp->randomACLp < (cm_aclent_t *)cm_data.aclBaseAddress || + scp->randomACLp >= (cm_aclent_t *)cm_data.scacheBaseAddress) { + afsi_log("cm_ValidateSCache failure: out of range cm_aclent_t pointers"); + fprintf(stderr, "cm_ValidateSCache failure: out of range cm_aclent_t pointers\n"); + return -30; + } + if (scp->randomACLp && scp->randomACLp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n"); diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index 00e9407..87ad865 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -32,21 +32,46 @@ cm_ValidateVolume(void) afs_uint32 count; for (volp = cm_data.allVolumesp, count = 0; volp; volp=volp->allNextp, count++) { + + if ( volp < (cm_volume_t *)cm_data.volumeBaseAddress || + volp >= (cm_volume_t *)cm_data.cellBaseAddress) { + afsi_log("cm_ValidateVolume failure: out of range cm_volume_t pointers"); + fprintf(stderr, "cm_ValidateVolume failure: out of range cm_volume_t pointers\n"); + return -10; + } + if ( volp->magic != CM_VOLUME_MAGIC ) { afsi_log("cm_ValidateVolume failure: volp->magic != CM_VOLUME_MAGIC"); fprintf(stderr, "cm_ValidateVolume failure: volp->magic != CM_VOLUME_MAGIC\n"); return -1; } + + if ( volp->cellp < (cm_cell_t *)cm_data.cellBaseAddress || + volp->cellp >= (cm_cell_t *)cm_data.aclBaseAddress) { + afsi_log("cm_ValidateVolume failure: out of range cm_cell_t pointers"); + fprintf(stderr, "cm_ValidateVolume failure: out of range cm_cell_t pointers\n"); + return -11; + } + if ( volp->cellp && volp->cellp->magic != CM_CELL_MAGIC ) { afsi_log("cm_ValidateVolume failure: volp->cellp->magic != CM_CELL_MAGIC"); fprintf(stderr, "cm_ValidateVolume failure: volp->cellp->magic != CM_CELL_MAGIC\n"); return -2; } + + if ( volp->allNextp < (cm_volume_t *)cm_data.volumeBaseAddress || + volp->allNextp >= (cm_volume_t *)cm_data.cellBaseAddress) { + afsi_log("cm_ValidateVolume failure: out of range cm_volume_t pointers"); + fprintf(stderr, "cm_ValidateVolume failure: out of range cm_volume_t pointers\n"); + return -12; + } + if ( volp->allNextp && volp->allNextp->magic != CM_VOLUME_MAGIC ) { afsi_log("cm_ValidateVolume failure: volp->allNextp->magic != CM_VOLUME_MAGIC"); fprintf(stderr, "cm_ValidateVolume failure: volp->allNextp->magic != CM_VOLUME_MAGIC\n"); return -3; } + if ( count != 0 && volp == cm_data.allVolumesp || count > cm_data.maxVolumes ) { afsi_log("cm_ValidateVolume failure: cm_data.allVolumep loop detected"); -- 1.9.4