Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s
      2 // RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s
      3 
      4 #include "Inputs/system-header-simulator.h"
      5 
      6 void foo();
      7 
      8 // Ensure that child process is properly checked.
      9 int f1(int x) {
     10   pid_t pid = vfork(); // expected-warning{{Call to function 'vfork' is insecure}}
     11   if (pid != 0)
     12     return 0;
     13 
     14   switch (x) {
     15   case 0:
     16     // Ensure that modifying pid is ok.
     17     pid = 1; // no-warning
     18     // Ensure that calling whitelisted routines is ok.
     19     execl("", "", 0); // no-warning
     20     _exit(1); // no-warning
     21     break;
     22   case 1:
     23     // Ensure that writing variables is prohibited.
     24     x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}
     25     break;
     26   case 2:
     27     // Ensure that calling functions is prohibited.
     28     foo(); // expected-warning{{This function call is prohibited after a successful vfork}}
     29     break;
     30   default:
     31     // Ensure that returning from function is prohibited.
     32     return 0; // expected-warning{{Return is prohibited after a successful vfork; call _exit() instead}}
     33   }
     34 
     35   while(1);
     36 }
     37 
     38 // Same as previous but without explicit pid variable.
     39 int f2(int x) {
     40   pid_t pid = vfork(); // expected-warning{{Call to function 'vfork' is insecure}}
     41 
     42   switch (x) {
     43   case 0:
     44     // Ensure that writing pid is ok.
     45     pid = 1; // no-warning
     46     // Ensure that calling whitelisted routines is ok.
     47     execl("", "", 0); // no-warning
     48     _exit(1); // no-warning
     49     break;
     50   case 1:
     51     // Ensure that writing variables is prohibited.
     52     x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}
     53     break;
     54   case 2:
     55     // Ensure that calling functions is prohibited.
     56     foo(); // expected-warning{{This function call is prohibited after a successful vfork}}
     57     break;
     58   default:
     59     // Ensure that returning from function is prohibited.
     60     return 0; // expected-warning{{Return is prohibited after a successful vfork; call _exit() instead}}
     61   }
     62 
     63   while(1);
     64 }
     65 
     66 // Ensure that parent process isn't restricted.
     67 int f3(int x) {
     68   if (vfork() == 0) // expected-warning{{Call to function 'vfork' is insecure}}
     69     _exit(1);
     70   x = 0; // no-warning
     71   foo(); // no-warning
     72   return 0;
     73 } // no-warning
     74 
     75 // Unbound pids are special so test them separately.
     76 void f4(int x) {
     77   switch (x) {
     78   case 0:
     79     vfork(); // expected-warning{{Call to function 'vfork' is insecure}}
     80     x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}
     81     break;
     82 
     83   case 1:
     84     {
     85       char args[2];
     86       switch (vfork()) { // expected-warning{{Call to function 'vfork' is insecure}}
     87       case 0:
     88         args[0] = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}
     89         exit(1);
     90       }
     91       break;
     92     }
     93 
     94   case 2:
     95     {
     96       pid_t pid;
     97       if ((pid = vfork()) == 0) // expected-warning{{Call to function 'vfork' is insecure}}
     98         while(1); // no-warning
     99       break;
    100     }
    101   }
    102   while(1);
    103 } //no-warning
    104 
    105 
    106 void f5() {
    107   // See "libxtables: move some code to avoid cautions in vfork man page"
    108   // (http://lists.netfilter.org/pipermail/netfilter-buglog/2014-October/003280.html).
    109   if (vfork() == 0) { // expected-warning{{Call to function 'vfork' is insecure}}
    110     execl("prog", "arg1", 0); // no-warning
    111     exit(1);  // expected-warning{{This function call is prohibited after a successful vfork}}
    112   }
    113 }
    114 
    115