1/* { dg-do run } */ 2/* SEGV at comment below. */ 3typedef unsigned int size_t; 4typedef enum har { 5 he_fatal = (-199), 6 he_not_initialized, 7 he_bad_input, 8 he_memory_too_small, 9 he_bad_action, 10 he_duplicate, 11 he_bad_nonce, 12 he_stale_nonce, 13 he_bad_credentials, 14 he_bad_user, 15 he_no_such_user, 16 he_bad_passwd, 17 he_unknown_auth_scheme, 18 he_not_found, 19 he_failed_digest_file_check, 20 he_failed_digest_file_save, 21 he_process_not_privileged, 22 he_other, 23 he_end_of_range, 24 ha_no_error = 0, 25 ha_no_value = 1 26} har; 27typedef enum realm_type 28{ 29 axis_realm = 0, 30 ws_realm 31} realm_type; 32 33__attribute__((__noclone__, __noinline__)) 34har has_www_auth(char *, size_t, realm_type, har); 35 36__attribute__((__noclone__, __noinline__)) 37har has_auth_user(const char *, const char *, realm_type, char *, size_t); 38 39__attribute__((__noclone__, __noinline__)) 40char *ha_get_string_value(void); 41 42typedef struct 43{ 44 unsigned int track_id; 45 char* user; 46 char* realm; 47 char* authent; 48 int internal_realm; 49} request; 50enum user_response { 51 file_not_found_user_response = -3, 52 access_denied_user_response = -2, 53 no_user_response = -1, 54 ok_user_response = 0 55}; 56struct realm_group { 57 char *name; 58 int id; 59 struct realm_group *next; 60}; 61struct realm { 62 char *name; 63 char *space; 64 struct realm_group *groups; 65 struct realm *next; 66}; 67struct user_info { 68 char *name; 69 int no_groups; 70 int groups[128]; 71 struct user_info *next; 72}; 73static struct user_info *find_user(const char *user_name); 74static int is_member_of_groups(const struct user_info *user_item, 75 const struct realm_group *groups); 76int authent_author(request *req); 77struct realm *realms = ((void *)0); 78struct user_info *users = ((void *)0); 79static struct user_info* 80find_user(const char *user_name) 81{ 82 struct user_info *user_item; 83 user_item = users; 84 while (user_item != ((void *)0)) { 85 /* SEGV due to NULL access here on user_name. See also comment below. */ 86 if ((__builtin_strcmp(user_item->name, user_name) == 0)) 87 break; 88 user_item = user_item->next; 89 } 90 return user_item; 91} 92static int 93is_member_of_groups(const struct user_info *user_item, 94 const struct realm_group *groups) 95{ 96 const struct realm_group *group_item; 97 int i; 98 group_item = groups; 99 while (group_item != ((void *)0)) { 100 for (i = 0; i < user_item->no_groups; i++) 101 if (user_item->groups[i] == group_item->id) 102 return 0; 103 group_item = group_item->next; 104 } 105 return -1; 106} 107char *foo (void) __attribute__((__noclone__, __noinline__)); 108char* g_strdup (const char *str) __attribute__((__malloc__, __noclone__, __noinline__)); 109int g_strcmp0 (const char *str1, const char *str2); 110static int 111is_basic(char **user) 112{ 113 char *passwd_ptr; 114 char *authent = foo(); 115 passwd_ptr = __builtin_strchr(authent, ':'); 116 if (passwd_ptr != ((void *)0)) { 117 *user = g_strdup(authent); 118 return 0; 119 } 120 return -1; 121} 122static int 123is_digest(char **user) 124{ 125 int ret_val = -1; 126 char *authent; 127 authent = ha_get_string_value(); 128 if (authent) { 129 *user = g_strdup(authent); 130 ret_val = 0; 131 } 132 return ret_val; 133} 134__attribute__((__noclone__, __noinline__)) 135void g_free (void * mem); 136static enum user_response 137get_user_info_from_header(const realm_type type, 138 char **user_name, 139 struct user_info **user_item) 140{ 141 int ret_val = no_user_response; 142 if ((type == ws_realm)) { 143 if (is_basic(user_name) == 0) 144 ret_val = access_denied_user_response; 145 if (is_digest(user_name) == 0) 146 ret_val = ok_user_response; 147 } else { 148 if (is_basic(user_name) < 0 && 149 /* Load of *user_name here, but not after the is_digest call. */ 150 is_digest(user_name) < 0) 151 ; 152 else if ((*user_item = find_user(*user_name)) != ((void *)0)) 153 ret_val = ok_user_response; 154 else 155 ret_val = access_denied_user_response; 156 if (ret_val != ok_user_response) 157 g_free(*user_name); 158 } 159 return ret_val; 160} 161static enum user_response 162authenticate_user(request *req, 163 char **user_name, 164 struct user_info **user_item) 165{ 166 char *authent = ((void *)0); 167 har resp = ha_no_value; 168 enum user_response user_resp; 169 int ret_val = no_user_response; 170 if (req->authent && __builtin_strlen(req->authent)) { 171 authent = req->authent; 172 user_resp = get_user_info_from_header(req->internal_realm, 173 user_name, 174 user_item); 175 if (user_resp == ok_user_response) { 176 resp = has_auth_user(authent, 0, req->internal_realm, "", 1); 177 if (resp == ha_no_error) 178 ret_val = ok_user_response; 179 else if (resp != he_stale_nonce) 180 ret_val = access_denied_user_response; 181 } else if (user_resp == access_denied_user_response) 182 ret_val = access_denied_user_response; 183 } 184 if (resp != he_memory_too_small && resp != ha_no_error) 185 resp = has_www_auth("", 1, req->internal_realm, resp); 186 return ret_val; 187} 188 189int __attribute__ ((__noinline__, __noclone__)) 190authent_author(request *req) 191{ 192 struct realm *realm; 193 char *user_name = ((void *)0); 194 struct user_info *user_item = ((void *)0); 195 int res = 0; 196 asm (""); 197 realm = realms; 198 if (__builtin_strcmp("Wsd", realm->name) == 0) { 199 req->internal_realm = ws_realm; 200 is_digest(&user_name); 201 } 202 if (authenticate_user(req, &user_name, &user_item) < 0) { 203 if (user_name != ((void *)0)) 204 req->user = user_name; 205 res = -2; 206 goto authent_author_return; 207 } 208 if (is_member_of_groups(user_item, realm->groups) < 0) 209 res = -1; 210authent_author_return: 211 return res; 212} 213 214int good0, good1, good2; 215 216__attribute__ ((__noinline__, __noclone__)) 217char *foo(void) 218{ 219 asm (""); 220 good0++; 221 return ""; 222} 223 224__attribute__ ((__noinline__, __noclone__)) 225char *ha_get_string_value(void) 226{ 227 asm (""); 228 good1++; 229 return "f"; 230} 231 232__attribute__ ((__noinline__, __noclone__)) 233har has_auth_user(const char *a, const char *b, realm_type c, char *d, size_t e) 234{ 235 asm (""); 236 if (*a != 'z' || a[1] != 0 || b != 0 || c != axis_realm || *d != 0 237 || e != 1) 238 __builtin_abort (); 239 return ha_no_error; 240} 241 242__attribute__ ((__noinline__, __noclone__)) 243har has_www_auth(char *a, size_t b, realm_type c, har d) 244{ 245 (void)(*a+b+c+d); 246 asm (""); 247 __builtin_abort (); 248} 249 250 251char *strdupped_user = "me"; 252__attribute__((__malloc__, __noclone__, __noinline__)) 253char* g_strdup (const char *str) 254{ 255 asm (""); 256 if (*str != 'f') 257 __builtin_abort (); 258 good2++; 259 return strdupped_user; 260} 261 262__attribute__((__noclone__, __noinline__)) 263void g_free (void * mem) 264{ 265 (void)mem; 266 asm (""); 267 __builtin_abort (); 268} 269 270struct user_info me = { .name = "me", .no_groups = 1, .groups = {42}, .next = 0}; 271struct user_info you = { .name = "you", .next = &me}; 272struct realm_group xgroups = { .name = "*", .id = 42, .next = 0}; 273 274int main(void) 275{ 276 char *orig_user = "?"; 277 struct realm r = { .name = "x", .space = "space?", .groups = &xgroups, .next = 0}; 278 request req = { .user = orig_user, .realm = "!", .authent = "z", 279 .internal_realm = axis_realm}; 280 realms = &r; 281 users = &you; 282 if (authent_author (&req) != 0 || good0 != 1 || good1 != 1 || good2 != 1 283 || req.user != orig_user 284 || req.internal_realm != axis_realm) 285 __builtin_abort (); 286 __builtin_exit (0); 287} 288 289