Created
December 19, 2019 07:52
-
-
Save scovetta/c6e759fbecf55f9d4f90a7c0229063fb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# License: MIT | |
# Author: Michael Scovetta <[email protected]> | |
import re | |
import sys | |
""" | |
Usage: | |
Do an initial grep through the source tree and xargs the results over to this script, e.g.: | |
grep -FlRi 'alloc' freebsd_src | xargs -n1 -P6 python malloc.py | |
""" | |
""" | |
The MALLOCs here are malloc-like functions. You can find some of them with this: | |
egrep -hoRi "[a-z_]*alloc\s*\(" freebsd_src | sort | uniq -c | sort -n | |
""" | |
MALLOCS = ['malloc', 'realloc', 'alloc', 'xmalloc', 'os_malloc', 'os_zalloc', '_malloc', 'g_malloc'] | |
if len(sys.argv) != 2: | |
print('Usage: python malloc_search.py filename') | |
sys.exit(1) | |
filename = sys.argv[1] | |
with open(filename) as f: | |
lines = map(str.strip, f) | |
for line_number, line in enumerate(lines): | |
for malloc in MALLOCS: | |
# First, we check to see if we match the general malloc pattern, with optional cast. | |
matches = re.match(r'.*(?:\((.+\s*\*)\)\s*)?' + malloc + r'\s*\((.+)\)\s*;$', line, re.IGNORECASE) | |
if not matches: | |
continue # Missing the initial malloc pattern | |
cast_param = matches.group(1) | |
if cast_param: | |
cast_param = cast_param.replace('*', '').strip() | |
malloc_params = matches.group(2) | |
sizeof_matches = re.search(r'sizeof\s*\(([^\)]+)\)', malloc_params) | |
if sizeof_matches: | |
sizeof_param = sizeof_matches.group(1) | |
else: | |
continue # Must have a sizeof operator | |
var_matches = re.search(r'([a-z][a-z0-9_]*)\s*\*\s*sizeof', malloc_params) | |
if not var_matches: | |
var_matches = re.search(r'sizeof\s*\([^\)]+\)\s*\*\s*([a-z][a-z0-9_]*)', malloc_params, re.IGNORECASE) | |
if not var_matches: | |
continue # We need a multiplicative offset | |
var_param = var_matches.group(1) | |
const_matches = re.match(r'.*(\+\s*\d+)\s*$', malloc_params) | |
if not const_matches: | |
const_matches = re.match(r'^\s*(\d+\s*\+).*', malloc_params) | |
if not const_matches: | |
continue # Must have a constant offset | |
const_param = const_matches.group(1) | |
print("************************") | |
print("Found a potential match:") | |
print(" Filename: {0}:{1}".format(filename, line_number)) | |
print(" Offending Line: {0}".format(line)) | |
print(" Variable assignments found at:") | |
for var_line_number, var_line in enumerate(lines): | |
if var_line_number >= line_number: | |
break # Only looking upward | |
if re.search(r'(^|\b)' + re.escape(var_param) + r'\s*=[^=]', var_line, re.IGNORECASE): | |
print("\t{0} {1}".format(var_line_number, var_line)) | |
print(" Variable usage found at:") | |
for var_line_number, var_line in enumerate(lines): | |
if var_line_number >= line_number: | |
break # Only looking upward | |
if var_param in var_line: | |
print("\t{0} {1}".format(var_line_number + 1, var_line)) | |
print("") | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Results from running against github.com/freebsd/freebsd/tree/master