* First coccinelle script, need some help.
@ 2018-10-10 19:38 Joel Fernandes
2018-10-10 20:23 ` Julia Lawall
0 siblings, 1 reply; 6+ messages in thread
From: Joel Fernandes @ 2018-10-10 19:38 UTC (permalink / raw)
To: linux-kernel, Julia Lawall, Gilles Muller, Nicolas Palix,
Michal Marek, cocci, Kees Cook
Hi!
I am trying to determine if a function argument is used across the whole
kernel for a certain kernel function.
I mustered up enough courage to write my first coccinelle script after a few
late nights of reading up about it :)
Here is .cocci script. I am trying to find if address is used at all in any
possible definitions of pte_alloc():
$ cat ~/pte_alloc.cocci
virtual report
@pte_args depends on report@
identifier E1, E2;
type T1, T2;
position p;
@@
pte_alloc@p(T1 E1, T2 E2)
{
...
(
...
E2
...
)
...
}
@script:python depends on report@
p << pte_args.p;
@@
coccilib.report.print_report(p[0], "WARNING: found definition of
apte_alloc_one with address used in the body")
The above warning does fire on the following test.c program:
struct page *pte_alloc(struct mm_struct *mm, unsigned long address)
{
address++;
if (condition()) {
return NULL;
}
}
But, *not* if I move 'address' into the if block:
struct page *pte_alloc(struct mm_struct *mm, unsigned long address)
{
if (condition()) {
address++;
return NULL;
}
}
I could not understand why, In my view the "address" expression should be
matched across the function body even within if blocks. But if I move
"address" into the if block, then the match doesn't occur any longer.
My coccicheck command is as follow:
make coccicheck COCCI=~/pte_alloc.cocci MODE=report M=test/test.c
What am I missing? Thanks for any help.
thanks,
- Joel
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: First coccinelle script, need some help. 2018-10-10 19:38 First coccinelle script, need some help Joel Fernandes @ 2018-10-10 20:23 ` Julia Lawall 2018-10-10 20:45 ` Joel Fernandes 0 siblings, 1 reply; 6+ messages in thread From: Julia Lawall @ 2018-10-10 20:23 UTC (permalink / raw) To: Joel Fernandes Cc: linux-kernel, Gilles Muller, Nicolas Palix, Michal Marek, cocci, Kees Cook On Wed, 10 Oct 2018, Joel Fernandes wrote: > > Hi! > > I am trying to determine if a function argument is used across the whole > kernel for a certain kernel function. > > I mustered up enough courage to write my first coccinelle script after a few > late nights of reading up about it :) > > Here is .cocci script. I am trying to find if address is used at all in any > possible definitions of pte_alloc(): > > $ cat ~/pte_alloc.cocci > virtual report > > @pte_args depends on report@ > identifier E1, E2; > type T1, T2; > position p; > @@ > > pte_alloc@p(T1 E1, T2 E2) > { > ... > ( > ... > E2 > ... > ) > ... > } In report mode, by default, the pattern has to match on all paths. Also when you have ... before or after E2, there can be no occurrence of E2 in the code matched by the ... So your rule requires that on every possible execution path through the function, there is exactly one occurrence of E2. You can try the following instead: virtual report @pte_args depends on report exists@ identifier E1, E2; type T1, T2; position p; @@ pte_alloc@p(T1 E1, T2 E2) { ... when any E2 ... when any } The exists in the rule header means check one path at a time. The when any allows anything, including E2, to occur in the ... part. You could also drop the first when any. The E2 will only match the first one, but you don't care in this case. julia > > @script:python depends on report@ > p << pte_args.p; > @@ > coccilib.report.print_report(p[0], "WARNING: found definition of > apte_alloc_one with address used in the body") > > The above warning does fire on the following test.c program: > > struct page *pte_alloc(struct mm_struct *mm, unsigned long address) > { > address++; > if (condition()) { > return NULL; > } > } > > But, *not* if I move 'address' into the if block: > > struct page *pte_alloc(struct mm_struct *mm, unsigned long address) > { > if (condition()) { > address++; > return NULL; > } > } > > I could not understand why, In my view the "address" expression should be > matched across the function body even within if blocks. But if I move > "address" into the if block, then the match doesn't occur any longer. > > My coccicheck command is as follow: > make coccicheck COCCI=~/pte_alloc.cocci MODE=report M=test/test.c > > What am I missing? Thanks for any help. > > thanks, > > - Joel > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: First coccinelle script, need some help. 2018-10-10 20:23 ` Julia Lawall @ 2018-10-10 20:45 ` Joel Fernandes 2018-10-10 20:51 ` Julia Lawall 0 siblings, 1 reply; 6+ messages in thread From: Joel Fernandes @ 2018-10-10 20:45 UTC (permalink / raw) To: Julia Lawall Cc: linux-kernel, Gilles Muller, Nicolas Palix, Michal Marek, cocci, Kees Cook On Wed, Oct 10, 2018 at 10:23:18PM +0200, Julia Lawall wrote: > > > On Wed, 10 Oct 2018, Joel Fernandes wrote: > > > > > Hi! > > > > I am trying to determine if a function argument is used across the whole > > kernel for a certain kernel function. > > > > I mustered up enough courage to write my first coccinelle script after a few > > late nights of reading up about it :) > > > > Here is .cocci script. I am trying to find if address is used at all in any > > possible definitions of pte_alloc(): > > > > $ cat ~/pte_alloc.cocci > > virtual report > > > > @pte_args depends on report@ > > identifier E1, E2; > > type T1, T2; > > position p; > > @@ > > > > pte_alloc@p(T1 E1, T2 E2) > > { > > ... > > ( > > ... > > E2 > > ... > > ) > > ... > > } > > > In report mode, by default, the pattern has to match on all paths. Also > when you have ... before or after E2, there can be no occurrence of E2 in > the code matched by the ... So your rule requires that on every possible > execution path through the function, there is exactly one occurrence of > E2. > > You can try the following instead: > > virtual report > > @pte_args depends on report exists@ > identifier E1, E2; > type T1, T2; > position p; > @@ > > pte_alloc@p(T1 E1, T2 E2) > { > ... when any > E2 > ... when any > } Thanks for the quick reply. If I just add 'depends on report exists' to the rule, then my original example works fine now. I did not need to add the 'when any'. Do you mind taking my original simple test.c example and modify it and let me know under what situation would it not work? I even added address = 1 outside of the if block and it works fine, I see the warning as I expect without 'when any' in pront of the "...". struct page *pte_alloc(struct mm_struct *mm, unsigned long address) { address = 1; if (condition()) { while (1) { address++; } return NULL; } } virtual report ----- For your reference, I included the .cocci script below again. This time with the 'depends on report exists' in the rule: @pte_args depends on report exists@ identifier E1, E2; type T1, T2; position p; @@ pte_alloc@p(T1 E1, T2 E2) { ... E2 ... } @script:python depends on report@ p << pte_args.p; @@ coccilib.report.print_report(p[0], "WARNING: found definition of pte_alloc_one with address used in the body") ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: First coccinelle script, need some help. 2018-10-10 20:45 ` Joel Fernandes @ 2018-10-10 20:51 ` Julia Lawall 2018-10-10 21:11 ` Joel Fernandes 0 siblings, 1 reply; 6+ messages in thread From: Julia Lawall @ 2018-10-10 20:51 UTC (permalink / raw) To: Joel Fernandes Cc: linux-kernel, Gilles Muller, Nicolas Palix, Michal Marek, cocci, Kees Cook On Wed, 10 Oct 2018, Joel Fernandes wrote: > On Wed, Oct 10, 2018 at 10:23:18PM +0200, Julia Lawall wrote: > > > > > > On Wed, 10 Oct 2018, Joel Fernandes wrote: > > > > > > > > Hi! > > > > > > I am trying to determine if a function argument is used across the whole > > > kernel for a certain kernel function. > > > > > > I mustered up enough courage to write my first coccinelle script after a few > > > late nights of reading up about it :) > > > > > > Here is .cocci script. I am trying to find if address is used at all in any > > > possible definitions of pte_alloc(): > > > > > > $ cat ~/pte_alloc.cocci > > > virtual report > > > > > > @pte_args depends on report@ > > > identifier E1, E2; > > > type T1, T2; > > > position p; > > > @@ > > > > > > pte_alloc@p(T1 E1, T2 E2) > > > { > > > ... > > > ( > > > ... > > > E2 > > > ... > > > ) > > > ... > > > } > > > > > > In report mode, by default, the pattern has to match on all paths. Also > > when you have ... before or after E2, there can be no occurrence of E2 in > > the code matched by the ... So your rule requires that on every possible > > execution path through the function, there is exactly one occurrence of > > E2. > > > > You can try the following instead: > > > > virtual report > > > > @pte_args depends on report exists@ > > identifier E1, E2; > > type T1, T2; > > position p; > > @@ > > > > pte_alloc@p(T1 E1, T2 E2) > > { > > ... when any > > E2 > > ... when any > > } > > Thanks for the quick reply. > If I just add 'depends on report exists' to the rule, then my original > example works fine now. I did not need to add the 'when any'. Do you mind > taking my original simple test.c example and modify it and let me know under > what situation would it not work? > > I even added address = 1 outside of the if block and it works fine, I see the > warning as I expect without 'when any' in pront of the "...". > > struct page *pte_alloc(struct mm_struct *mm, unsigned long address) > { > address = 1; > if (condition()) { > while (1) { > address++; > } > return NULL; > } > } This works, because there exists a path through the function that has only one use of address, ie the path where condition() is false. It should break if you put address = 2; just under address = 1, for example. julia ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: First coccinelle script, need some help. 2018-10-10 20:51 ` Julia Lawall @ 2018-10-10 21:11 ` Joel Fernandes 2018-10-10 21:12 ` Julia Lawall 0 siblings, 1 reply; 6+ messages in thread From: Joel Fernandes @ 2018-10-10 21:11 UTC (permalink / raw) To: Julia Lawall Cc: linux-kernel, Gilles Muller, Nicolas Palix, Michal Marek, cocci, Kees Cook On Wed, Oct 10, 2018 at 10:51:28PM +0200, Julia Lawall wrote: > > > On Wed, 10 Oct 2018, Joel Fernandes wrote: > > > On Wed, Oct 10, 2018 at 10:23:18PM +0200, Julia Lawall wrote: > > > > > > > > > On Wed, 10 Oct 2018, Joel Fernandes wrote: > > > > > > > > > > > Hi! > > > > > > > > I am trying to determine if a function argument is used across the whole > > > > kernel for a certain kernel function. > > > > > > > > I mustered up enough courage to write my first coccinelle script after a few > > > > late nights of reading up about it :) > > > > > > > > Here is .cocci script. I am trying to find if address is used at all in any > > > > possible definitions of pte_alloc(): > > > > > > > > $ cat ~/pte_alloc.cocci > > > > virtual report > > > > > > > > @pte_args depends on report@ > > > > identifier E1, E2; > > > > type T1, T2; > > > > position p; > > > > @@ > > > > > > > > pte_alloc@p(T1 E1, T2 E2) > > > > { > > > > ... > > > > ( > > > > ... > > > > E2 > > > > ... > > > > ) > > > > ... > > > > } > > > > > > > > > In report mode, by default, the pattern has to match on all paths. Also > > > when you have ... before or after E2, there can be no occurrence of E2 in > > > the code matched by the ... So your rule requires that on every possible > > > execution path through the function, there is exactly one occurrence of > > > E2. > > > > > > You can try the following instead: > > > > > > virtual report > > > > > > @pte_args depends on report exists@ > > > identifier E1, E2; > > > type T1, T2; > > > position p; > > > @@ > > > > > > pte_alloc@p(T1 E1, T2 E2) > > > { > > > ... when any > > > E2 > > > ... when any > > > } > > > > Thanks for the quick reply. > > If I just add 'depends on report exists' to the rule, then my original > > example works fine now. I did not need to add the 'when any'. Do you mind > > taking my original simple test.c example and modify it and let me know under > > what situation would it not work? > > > > I even added address = 1 outside of the if block and it works fine, I see the > > warning as I expect without 'when any' in pront of the "...". > > > > struct page *pte_alloc(struct mm_struct *mm, unsigned long address) > > { > > address = 1; > > if (condition()) { > > while (1) { > > address++; > > } > > return NULL; > > } > > } > > This works, because there exists a path through the function that has only > one use of address, ie the path where condition() is false. It should > break if you put address = 2; just under address = 1, for example. > Ok, thanks. This fact really is a bit subtle I'd say but hopefully will not be once I get past the learning curve. Interestingly, if I do the following then that works too without needing 'exists': virtual report @pte_args depends on report@ identifier E1, E2; type T1, T2; position p; @@ pte_alloc@p(T1 E1, T2 E2) { <+... E2 ...+> } @script:python depends on report@ p << pte_args.p; @@ coccilib.report.print_report(p[0], "WARNING: found definition of pte_alloc with address used in the body") thanks, - Joel ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: First coccinelle script, need some help. 2018-10-10 21:11 ` Joel Fernandes @ 2018-10-10 21:12 ` Julia Lawall 0 siblings, 0 replies; 6+ messages in thread From: Julia Lawall @ 2018-10-10 21:12 UTC (permalink / raw) To: Joel Fernandes Cc: linux-kernel, Gilles Muller, Nicolas Palix, Michal Marek, cocci, Kees Cook On Wed, 10 Oct 2018, Joel Fernandes wrote: > On Wed, Oct 10, 2018 at 10:51:28PM +0200, Julia Lawall wrote: > > > > > > On Wed, 10 Oct 2018, Joel Fernandes wrote: > > > > > On Wed, Oct 10, 2018 at 10:23:18PM +0200, Julia Lawall wrote: > > > > > > > > > > > > On Wed, 10 Oct 2018, Joel Fernandes wrote: > > > > > > > > > > > > > > Hi! > > > > > > > > > > I am trying to determine if a function argument is used across the whole > > > > > kernel for a certain kernel function. > > > > > > > > > > I mustered up enough courage to write my first coccinelle script after a few > > > > > late nights of reading up about it :) > > > > > > > > > > Here is .cocci script. I am trying to find if address is used at all in any > > > > > possible definitions of pte_alloc(): > > > > > > > > > > $ cat ~/pte_alloc.cocci > > > > > virtual report > > > > > > > > > > @pte_args depends on report@ > > > > > identifier E1, E2; > > > > > type T1, T2; > > > > > position p; > > > > > @@ > > > > > > > > > > pte_alloc@p(T1 E1, T2 E2) > > > > > { > > > > > ... > > > > > ( > > > > > ... > > > > > E2 > > > > > ... > > > > > ) > > > > > ... > > > > > } > > > > > > > > > > > > In report mode, by default, the pattern has to match on all paths. Also > > > > when you have ... before or after E2, there can be no occurrence of E2 in > > > > the code matched by the ... So your rule requires that on every possible > > > > execution path through the function, there is exactly one occurrence of > > > > E2. > > > > > > > > You can try the following instead: > > > > > > > > virtual report > > > > > > > > @pte_args depends on report exists@ > > > > identifier E1, E2; > > > > type T1, T2; > > > > position p; > > > > @@ > > > > > > > > pte_alloc@p(T1 E1, T2 E2) > > > > { > > > > ... when any > > > > E2 > > > > ... when any > > > > } > > > > > > Thanks for the quick reply. > > > If I just add 'depends on report exists' to the rule, then my original > > > example works fine now. I did not need to add the 'when any'. Do you mind > > > taking my original simple test.c example and modify it and let me know under > > > what situation would it not work? > > > > > > I even added address = 1 outside of the if block and it works fine, I see the > > > warning as I expect without 'when any' in pront of the "...". > > > > > > struct page *pte_alloc(struct mm_struct *mm, unsigned long address) > > > { > > > address = 1; > > > if (condition()) { > > > while (1) { > > > address++; > > > } > > > return NULL; > > > } > > > } > > > > This works, because there exists a path through the function that has only > > one use of address, ie the path where condition() is false. It should > > break if you put address = 2; just under address = 1, for example. > > > Ok, thanks. This fact really is a bit subtle I'd say but hopefully will not > be once I get past the learning curve. Interestingly, if I do the following > then that works too without needing 'exists': > > virtual report > > @pte_args depends on report@ > identifier E1, E2; > type T1, T2; > position p; > @@ > > pte_alloc@p(T1 E1, T2 E2) > { > <+... > E2 > ...+> > } > > @script:python depends on report@ > p << pte_args.p; > @@ > coccilib.report.print_report(p[0], "WARNING: found definition of pte_alloc with > address used in the body") Yes, that is another option. But it may be more expensive. julia ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-10-10 21:12 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-10-10 19:38 First coccinelle script, need some help Joel Fernandes 2018-10-10 20:23 ` Julia Lawall 2018-10-10 20:45 ` Joel Fernandes 2018-10-10 20:51 ` Julia Lawall 2018-10-10 21:11 ` Joel Fernandes 2018-10-10 21:12 ` Julia Lawall
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®