Powered by Linux
Re: Adding PCI hotplug safe checking to smatch — Semantic Matching Tool

Re: Adding PCI hotplug safe checking to smatch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



So I tried the first most obvious check which is to match code like
this:

	foo = readl();

If you see that then mark "foo" as untrusted.  Then if "foo" is used in
a condition print an error.

	if (foo & BAR) <-- Error.

I wasn't sure how to tell which drivers are hot plugable (plus I'm
lazy) so I ran it on drivers/usb/.

Also the test should ignore code which checks for "foo == 0xffffffff"
but I was too lazy to do that.  It turns out that no one ever does
error handling so this wasn't a problem.

I've looked at some of the warnings, and it's pretty hard to tell if
0xffffffff is handled correctly or not.  In the example you gave, then
it returned success and that would be treated like a warning.  Another
potential problem would be infinite loops like:

	while (readl() & BAR)
		;

There was a university group that did some work with infinite loops like
this:
http://pages.cs.wisc.edu/~kadav/new/carb/Site/splash.html
http://pages.cs.wisc.edu/~kadav/papers/carb-sosp09.pdf

I've attached my really dumb check that I wrote.  You would need to add
it to check_list.h.  Then run:
~/progs/smatch/devel/smatch_scripts/kchecker drivers/usb/host/pci-quirks.c

The check is not useful.  We need to specifically check for cases where
0xffffffff leads to returning success or when it causes an infinite
loop.  What other similar bad results could we check for?

regards,
dan carpenter
#include "smatch.h"
#include "smatch_extra.h"

static int my_id;

STATE(readl);

static void match_readl(const char *fn, struct expression *expr, void *unused)
{
	set_state_expr(my_id, expr->left, &readl);
}

static void check_condition(struct expression *expr)
{
	if (expr->type == EXPR_BINOP) {
		check_condition(expr->left);
		check_condition(expr->right);
		return;
	}
	if (get_state_expr(my_id, expr) != &readl)
		return;
	sm_msg("warn: readl() can return 0xffff");
}

void check_readl(int id)
{
	if (option_project != PROJ_KERNEL)
		return;

	my_id = id;

	add_function_assign_hook("readl", match_readl, NULL);
	add_hook(check_condition, CONDITION_HOOK);
}

[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux