How to force Clang static checker to check the code that will not be executed in some situations???

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to force Clang static checker to check the code that will not be executed in some situations???

Richard Smith via cfe-dev
Hi all,
   Recently, I am using Clang static checker to find buffer overflow related bugs. There is one case that the buggy code will be executed only if STATS is defined  (#ifdef STATS). I hope my checker can find all the bugs in a program even in the cases that the code will not be executed for now. Do you have any idea how can I achieve this?
   The following is a part of the buggy code. Since "STATS" is not defined, variable a and ns will be NULL. Thus, some code will not be checked by Clang and the checker will miss one bug.
   I put the full code as the attached file. Let me know if you have any solution. Thanks in advance!!

Regards,
Chaz
    
static void nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr, nsdp)
const char *sysloginfo, *queryname, *complaint, *dname;
const struct databuf *a_rr, *nsdp;
{
#ifdef STATS
char nsbuf[20];
char abuf[20];
#endif
  char *a, *ns;  
  if (sysloginfo && queryname)
   {
   char buf[999];

    a = ns = (char *)NULL;
#ifdef STATS
/* this part will not be executed because STATS is not defined */
/* so a and ns will be equal to NULL */
    if (nsdp) {
     /* assign value to a and ns */
    }
#endif
    if ( a != NULL || ns != NULL)
     {
/* the code here will not be checked by Clang because a and ns are equal to NULL */
     /*This line is a buggy point, but it cannot be found by Clang static checker now*/
     sprintf(buf, "%s: query(%s) %s (%s:%s) learnt (A=%s:NS=%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)),
       a ? a : "<Not Available>",
       ns ? ns : "<Not Available>" );
     }
    else{
     /*This is another buggy point, can be found by Clang static checker*/
     sprintf(buf, "%s: query(%s) %s (%s:%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)));
     }
   }
}

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

ns-lookup-klee.c (15K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to force Clang static checker to check the code that will not be executed in some situations???

Richard Smith via cfe-dev
Do you mean Klee or the Clang Static Analyzer?

For Klee, there is a separate mailing list. For CSA, you could just have two invocations: with and without -DSTATS=1.
You could also try to write a tool to generate all possible invocations if you want to consider all possible combinations of defined/undefined macros.

On Jan 3, 2019, at 2:27 AM, changze cui via cfe-dev <[hidden email]> wrote:

Hi all,
   Recently, I am using Clang static checker to find buffer overflow related bugs. There is one case that the buggy code will be executed only if STATS is defined  (#ifdef STATS). I hope my checker can find all the bugs in a program even in the cases that the code will not be executed for now. Do you have any idea how can I achieve this?
   The following is a part of the buggy code. Since "STATS" is not defined, variable a and ns will be NULL. Thus, some code will not be checked by Clang and the checker will miss one bug.
   I put the full code as the attached file. Let me know if you have any solution. Thanks in advance!!

Regards,
Chaz
    
static void nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr, nsdp)
const char *sysloginfo, *queryname, *complaint, *dname;
const struct databuf *a_rr, *nsdp;
{
#ifdef STATS
char nsbuf[20];
char abuf[20];
#endif
  char *a, *ns;  
  if (sysloginfo && queryname)
   {
   char buf[999];

    a = ns = (char *)NULL;
#ifdef STATS
/* this part will not be executed because STATS is not defined */
/* so a and ns will be equal to NULL */
    if (nsdp) {
     /* assign value to a and ns */
    }
#endif
    if ( a != NULL || ns != NULL)
     {
/* the code here will not be checked by Clang because a and ns are equal to NULL */
     /*This line is a buggy point, but it cannot be found by Clang static checker now*/
     sprintf(buf, "%s: query(%s) %s (%s:%s) learnt (A=%s:NS=%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)),
       a ? a : "<Not Available>",
       ns ? ns : "<Not Available>" );
     }
    else{
     /*This is another buggy point, can be found by Clang static checker*/
     sprintf(buf, "%s: query(%s) %s (%s:%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)));
     }
   }
}
<ns-lookup-klee.c>_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: How to force Clang static checker to check the code that will not be executed in some situations???

Richard Smith via cfe-dev
In reply to this post by Richard Smith via cfe-dev
scan build will only follow your build command to preprocess your code and check the bugs in the preprocessed code. 
If you want to scan the code with STATS defined, you need to tell the compile process to define STATS while compiling.

The STATS variable can either be defined to a specific value or not defined, only one version is available in one scan, but you can scan it again with different values.

Our team had researched this problem before, if there are a lot of macro switches, you can use combinatorial test technique to help you.
Here is our previous research on using combinatorial test technique to cover multiple macro switches values: https://doi.org/10.1109/COMPSAC.2017.91
(I am not one of the authors, as I was not the member of our team at that time. But you can still contact me or the last two authors (my boss) if you are interested in the method.)😝

The tool used in our research, Canalyze, is a private fork of CSA with our optimizations. The similar method can also be used on scan build.
As it is the strategy not the tool that matters.
I am not familiar with KLEE, but as far as I know about KLEE, the similar method can also be utilized on it.

Hope our research will be useful to you.

Regards,
Ella

changze cui via cfe-dev <[hidden email]> 于2019年1月3日周四 下午6:27写道:
Hi all,
   Recently, I am using Clang static checker to find buffer overflow related bugs. There is one case that the buggy code will be executed only if STATS is defined  (#ifdef STATS). I hope my checker can find all the bugs in a program even in the cases that the code will not be executed for now. Do you have any idea how can I achieve this?
   The following is a part of the buggy code. Since "STATS" is not defined, variable a and ns will be NULL. Thus, some code will not be checked by Clang and the checker will miss one bug.
   I put the full code as the attached file. Let me know if you have any solution. Thanks in advance!!

Regards,
Chaz
    
static void nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr, nsdp)
const char *sysloginfo, *queryname, *complaint, *dname;
const struct databuf *a_rr, *nsdp;
{
#ifdef STATS
char nsbuf[20];
char abuf[20];
#endif
  char *a, *ns;  
  if (sysloginfo && queryname)
   {
   char buf[999];

    a = ns = (char *)NULL;
#ifdef STATS
/* this part will not be executed because STATS is not defined */
/* so a and ns will be equal to NULL */
    if (nsdp) {
     /* assign value to a and ns */
    }
#endif
    if ( a != NULL || ns != NULL)
     {
/* the code here will not be checked by Clang because a and ns are equal to NULL */
     /*This line is a buggy point, but it cannot be found by Clang static checker now*/
     sprintf(buf, "%s: query(%s) %s (%s:%s) learnt (A=%s:NS=%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)),
       a ? a : "<Not Available>",
       ns ? ns : "<Not Available>" );
     }
    else{
     /*This is another buggy point, can be found by Clang static checker*/
     sprintf(buf, "%s: query(%s) %s (%s:%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)));
     }
   }
}
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: How to force Clang static checker to check the code that will not be executed in some situations???

Richard Smith via cfe-dev
Hi Ella and George,
   Thanks for your timely help. Now I have a better understanding of this problem. I will also read this paper carefully.

Regards,
Chaz

Ella Oikawa <[hidden email]> 于2019年1月4日周五 上午11:28写道:
In case you cannot reach the full paper.

Regards,
Ella

Ella Oikawa <[hidden email]> 于2019年1月4日周五 上午11:18写道:
scan build will only follow your build command to preprocess your code and check the bugs in the preprocessed code. 
If you want to scan the code with STATS defined, you need to tell the compile process to define STATS while compiling.

The STATS variable can either be defined to a specific value or not defined, only one version is available in one scan, but you can scan it again with different values.

Our team had researched this problem before, if there are a lot of macro switches, you can use combinatorial test technique to help you.
Here is our previous research on using combinatorial test technique to cover multiple macro switches values: https://doi.org/10.1109/COMPSAC.2017.91
(I am not one of the authors, as I was not the member of our team at that time. But you can still contact me or the last two authors (my boss) if you are interested in the method.)😝

The tool used in our research, Canalyze, is a private fork of CSA with our optimizations. The similar method can also be used on scan build.
As it is the strategy not the tool that matters.
I am not familiar with KLEE, but as far as I know about KLEE, the similar method can also be utilized on it.

Hope our research will be useful to you.

Regards,
Ella

changze cui via cfe-dev <[hidden email]> 于2019年1月3日周四 下午6:27写道:
Hi all,
   Recently, I am using Clang static checker to find buffer overflow related bugs. There is one case that the buggy code will be executed only if STATS is defined  (#ifdef STATS). I hope my checker can find all the bugs in a program even in the cases that the code will not be executed for now. Do you have any idea how can I achieve this?
   The following is a part of the buggy code. Since "STATS" is not defined, variable a and ns will be NULL. Thus, some code will not be checked by Clang and the checker will miss one bug.
   I put the full code as the attached file. Let me know if you have any solution. Thanks in advance!!

Regards,
Chaz
    
static void nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr, nsdp)
const char *sysloginfo, *queryname, *complaint, *dname;
const struct databuf *a_rr, *nsdp;
{
#ifdef STATS
char nsbuf[20];
char abuf[20];
#endif
  char *a, *ns;  
  if (sysloginfo && queryname)
   {
   char buf[999];

    a = ns = (char *)NULL;
#ifdef STATS
/* this part will not be executed because STATS is not defined */
/* so a and ns will be equal to NULL */
    if (nsdp) {
     /* assign value to a and ns */
    }
#endif
    if ( a != NULL || ns != NULL)
     {
/* the code here will not be checked by Clang because a and ns are equal to NULL */
     /*This line is a buggy point, but it cannot be found by Clang static checker now*/
     sprintf(buf, "%s: query(%s) %s (%s:%s) learnt (A=%s:NS=%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)),
       a ? a : "<Not Available>",
       ns ? ns : "<Not Available>" );
     }
    else{
     /*This is another buggy point, can be found by Clang static checker*/
     sprintf(buf, "%s: query(%s) %s (%s:%s)",
       sysloginfo, queryname,
       complaint, dname,
       inet_ntoa(data_inaddr(a_rr->d_data)));
     }
   }
}
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev