It should also be possible to do this using T1 multiple times. For
example, for the declaration case, you could write:
@r@
type T1,T2;
identifier c;
position p;
@@
(
T1 *c = calloc(sizeof(T1),...);
|
T1 *...@p = calloc(sizeof(T2),...);
)
You can of course extend it to take into account the other cases you have
considered.
For Linux, I made the following rule, which finds problems when the size
computation is more complicated:
@r@
type T;
T *x;
position p;
@@
x...@p = <+...sizeof(T)...+>
@s@
expression x;
position p;
@@
x...@p = <+...sizeof(*x)...+>
@bad@
position p!={r.p,s.p};
type T, T1, T2;
T1 *x;
T2 **y;
typedef u8;
{void *, char *, unsigned char *, u8*} a;
{struct device,struct net_device} dev;
@@
(
y = \(kmalloc\|kzalloc\)(<+...sizeof(T)...+>,...)
|
a = \(kmalloc\|kzalloc\)(<+...sizeof(T)...+>,...)
|
x...@p = \(kmalloc\|kzalloc\)(<+...sizeof(T)...+>,...)
)
@script:python@
p << bad.p;
@@
cocci.print_main("error",p)
The third rule may look a bit odd, because all of the patterns are the
same, but the key point is the constraints on the various metavariables.
I found that cases where the type is ** or char * were likely to be false
positives. The reason for having the first two rules rather than just
checking for a T1 that is different than the type of x is that one can
have a computation like
sizeof(*x) + sizeof(other_structure)
Even though this involves a sizeof of another type, it is not a bug.
It does not seem to be necessary to take into account the declaration case
specifically. If you make an assignment with no ; at the end, Coccinelle
will also try to match that to a declaration, and is aware of the declared
type of the identifier. Therefore the following code:
int main () {
struct foo *x = kmalloc(sizeof(struct foo));
struct foo *x = kmalloc(sizeof(struct another));
x = kmalloc(sizeof(struct another));
}
gives me only two error reports, in lines 3 and 4.
julia
On Wed, 30 Jun 2010, Lucas De Marchi wrote:
> Hi, I've written a semantic patch to check for wrong size allocation.
> Using python was the only way I found out to check if type T1 is
> different from T2. Following the semantic patch:
>
> -----------------------------------------------------------
> @bug exists@
> type T1, T2;
> T1 *a;
> T2 *b;
> expression E;
> position p;
> identifier c;
> @@
> (
> a...@p = calloc(sizeof(*b), E);
> |
> a...@p = calloc(sizeof(T2), E);
> |
> T1 *...@p = calloc(sizeof(*b), E);
> |
> T1 *...@p = calloc(sizeof(T2), E);
> )
>
> @script:python depends on bug@
> p << bug.p;
> t1 << bug.T1;
> t2 << bug.T2;
> @@
>
> if t1 != t2:
> print "WARNING: wrong size to calloc function => %s:%s" %
> (p[0].file, p[0].line)
> print " Type is '%s', but 'sizeof(%s)' was allocated" % (t1, t2)
>
> -----------------------------------------------------------
>
>
> I've used the code attached to test the correctness of the results.
> Any comments ? I think I can add more checks for when there are casts.
>
> This is a common error when someone else renamed the variable or the
> type without properly updating the allocation lines. This happened
> today in one of the projects I work on.
>
>
> Lucas De Marchi
>
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)