Hi all,
I'm continously trying to improve quality of the code any my coccinelle skills.
I've found interesting article about using Coccinelle to detect
OpenSSL bugs (http://www.diku.dk/hjemmesider/ansatte/julia/edcc10.pdf).
I've tried to use the same approach, but without much success, that's
why I ask here.
Let's assume we have function fun(...), which returns 0 on success,
non-0 on failure.
Therefore checking this function return value like this is probably
incorrect: <C, <=C, >C, >=C, == C (!0), != C (!0).
This is the first part of the checker, which works fine, but in my
opinion is superfluous (excessive):
@rule_simple@
expression x, x2;
@@
(
fun(...) == 0 // valid, skip
|
fun(...) != 0 // valid, skip
|
((x = fun(...)) != 0) // valid, skip
|
((x = fun(...)) == 0) // valid, skip
|
- ((x = fun(...)) < x2) // invalid, print
+ BUG(fun())
|
- ((x = fun(...)) > x2) // invalid, print
+ BUG(fun())
|
- ((x = fun(...)) <= x2) // invalid, print
+ BUG(fun())
|
- ((x = fun(...)) >= x2) // invalid, print
+ BUG(fun())
|
- ((x = fun(...)) == x2) // invalid, print
+ BUG(fun())
|
- ((x = fun(...)) != x2) // invalid, print
+ BUG(fun())
|
- fun(x) > x2
+ BUG(fun(x)) // invalid, print
|
- fun(x) < x2
+ BUG(fun(x)) // invalid, print
|
- fun(x) >= x2
+ BUG(fun(x)) // invalid, print
|
- fun(x) <= x2
+ BUG(fun(x)) // invalid, print
|
- fun(x) == x2
+ BUG(fun(x)) // invalid, print
|
- fun(x) != x2
+ BUG(fun(x)) // invalid, print
)
Is there a better way to write the above? Is there a possibility to
use "|" with operators, like: - fun(x) < | > | >= | <=?
Please note that, in opposite to OpenSSL example, I can't easily
propose a patch, because I don't know programmer's intentions, so I
put BUG() in the output.
Is there a way of generalizing that? I mean - automatically generate
rules basing on function return values?
In OpenSSL's AES_set_encryp_key there was: valid: <= 0, > 0, invalid: else
In above: valid: != 0, == 0, invalid: else
As I'm going to check many functions, rewriting patch with replacing
fun() is possible, but inconvenient.
What would be the better way? Putting some __attribute__ in header
file and using that instead of function name? Is it possible with
Coccinelle?
But I can live with the above. My current problem is with the second
part of the cocci file:
@rule2@
expression x2;
idexpression x;
@@
x = fun(x2);
... WHEN != x
(
x == 0 // valid, skip
|
x != 0 // valid, skip
|
- x == x2 // invalid, print
+ BUG(x)
|
- x != x2 // invalid, print
+ BUG(x)
|
- x > x2
+ BUG(x) // invalid, print
|
- x < x2
+ BUG(x) // invalid, print
|
- x >= x2
+ BUG(x) // invalid, print
|
- x <= x2
+ BUG(x) // invalid, print
)
Why doesn't it work? Where is a bug? Can those two patterns be put in
single cocci file or should be split into two? Why the line:
x = fun(x2);
when added - in front of it, just to check, doesn't detect:
int b=fun(2);
while it detects:
int c;
c = fun(2);
I'm putting test C code here:
int main(int argc, char ** argv) {
// fun() - returns 0/non-0 value
int a;
int b=fun(2);
int c;
c = fun(2);
if (b == 0) { // valid
printf("");
}
if (b != 0) { // valid
printf("");
}
if (b) { // valid
printf("");
}
if (b >= 0) { // invalid
printf("");
}
if (c) { // valid
printf("");
}
if (c >= 0) { // invalid
printf("");
}
if (!b) { // valid
printf("");
}
if ((a = fun(2)) != 0 ){ // valid
printf("");
}
if ((a = fun(2)) == 0 ){ // valid
printf("");
}
if ((a = fun(2)) < 0 ){ // invalid
printf("");
}
if (fun(2) == 0) { // valid
printf("");
}
if (fun(2) <= 0) { //invalid
printf("");
}
return 0;
}
As I'm still learning, the code is of course non-optimal, but first
I'd like to get basic version working.
I'd appreciate your comments.
Best regards,
Robert
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)