Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix clang static analyzer false positive #180

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

inye
Copy link

@inye inye commented Jul 29, 2019

Fixes #128. Clang static analyzer was thinking that it's possible to
free() list head without updating head pointer. This assert assures
static analyzer that branch without head pointer update could be taken
only when we are freeing non-head element.

Fixes troydhanson#128. Clang static analyzer was thinking that it's possible to
free() list head without updating head pointer. This assert assures
static analyzer that branch without head pointer update could be taken
only when we are freeing non-head element.
@Scorbutics
Copy link

Hello,
I'm quite interested in this Merge request in order to keep scan-build quiet on the uthash part.
Are there any plan of merging it soon ?
Thank you

@@ -473,6 +473,7 @@ do {
(head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \
} \
if (_hd_hh_del->prev != NULL) { \
assert(&(head)->hh != _hd_hh_del); \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern with this one is that it's introducing assert (and <assert.h>) into "uthash.h", which historically hasn't been the case. I know "utlist.h" uses <assert.h>, but "uthash.h" itself has a lot more users than "utlist.h", so I'm leery of introducing new header dependencies (even if they are C89 standard) and especially new runtime dependencies (e.g. you're introducing a hidden dependency on the libc's abort function, right?).

Is there any way to silence scan-build's warning here with core-language features instead of assert?

I even wonder if we could just change line 475 from if (_hd_hh_del->prev != NULL) to if (_hd_hh_del != &(head)->hh) — does that work? It shouldn't really be any less efficient, since we have to load (head)->hh on line 476 anyway.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I'd also be extremely interested in PRs against our .travis.yml file so that we could actually test the scan-build build against regressions in this area. Any takers?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I even wonder if we could just change line 475 from if (_hd_hh_del->prev != NULL) to if (_hd_hh_del != &(head)->hh) — does that work?

Nope, this introduced a new warning warning: Dereference of null pointer [clang-analyzer-core.NullDereference].

Using the assert and including <assert.h> in uthash.h solved the problem, can we go ahead with that fix?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

including <assert.h> in uthash.h solved the problem, can we go ahead with that fix?

No.

Any volunteers to add scan-build into .travis.yml?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can take a stab

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I'm able to reproduce locally (thanks @chaitu-tk!) I see that we could silence the false positives on test15, test40, and test59 by adding assert((delptr) != (head)) at the end of HASH_DELETE — i.e., "after deleting an item from the hash table, the deleted item is no longer in the table at all, let alone at the front of the table."

Except that this breaks test18, because we want to permit HASH_DEL(table, table) to mean "delete the first item in the table." And anyway, I still don't want to add a dependency on <assert.h> to uthash.

I've just fixed some low-hanging fruit in 45af88c and f0e1bd9 (which I'll merge up to this repo once Travis passes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang reports use after free when deleting all hashmap contents
4 participants