Bash script to detect bad checks of mmap() return value
The mmap() POSIX function returns MAP_FAILED or -1 when an error occurs. A common mistake is to check the return value for 0 instead. This script tries to heuristically find such bugs in an automated way.
- efivar: rhboot/efivar#152
- GNOME/gvfs: https://gitlab.gnome.org/GNOME/gvfs/-/issues/477
- Geeqie: BestImageViewer/geeqie#771
- ZoneDetect: BertoldVdb/ZoneDetect#26
- GDB: https://sourceware.org/bugzilla/show_bug.cgi?id=26016
- GNOME/gdk-pixbuf: https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/issues/158
- KDE/kwayland: https://bugs.kde.org/show_bug.cgi?id=421868
- Mesa: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5150
- QEMU: https://bugs.launchpad.net/qemu/+bug/1879998
- GNOME/Tracker: https://gitlab.gnome.org/GNOME/tracker-miners/-/merge_requests/201
Article (in German):
Cppcheck is capable of detecting bad checks of mmap-return values as well. Before the checking can begin, the tool must be prepared by building from source having 'HAVE_RULES=yes'-option activated. Once enabled, Cppcheck is equipped with a "rules"-feature, where the user can provide custom PCRE-regex-expressions to match bug-prone patterns. Detailed installation instructions for common platforms are available here.
After successful building with "rules"-feature enabled, Cppcheck can be executed with a rule-file to detected bad checks of mmap:
$ cppcheck --enable=all --rule-file=cppcheck/mmap.xml --template=cppcheck1 test/
Checking test/bad 2.c ...
[test/bad 2.c:14]: (warning) mmap returns 'MAP_FAILED (=-1)' in case of an error. Checking against '0' is wrong.
1/3 files checked 33% done
Checking test/bad.c ...
[test/bad.c:14]: (warning) mmap returns 'MAP_FAILED (=-1)' in case of an error. Checking against '0' is wrong.
2/3 files checked 66% done
Checking test/good.c ...
3/3 files checked 100% done
: (information) Cppcheck cannot find all the include files (use --check-config for details)
-
Findings: Skiboot: open-power/skiboot#255
-
Further reading: Tutorials about writing Cppcheck-rules: 1, 2