1  /* { dg-do compile } */
       2  /* { dg-options "-fanalyzer" } */
       3  /* { dg-require-effective-target analyzer } */
       4  
       5  #include <string.h>
       6  
       7  #include "test-uaccess.h"
       8  
       9  typedef unsigned char u8;
      10  typedef unsigned __INT16_TYPE__ u16;
      11  typedef unsigned __INT32_TYPE__ u32;
      12  
      13  struct s1
      14  {
      15    u32 i;
      16  };
      17  
      18  void test_1a (void __user *dst, u32 a)
      19  {
      20    struct s1 s;
      21    s.i = a;
      22    copy_to_user(dst, &s, sizeof (struct s1)); /* { dg-bogus "" } */
      23  }
      24  
      25  void test_1b (void __user *dst, u32 a)
      26  {
      27    struct s1 s;
      28    copy_to_user(dst, &s, sizeof (struct s1)); /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
      29    /* { dg-message "4 bytes are uninitialized" "note how much" { target *-*-* } .-1 } */
      30  }
      31  
      32  void test_1c (void __user *dst, u32 a)
      33  {
      34    struct s1 s;
      35    memset (&s, 0, sizeof (struct s1));
      36    copy_to_user(dst, &s, sizeof (struct s1)); /* { dg-bogus "" } */
      37  }
      38  
      39  void test_1d (void __user *dst, u32 a)
      40  {
      41    struct s1 s = {0};
      42    copy_to_user(dst, &s, sizeof (struct s1)); /* { dg-bogus "" } */
      43  }
      44  
      45  struct s2
      46  {
      47    u32 i;
      48    u32 j; /* { dg-message "field 'j' is uninitialized \\(4 bytes\\)" } */
      49  };
      50  
      51  void test_2a (void __user *dst, u32 a)
      52  {
      53    struct s2 s; /* { dg-message "region created on stack here" "where" } */
      54    /* { dg-message "capacity: 8 bytes" "capacity" { target *-*-* } .-1 } */
      55    s.i = a;
      56    copy_to_user(dst, &s, sizeof (struct s2)); /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
      57    /* { dg-message "4 bytes are uninitialized" "note how much" { target *-*-* } .-1 } */
      58  }
      59  
      60  void test_2b (void __user *dst, u32 a)
      61  {
      62    struct s2 s;
      63    s.i = a;
      64    /* Copy with wrong size (only part of s2).  */
      65    copy_to_user(dst, &s, sizeof (struct s1));
      66  }
      67  
      68  void test_2d (void __user *dst, u32 a)
      69  {
      70    struct s2 s = {0};
      71    s.i = a;
      72    copy_to_user(dst, &s, sizeof (struct s2)); /* { dg-bogus" } */
      73  }
      74  
      75  struct empty {};
      76  
      77  void test_empty (void __user *dst)
      78  {
      79    struct empty e;
      80    copy_to_user(dst, &e, sizeof (struct empty));
      81  }
      82  
      83  union un_a
      84  {
      85    u32 i;
      86    u8  j;
      87  };
      88  
      89  /* As above, but in a different order.  */
      90  
      91  union un_b
      92  {
      93    u8  j;
      94    u32 i;
      95  };
      96  
      97  void test_union_1a (void __user *dst, u8 v)
      98  {
      99    union un_a u; /* { dg-message "region created on stack here" "where" } */
     100    /* { dg-message "capacity: 4 bytes" "capacity" { target *-*-* } .-1 } */
     101    u.j = v;
     102    copy_to_user(dst, &u, sizeof (union un_a)); /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
     103    /* { dg-message "3 bytes are uninitialized" "note how much" { target *-*-* } .-1 } */
     104    /* { dg-message "bytes 1 - 3 are uninitialized" "note how much" { target *-*-* } .-2 } */
     105  }
     106  
     107  void test_union_1b (void __user *dst, u8 v)
     108  {
     109    union un_b u; /* { dg-message "region created on stack here" "where" } */
     110    /* { dg-message "capacity: 4 bytes" "capacity" { target *-*-* } .-1 } */
     111    u.j = v;
     112    copy_to_user(dst, &u, sizeof (union un_b)); /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
     113    /* { dg-message "3 bytes are uninitialized" "note how much" { target *-*-* } .-1 } */
     114    /* { dg-message "bytes 1 - 3 are uninitialized" "note how much" { target *-*-* } .-2 } */
     115  }
     116  
     117  void test_union_2a (void __user *dst, u8 v)
     118  {
     119    union un_a u = {0};
     120    u.j = v;
     121    copy_to_user(dst, &u, sizeof (union un_a));
     122  }
     123  
     124  void test_union_2b (void __user *dst, u8 v)
     125  {
     126    union un_b u = {0};
     127    u.j = v;
     128    copy_to_user(dst, &u, sizeof (union un_b));
     129  }
     130  
     131  void test_union_3a (void __user *dst, u32 v)
     132  {
     133    union un_a u;
     134    u.i = v;
     135    copy_to_user(dst, &u, sizeof (union un_a)); /* { dg-bogus "" } */
     136  }
     137  
     138  void test_union_3b (void __user *dst, u32 v)
     139  {
     140    union un_b u;
     141    u.i = v;
     142    copy_to_user(dst, &u, sizeof (union un_b)); /* { dg-bogus "" } */
     143  }
     144  
     145  void test_union_4a (void __user *dst, u8 v)
     146  {
     147    union un_a u = {0};
     148    copy_to_user(dst, &u, sizeof (union un_a)); /* { dg-bogus "" } */
     149  }
     150  
     151  void test_union_4b (void __user *dst, u8 v)
     152  {
     153    union un_b u = {0};
     154    copy_to_user(dst, &u, sizeof (union un_b)); /* { dg-bogus "" } */
     155  }
     156  
     157  struct st_union_5
     158  {
     159    union {
     160      u8 f1;
     161      u32 f2;
     162    } u; /* { dg-message "field 'u' is partially uninitialized" } */
     163  };
     164  
     165  void test_union_5 (void __user *dst, u8 v)
     166  {
     167    struct st_union_5 st; /* { dg-message "region created on stack here" "where" } */
     168    /* { dg-message "capacity: 4 bytes" "capacity" { target *-*-* } .-1 } */
     169  
     170    /* This write only initializes the u8 within the union "u",
     171       leaving the remaining 3 bytes uninitialized.  */
     172    st.u.f1 = v;
     173  
     174    copy_to_user (dst, &st, sizeof(st)); /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
     175    /* { dg-message "3 bytes are uninitialized" "note how much" { target *-*-* } .-1 } */
     176  }
     177  
     178  void test_one_byte (void __user *dst)
     179  {
     180    char src;  /* { dg-message "region created on stack here" "where" } */
     181    /* { dg-message "capacity: 1 byte" "capacity" { target *-*-* } .-1 } */
     182  
     183    copy_to_user (dst, &src, sizeof(src)); /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" } */
     184    /* { dg-message "1 byte is uninitialized" "note how much" { target *-*-* } .-1 } */
     185  }