Skip to content

Commit

Permalink
ftrace: Create ftrace_hash_empty() helper routine
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed Dec 21, 2011
1 parent c842e97 commit 06a51d9
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,11 @@ static struct ftrace_page *ftrace_new_pgs;
static struct ftrace_page *ftrace_pages_start;
static struct ftrace_page *ftrace_pages;

static bool ftrace_hash_empty(struct ftrace_hash *hash)
{
return !hash || !hash->count;
}

static struct ftrace_func_entry *
ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
{
Expand All @@ -1007,7 +1012,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
struct hlist_head *hhd;
struct hlist_node *n;

if (!hash->count)
if (ftrace_hash_empty(hash))
return NULL;

if (hash->size_bits > 0)
Expand Down Expand Up @@ -1151,7 +1156,7 @@ alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash)
return NULL;

/* Empty hash? */
if (!hash || !hash->count)
if (ftrace_hash_empty(hash))
return new_hash;

size = 1 << hash->size_bits;
Expand Down Expand Up @@ -1276,9 +1281,9 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
filter_hash = rcu_dereference_raw(ops->filter_hash);
notrace_hash = rcu_dereference_raw(ops->notrace_hash);

if ((!filter_hash || !filter_hash->count ||
if ((ftrace_hash_empty(filter_hash) ||
ftrace_lookup_ip(filter_hash, ip)) &&
(!notrace_hash || !notrace_hash->count ||
(ftrace_hash_empty(notrace_hash) ||
!ftrace_lookup_ip(notrace_hash, ip)))
ret = 1;
else
Expand Down Expand Up @@ -1371,7 +1376,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
if (filter_hash) {
hash = ops->filter_hash;
other_hash = ops->notrace_hash;
if (!hash || !hash->count)
if (ftrace_hash_empty(hash))
all = 1;
} else {
inc = !inc;
Expand All @@ -1381,7 +1386,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
* If the notrace hash has no items,
* then there's nothing to do.
*/
if (!hash || !hash->count)
if (ftrace_hash_empty(hash))
return;
}

Expand All @@ -1398,16 +1403,16 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip))
match = 1;
} else {
in_hash = hash && !!ftrace_lookup_ip(hash, rec->ip);
in_other_hash = other_hash && !!ftrace_lookup_ip(other_hash, rec->ip);
in_hash = !!ftrace_lookup_ip(hash, rec->ip);
in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip);

/*
*
*/
if (filter_hash && in_hash && !in_other_hash)
match = 1;
else if (!filter_hash && in_hash &&
(in_other_hash || !other_hash->count))
(in_other_hash || ftrace_hash_empty(other_hash)))
match = 1;
}
if (!match)
Expand Down Expand Up @@ -1950,7 +1955,7 @@ static int ops_traces_mod(struct ftrace_ops *ops)
struct ftrace_hash *hash;

hash = ops->filter_hash;
return !!(!hash || !hash->count);
return ftrace_hash_empty(hash);
}

static int ftrace_update_code(struct module *mod)
Expand Down Expand Up @@ -2320,7 +2325,8 @@ static void *t_start(struct seq_file *m, loff_t *pos)
* off, we can short cut and just print out that all
* functions are enabled.
*/
if (iter->flags & FTRACE_ITER_FILTER && !ops->filter_hash->count) {
if (iter->flags & FTRACE_ITER_FILTER &&
ftrace_hash_empty(ops->filter_hash)) {
if (*pos > 0)
return t_hash_start(m, pos);
iter->flags |= FTRACE_ITER_PRINTALL;
Expand Down

0 comments on commit 06a51d9

Please sign in to comment.