aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-12-19 19:07:36 -0500
committerSteven Rostedt <rostedt@goodmis.org>2011-12-21 07:23:11 -0500
commit06a51d9307380c78bb5c92e68fc80ad2c7d7f890 (patch)
treee0f38e8780f92937e8f19f17b8bf9eff6bcc3137
parentc842e975520f8ab09e293cc92f51a1f396251fd5 (diff)
ftrace: Create ftrace_hash_empty() helper routine
There are two types of hashes in the ftrace_ops; one type is the filter_hash and the other is the notrace_hash. Either one may be null, meaning it has no elements. But when elements are added, the hash is allocated. Throughout the code, a check needs to be made to see if a hash exists or the hash has elements, but the check if the hash exists is usually missing causing the possible "NULL pointer dereference bug". Add a helper routine called "ftrace_hash_empty()" that returns true if the hash doesn't exist or its count is zero. As they mean the same thing. Last-bug-reported-by: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel/trace/ftrace.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a383d6c67bfa..e1ee07f81ca2 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -999,6 +999,11 @@ static struct ftrace_page *ftrace_new_pgs;
999static struct ftrace_page *ftrace_pages_start; 999static struct ftrace_page *ftrace_pages_start;
1000static struct ftrace_page *ftrace_pages; 1000static struct ftrace_page *ftrace_pages;
1001 1001
1002static bool ftrace_hash_empty(struct ftrace_hash *hash)
1003{
1004 return !hash || !hash->count;
1005}
1006
1002static struct ftrace_func_entry * 1007static struct ftrace_func_entry *
1003ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) 1008ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
1004{ 1009{
@@ -1007,7 +1012,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
1007 struct hlist_head *hhd; 1012 struct hlist_head *hhd;
1008 struct hlist_node *n; 1013 struct hlist_node *n;
1009 1014
1010 if (!hash->count) 1015 if (ftrace_hash_empty(hash))
1011 return NULL; 1016 return NULL;
1012 1017
1013 if (hash->size_bits > 0) 1018 if (hash->size_bits > 0)
@@ -1151,7 +1156,7 @@ alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash)
1151 return NULL; 1156 return NULL;
1152 1157
1153 /* Empty hash? */ 1158 /* Empty hash? */
1154 if (!hash || !hash->count) 1159 if (ftrace_hash_empty(hash))
1155 return new_hash; 1160 return new_hash;
1156 1161
1157 size = 1 << hash->size_bits; 1162 size = 1 << hash->size_bits;
@@ -1276,9 +1281,9 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
1276 filter_hash = rcu_dereference_raw(ops->filter_hash); 1281 filter_hash = rcu_dereference_raw(ops->filter_hash);
1277 notrace_hash = rcu_dereference_raw(ops->notrace_hash); 1282 notrace_hash = rcu_dereference_raw(ops->notrace_hash);
1278 1283
1279 if ((!filter_hash || !filter_hash->count || 1284 if ((ftrace_hash_empty(filter_hash) ||
1280 ftrace_lookup_ip(filter_hash, ip)) && 1285 ftrace_lookup_ip(filter_hash, ip)) &&
1281 (!notrace_hash || !notrace_hash->count || 1286 (ftrace_hash_empty(notrace_hash) ||
1282 !ftrace_lookup_ip(notrace_hash, ip))) 1287 !ftrace_lookup_ip(notrace_hash, ip)))
1283 ret = 1; 1288 ret = 1;
1284 else 1289 else
@@ -1371,7 +1376,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
1371 if (filter_hash) { 1376 if (filter_hash) {
1372 hash = ops->filter_hash; 1377 hash = ops->filter_hash;
1373 other_hash = ops->notrace_hash; 1378 other_hash = ops->notrace_hash;
1374 if (!hash || !hash->count) 1379 if (ftrace_hash_empty(hash))
1375 all = 1; 1380 all = 1;
1376 } else { 1381 } else {
1377 inc = !inc; 1382 inc = !inc;
@@ -1381,7 +1386,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
1381 * If the notrace hash has no items, 1386 * If the notrace hash has no items,
1382 * then there's nothing to do. 1387 * then there's nothing to do.
1383 */ 1388 */
1384 if (!hash || !hash->count) 1389 if (ftrace_hash_empty(hash))
1385 return; 1390 return;
1386 } 1391 }
1387 1392
@@ -1398,8 +1403,8 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
1398 if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip)) 1403 if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip))
1399 match = 1; 1404 match = 1;
1400 } else { 1405 } else {
1401 in_hash = hash && !!ftrace_lookup_ip(hash, rec->ip); 1406 in_hash = !!ftrace_lookup_ip(hash, rec->ip);
1402 in_other_hash = other_hash && !!ftrace_lookup_ip(other_hash, rec->ip); 1407 in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip);
1403 1408
1404 /* 1409 /*
1405 * 1410 *
@@ -1407,7 +1412,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
1407 if (filter_hash && in_hash && !in_other_hash) 1412 if (filter_hash && in_hash && !in_other_hash)
1408 match = 1; 1413 match = 1;
1409 else if (!filter_hash && in_hash && 1414 else if (!filter_hash && in_hash &&
1410 (in_other_hash || !other_hash->count)) 1415 (in_other_hash || ftrace_hash_empty(other_hash)))
1411 match = 1; 1416 match = 1;
1412 } 1417 }
1413 if (!match) 1418 if (!match)
@@ -1950,7 +1955,7 @@ static int ops_traces_mod(struct ftrace_ops *ops)
1950 struct ftrace_hash *hash; 1955 struct ftrace_hash *hash;
1951 1956
1952 hash = ops->filter_hash; 1957 hash = ops->filter_hash;
1953 return !!(!hash || !hash->count); 1958 return ftrace_hash_empty(hash);
1954} 1959}
1955 1960
1956static int ftrace_update_code(struct module *mod) 1961static int ftrace_update_code(struct module *mod)
@@ -2320,7 +2325,8 @@ static void *t_start(struct seq_file *m, loff_t *pos)
2320 * off, we can short cut and just print out that all 2325 * off, we can short cut and just print out that all
2321 * functions are enabled. 2326 * functions are enabled.
2322 */ 2327 */
2323 if (iter->flags & FTRACE_ITER_FILTER && !ops->filter_hash->count) { 2328 if (iter->flags & FTRACE_ITER_FILTER &&
2329 ftrace_hash_empty(ops->filter_hash)) {
2324 if (*pos > 0) 2330 if (*pos > 0)
2325 return t_hash_start(m, pos); 2331 return t_hash_start(m, pos);
2326 iter->flags |= FTRACE_ITER_PRINTALL; 2332 iter->flags |= FTRACE_ITER_PRINTALL;