From 04de939e4200d15dce0c95f0132b377c5a0d8a11 Mon Sep 17 00:00:00 2001 From: Sears Russell Date: Wed, 21 Apr 2010 21:34:00 +0000 Subject: [PATCH] fix null pointer derefence in lruFast.c; add unit tests to check for this bug --- src/stasis/replacementPolicy/lruFast.c | 8 ++-- test/stasis/check_replacementPolicy.c | 53 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/stasis/replacementPolicy/lruFast.c b/src/stasis/replacementPolicy/lruFast.c index 2ba1cdd..ae8015f 100644 --- a/src/stasis/replacementPolicy/lruFast.c +++ b/src/stasis/replacementPolicy/lruFast.c @@ -45,9 +45,11 @@ static void* remove(struct replacementPolicy* r, void * p) { static void* getStaleAndRemove(struct replacementPolicy* r) { lruFast * l = r->impl; void * ret = LL_ENTRY(shift)(l->lru); - l->setNode(ret, 0, l->conf); - assert(!(*l->derefCount(ret))); - (*l->derefCount(ret))++; + if(ret) { + l->setNode(ret, 0, l->conf); + assert(!(*l->derefCount(ret))); + (*l->derefCount(ret))++; + } return ret; } static void insert(struct replacementPolicy* r, void * p) { diff --git a/test/stasis/check_replacementPolicy.c b/test/stasis/check_replacementPolicy.c index 5bc4cd0..aa1666f 100644 --- a/test/stasis/check_replacementPolicy.c +++ b/test/stasis/check_replacementPolicy.c @@ -130,6 +130,29 @@ void randomTest(replacementPolicy * lru, unsigned long count) { } } } + +void fillThenEmptyTest(replacementPolicy *lru) { + for(int i = 0; i < OBJECT_COUNT; i++) { + lru->insert(lru, &t[i]); + } + int j = 0; + while(lru->getStaleAndRemove(lru)) { + j++; + } + assert(0 == lru->getStaleAndRemove(lru)); + assert(0 == lru->getStale(lru)); + assert(j == OBJECT_COUNT); + for(int i = 0; i < OBJECT_COUNT; i++) { + lru->insert(lru, &t[i]); + lru->remove(lru, &t[i]); + } + j = 0; + while(lru->getStaleAndRemove(lru)) { + j++; + } + assert(j == 0); +} + START_TEST(replacementPolicyLRURandomTest) { replacementPolicy * lru = lruFastInit(getKey, setKey, pinCount, 0); threaded = 0; @@ -216,6 +239,33 @@ START_TEST(replacementPolicyConcurrentThreadTest) { cwLru->deinit(cwLru); randomTeardown(); } END_TEST +START_TEST(replacementPolicyEmptyFastLRUTest) { + randomSetup(); + replacementPolicy *rp = lruFastInit(getKey, setKey, pinCount, 0); + fillThenEmptyTest(rp); + rp->deinit(rp); + randomTeardown(); +} END_TEST +START_TEST(replacementPolicyEmptyThreadsafeTest) { + randomSetup(); + replacementPolicy *rpA = lruFastInit(getKey, setKey, pinCount, 0); + replacementPolicy *rp = replacementPolicyThreadsafeWrapperInit(rpA); + fillThenEmptyTest(rp); + rp->deinit(rp); + randomTeardown(); +} END_TEST +START_TEST(replacementPolicyEmptyConcurrentTest) { + randomSetup(); + replacementPolicy *rpA[THREAD_COUNT]; + for(int i = 0; i < THREAD_COUNT; i++) { + rpA[i] = lruFastInit(getKey, setKey, pinCount, 0); + } + replacementPolicy *rp + = replacementPolicyConcurrentWrapperInit(rpA, THREAD_COUNT); + fillThenEmptyTest(rp); + rp->deinit(rp); + randomTeardown(); +} END_TEST Suite * check_suite(void) { Suite *s = suite_create("replacementPolicy"); @@ -223,6 +273,9 @@ Suite * check_suite(void) { TCase *tc = tcase_create("multithreaded"); tcase_set_timeout(tc, 1200); // twenty minute timeout /* Sub tests are added, one per line, here */ + tcase_add_test(tc, replacementPolicyEmptyFastLRUTest); + tcase_add_test(tc, replacementPolicyEmptyThreadsafeTest); + tcase_add_test(tc, replacementPolicyEmptyConcurrentTest); tcase_add_test(tc, replacementPolicyLRURandomTest); tcase_add_test(tc, replacementPolicyLRUFastRandomTest); tcase_add_test(tc, replacementPolicyThreadsafeRandomTest);