libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / testsuite / gcc.dg / plugin / infoleak-CVE-2011-1078-1.c
blob8afce8eefac2b5a935996c673ea8715a95cd9aef
1 /* "The sco_sock_getsockopt_old function in net/bluetooth/sco.c in the
2 Linux kernel before 2.6.39 does not initialize a certain structure,
3 which allows local users to obtain potentially sensitive information
4 from kernel stack memory via the SCO_CONNINFO option."
6 Fixed e.g. by c4c896e1471aec3b004a693c689f60be3b17ac86 on linux-2.6.39.y
7 in linux-stable. */
9 /* { dg-do compile } */
10 /* { dg-options "-fanalyzer" } */
11 /* { dg-require-effective-target analyzer } */
12 /* { dg-skip-if "structure layout assumption not met" { default_packed } } */
14 #include <string.h>
16 typedef unsigned char __u8;
17 typedef unsigned short __u16;
19 #include "test-uaccess.h"
21 /* Adapted from include/asm-generic/uaccess.h. */
23 #define get_user(x, ptr) \
24 ({ \
25 /* [...snip...] */ \
26 __get_user_fn(sizeof (*(ptr)), ptr, &(x)); \
27 /* [...snip...] */ \
30 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
32 size = copy_from_user(x, ptr, size);
33 return size ? -1 : size;
36 /* Adapted from include/linux/kernel.h. */
38 #define min_t(type, x, y) ({ \
39 type __min1 = (x); \
40 type __min2 = (y); \
41 __min1 < __min2 ? __min1: __min2; })
43 /* Adapted from include/linux/net.h. */
45 struct socket {
46 /* [...snip...] */
47 struct sock *sk;
48 /* [...snip...] */
51 /* Adapted from include/net/bluetooth/sco.h. */
53 struct sco_conninfo {
54 __u16 hci_handle;
55 __u8 dev_class[3]; /* { dg-message "padding after field 'dev_class' is uninitialized \\(1 byte\\)" } */
58 struct sco_conn {
60 struct hci_conn *hcon;
61 /* [...snip...] */
64 #define sco_pi(sk) ((struct sco_pinfo *) sk)
66 struct sco_pinfo {
67 /* [...snip...] */
68 struct sco_conn *conn;
71 /* Adapted from include/net/bluetooth/hci_core.h. */
73 struct hci_conn {
74 /* [...snip...] */
75 __u16 handle;
76 /* [...snip...] */
77 __u8 dev_class[3];
78 /* [...snip...] */
81 /* Adapted from sco_sock_getsockopt_old in net/bluetooth/sco.c. */
83 static int sco_sock_getsockopt_old_broken(struct socket *sock, int optname, char __user *optval, int __user *optlen)
85 struct sock *sk = sock->sk;
86 /* [...snip...] */
87 struct sco_conninfo cinfo; /* { dg-message "region created on stack here" "where" } */
88 /* { dg-message "capacity: 6 bytes" "capacity" { target *-*-* } .-1 } */
89 /* Note: 40 bits of fields, padded to 48. */
91 int len, err = 0;
93 /* [...snip...] */
95 if (get_user(len, optlen))
96 return -1;
98 /* [...snip...] */
100 /* case SCO_CONNINFO: */
101 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
102 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
104 len = min_t(unsigned int, len, sizeof(cinfo));
105 if (copy_to_user(optval, (char *)&cinfo, len)) /* { dg-warning "potential exposure of sensitive information by copying uninitialized data from stack" "warning" { target *-*-* } } */
106 /* { dg-message "1 byte is uninitialized" "how much note" { target *-*-* } .-1 } */
107 err = -1;
109 /* [...snip...] */
112 static int sco_sock_getsockopt_fixed(struct socket *sock, int optname, char __user *optval, int __user *optlen)
114 struct sock *sk = sock->sk;
115 /* [...snip...] */
116 struct sco_conninfo cinfo;
117 /* Note: 40 bits of fields, padded to 48. */
119 int len, err = 0;
121 /* [...snip...] */
123 if (get_user(len, optlen))
124 return -1;
126 /* [...snip...] */
128 /* case SCO_CONNINFO: */
129 /* Infoleak fixed by this memset call. */
130 memset(&cinfo, 0, sizeof(cinfo));
131 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
132 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
134 len = min_t(unsigned int, len, sizeof(cinfo));
135 if (copy_to_user(optval, (char *)&cinfo, len)) /* { dg-bogus "exposure" } */
136 err = -1;
138 /* [...snip...] */