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)

Reply via email to