diff --git a/src/viced/callback.c b/src/viced/callback.c index 5c3cec0075..790744c863 100644 --- a/src/viced/callback.c +++ b/src/viced/callback.c @@ -1944,7 +1944,9 @@ cb_stateVerifyFEHash(struct fs_dump_state * state) { int ret = 0, i; struct FileEntry * fe; - afs_uint32 fei, chain_len; + afs_uint32 fei, chain_len, max_FEs; + + max_FEs = cbstuff.nblks; for (i = 0; i < FEHASH_SIZE; i++) { chain_len = 0; @@ -1959,9 +1961,9 @@ cb_stateVerifyFEHash(struct fs_dump_state * state) if (cb_stateVerifyFE(state, fe)) { ret = 1; } - if (chain_len > FS_STATE_FE_MAX_HASH_CHAIN_LEN) { + if (chain_len > max_FEs) { ViceLog(0, ("cb_stateVerifyFEHash: error: hash chain %d length exceeds %d; assuming there's a loop\n", - i, FS_STATE_FE_MAX_HASH_CHAIN_LEN)); + i, max_FEs)); ret = 1; break; } @@ -1998,9 +2000,10 @@ static int cb_stateVerifyFCBList(struct fs_dump_state * state, struct FileEntry * fe) { int ret = 0; - afs_uint32 cbi, fei, chain_len = 0; + afs_uint32 cbi, fei, chain_len = 0, max_CBs; struct CallBack * cb; + max_CBs = cbstuff.nblks; fei = fetoi(fe); for (cbi = fe->firstcb, cb = itocb(cbi); @@ -2017,9 +2020,9 @@ cb_stateVerifyFCBList(struct fs_dump_state * state, struct FileEntry * fe) fei, cb->fhead)); ret = 1; } - if (chain_len > FS_STATE_FCB_MAX_LIST_LEN) { + if (chain_len > max_CBs) { ViceLog(0, ("cb_stateVerifyFCBList: error: list length exceeds %d (fei=%d); assuming there's a loop\n", - FS_STATE_FCB_MAX_LIST_LEN, fei)); + max_CBs, fei)); ret = 1; goto done; } @@ -2040,9 +2043,10 @@ int cb_stateVerifyHCBList(struct fs_dump_state * state, struct host * host) { int ret = 0; - afs_uint32 hi, chain_len, cbi; + afs_uint32 hi, chain_len, cbi, max_CBs; struct CallBack *cb, *ncb; + max_CBs = cbstuff.nblks; hi = h_htoi(host); chain_len = 0; @@ -2078,9 +2082,10 @@ cb_stateVerifyHCBList(struct fs_dump_state * state, struct host * host) ret = 1; goto done; } - if (chain_len > FS_STATE_HCB_MAX_LIST_LEN) { + + if (chain_len > max_CBs) { ViceLog(0, ("cb_stateVerifyHCBList: error: list length exceeds %d (h->index=%d); assuming there's a loop\n", - FS_STATE_HCB_MAX_LIST_LEN, hi)); + max_CBs, hi)); ret = 1; goto done; } @@ -2095,9 +2100,11 @@ static int cb_stateVerifyTimeoutQueues(struct fs_dump_state * state) { int ret = 0, i; - afs_uint32 cbi, chain_len; + afs_uint32 cbi, chain_len, max_CBs; struct CallBack *cb, *ncb; + max_CBs = cbstuff.nblks; + for (i = 0; i < CB_NUM_TIMEOUT_QUEUES; i++) { chain_len = 0; for (cbi = timeout[i], cb = itocb(cbi); @@ -2138,9 +2145,10 @@ cb_stateVerifyTimeoutQueues(struct fs_dump_state * state) ret = 1; break; } - if (chain_len > FS_STATE_TCB_MAX_LIST_LEN) { + + if (chain_len > max_CBs) { ViceLog(0, ("cb_stateVerifyTimeoutQueues: list length exceeds %d (tindex=%d); assuming there's a loop\n", - FS_STATE_TCB_MAX_LIST_LEN, i)); + max_CBs, i)); ret = 1; break; } diff --git a/src/viced/host.c b/src/viced/host.c index cfa7a55947..a4f8a6c110 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -3284,6 +3284,21 @@ h_stateVerify(struct fs_dump_state * state) return state->bail; } +static int +h_stateVerifyMaxHosts(struct fs_dump_state * state, int *a_maxHosts) +{ + if (state->mode == FS_STATE_DUMP_MODE) { + *a_maxHosts = hostCount; /* state not fully populated yet */ + return 0; + } else if (state->mode == FS_STATE_LOAD_MODE) { + *a_maxHosts = state->h_hdr->records; + return 0; + } else { + ViceLog(0, ("h_stateVerifyMaxHosts: bad state mode %d\n", state->mode)); + return 1; + } +} + static int h_stateVerifyHost(struct host * h, void* rock) { @@ -3344,7 +3359,13 @@ h_stateVerifyAddrHash(struct fs_dump_state * state, struct host * h, struct h_AddrHashChain *chain; int index = h_HashIndex(addr); char tmp[16]; - int chain_len = 0; + int chain_len = 0, maxHosts; + + ret = h_stateVerifyMaxHosts(state, &maxHosts); + if (ret != 0) { + ret = 1; + goto done; + } for (chain = hostAddrHashTable[index]; chain; chain = chain->next) { host = chain->hostPtr; @@ -3375,9 +3396,9 @@ h_stateVerifyAddrHash(struct fs_dump_state * state, struct host * h, found = 1; break; } - if (chain_len > FS_STATE_H_MAX_ADDR_HASH_CHAIN_LEN) { + if (chain_len > maxHosts) { ViceLog(0, ("h_stateVerifyAddrHash: error: hash chain length exceeds %d; assuming there's a loop\n", - FS_STATE_H_MAX_ADDR_HASH_CHAIN_LEN)); + maxHosts)); ret = 1; goto done; } @@ -3416,7 +3437,13 @@ h_stateVerifyUuidHash(struct fs_dump_state * state, struct host * h) afsUUID * uuidp = &h->z.interface->uuid; int index = h_UuidHashIndex(uuidp); struct uuid_fmtbuf tmp; - int chain_len = 0; + int chain_len = 0, maxHosts; + + ret = h_stateVerifyMaxHosts(state, &maxHosts); + if (ret != 0) { + ret = 1; + goto done; + } for (chain = hostUuidHashTable[index]; chain; chain = chain->next) { host = chain->hostPtr; @@ -3436,9 +3463,9 @@ h_stateVerifyUuidHash(struct fs_dump_state * state, struct host * h) } goto done; } - if (chain_len > FS_STATE_H_MAX_UUID_HASH_CHAIN_LEN) { + if (chain_len > maxHosts) { ViceLog(0, ("h_stateVerifyUuidHash: error: hash chain length exceeds %d; assuming there's a loop\n", - FS_STATE_H_MAX_UUID_HASH_CHAIN_LEN)); + maxHosts)); ret = 1; goto done; } @@ -3491,6 +3518,11 @@ h_stateCheckHeader(struct host_state_header * hdr) ViceLog(0, ("check_host_state_header: unknown version number\n")); ret = 1; } + else if (hdr->records > FS_STATE_H_MAX_LIST_LEN) { + ViceLog(0, ("check_host_state_header: saved host state too large " + "(%d > %d)\n", hdr->records, FS_STATE_H_MAX_LIST_LEN)); + ret = 1; + } return ret; } diff --git a/src/viced/serialize_state.h b/src/viced/serialize_state.h index 1e906b8cbb..ad5d5a3d90 100644 --- a/src/viced/serialize_state.h +++ b/src/viced/serialize_state.h @@ -216,13 +216,7 @@ struct idx_map_entry_t { * make them fairly large so we don't get * false positives */ -#define FS_STATE_H_MAX_UUID_HASH_CHAIN_LEN 100000 /* max elements in a host uuid-hash chain */ -#define FS_STATE_H_MAX_ADDR_HASH_CHAIN_LEN 2000000 /* max elements in a host ipv4-hash chain */ -#define FS_STATE_FE_MAX_HASH_CHAIN_LEN 100000 /* max elements in a FE fid-hash chain */ -#define FS_STATE_FCB_MAX_LIST_LEN 100000 /* max elements in a per-FE CB list */ -#define FS_STATE_HCB_MAX_LIST_LEN 100000 /* max elements in a per-host CB list */ -#define FS_STATE_TCB_MAX_LIST_LEN 100000 /* max elements in a per-timeout CB list */ - +#define FS_STATE_H_MAX_LIST_LEN 100000000 /* max number of hosts (100M) */ /* * main state serialization state structure