From ac5346c3703e199eaabf8eeb7e156e42644092c4 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 2 Aug 2007 21:57:38 +0000 Subject: [PATCH] windows-no-more-infinite-recursion-20070802 FIXES 15855 In cm_NameI, keep track of what fids were crossed when evaluating the path. If we discover a loop return a CM_ERROR_TOO_MANY_SYMLINKS error. This resolves the complaint that when infinite loops are hit in the afs name space the afsd_service.exe process uses 100% of the CPU. --- src/WINNT/afsd/cm_vnodeops.c | 42 +++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 60e895d4f..9103162d7 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1786,6 +1786,10 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, int symlinkCount; /* count of # of symlinks traversed */ int extraFlag; /* avoid chasing mt pts for dir cmd */ int phase = 1; /* 1 = tidPathp, 2 = pathp */ +#define MAX_FID_COUNT 512 + cm_fid_t fids[MAX_FID_COUNT]; /* array of fids processed in this path walk */ + int fid_count = 0; /* number of fids processed in this path walk */ + int i; #ifdef DEBUG_REFCOUNT afsi_log("%s:%d cm_NameI rootscp 0x%p ref %d", file, line, rootSCachep, rootSCachep->refCount); @@ -1849,7 +1853,22 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, code = cm_Lookup(tscp, component, flags | extraFlag, userp, reqp, &nscp); - if (code) { + + if (code == 0) { + for ( i=0; ifid, &fids[i]) ) { + code = CM_ERROR_TOO_MANY_SYMLINKS; + cm_ReleaseSCache(nscp); + nscp = NULL; + break; + } + } + if (i == fid_count && fid_count < MAX_FID_COUNT) { + fids[fid_count++] = nscp->fid; + } + } + + if (code) { cm_ReleaseSCache(tscp); if (dirScp) cm_ReleaseSCache(dirScp); @@ -1917,6 +1936,21 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, else restp = tp; code = cm_AssembleLink(tscp, restp, &linkScp, &tempsp, userp, reqp); + + if (code == 0 && linkScp != NULL) { + for ( i=0; ifid, &fids[i]) ) { + code = CM_ERROR_TOO_MANY_SYMLINKS; + cm_ReleaseSCache(linkScp); + nscp = NULL; + break; + } + } + if (i == fid_count && fid_count < MAX_FID_COUNT) { + fids[fid_count++] = linkScp->fid; + } + } + if (code) { /* something went wrong */ cm_ReleaseSCache(tscp); @@ -2049,6 +2083,12 @@ long cm_EvaluateSymLink(cm_scache_t *dscp, cm_scache_t *linkScp, cm_FreeSpace(spacep); cm_ReleaseSCache(newRootScp); + if (linkScp == *outScpp) { + cm_ReleaseSCache(*outScpp); + *outScpp = NULL; + code = CM_ERROR_NOSUCHPATH; + } + return code; } -- 2.39.5