diff options
author | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-13 08:58:46 +0000 |
---|---|---|
committer | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-13 08:58:46 +0000 |
commit | ba187736c174c79b085c205027799b62ae14634b (patch) | |
tree | e408266eb2bc72e5cd9cb46d1b3a54782a26c0de | |
parent | cd734582c151824710104daceb0cd266ea3d2944 (diff) | |
download | gcc-ba187736c174c79b085c205027799b62ae14634b.tar.gz |
PR rtl-optimization/53908
* gcc.dg/torture/pr53908.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189455 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr53908.c | 288 |
2 files changed, 293 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd23d61bcdc..0e2b8f30a5b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-07-13 Hans-Peter Nilsson <hp@axis.com> + + PR rtl-optimization/53908 + * gcc.dg/torture/pr53908.c: New test. + 2012-07-13 Jonathan Wakely <jwakely.gcc@gmail.com> PR c++/53531 diff --git a/gcc/testsuite/gcc.dg/torture/pr53908.c b/gcc/testsuite/gcc.dg/torture/pr53908.c new file mode 100644 index 00000000000..e96b6352232 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr53908.c @@ -0,0 +1,288 @@ +/* { dg-do run } */ +/* SEGV at comment below. */ +typedef unsigned int size_t; +typedef enum har { + he_fatal = (-199), + he_not_initialized, + he_bad_input, + he_memory_too_small, + he_bad_action, + he_duplicate, + he_bad_nonce, + he_stale_nonce, + he_bad_credentials, + he_bad_user, + he_no_such_user, + he_bad_passwd, + he_unknown_auth_scheme, + he_not_found, + he_failed_digest_file_check, + he_failed_digest_file_save, + he_process_not_privileged, + he_other, + he_end_of_range, + ha_no_error = 0, + ha_no_value = 1 +} har; +typedef enum realm_type +{ + axis_realm = 0, + ws_realm +} realm_type; + +__attribute__((__noclone__, __noinline__)) +har has_www_auth(char *, size_t, realm_type, har); + +__attribute__((__noclone__, __noinline__)) +har has_auth_user(const char *, const char *, realm_type, char *, size_t); + +__attribute__((__noclone__, __noinline__)) +char *ha_get_string_value(void); + +typedef struct +{ + unsigned int track_id; + char* user; + char* realm; + char* authent; + int internal_realm; +} request; +enum user_response { + file_not_found_user_response = -3, + access_denied_user_response = -2, + no_user_response = -1, + ok_user_response = 0 +}; +struct realm_group { + char *name; + int id; + struct realm_group *next; +}; +struct realm { + char *name; + char *space; + struct realm_group *groups; + struct realm *next; +}; +struct user_info { + char *name; + int no_groups; + int groups[128]; + struct user_info *next; +}; +static struct user_info *find_user(const char *user_name); +static int is_member_of_groups(const struct user_info *user_item, + const struct realm_group *groups); +int authent_author(request *req); +struct realm *realms = ((void *)0); +struct user_info *users = ((void *)0); +static struct user_info* +find_user(const char *user_name) +{ + struct user_info *user_item; + user_item = users; + while (user_item != ((void *)0)) { + /* SEGV due to NULL access here on user_name. See also comment below. */ + if ((__builtin_strcmp(user_item->name, user_name) == 0)) + break; + user_item = user_item->next; + } + return user_item; +} +static int +is_member_of_groups(const struct user_info *user_item, + const struct realm_group *groups) +{ + const struct realm_group *group_item; + int i; + group_item = groups; + while (group_item != ((void *)0)) { + for (i = 0; i < user_item->no_groups; i++) + if (user_item->groups[i] == group_item->id) + return 0; + group_item = group_item->next; + } + return -1; +} +char *foo (void) __attribute__((__noclone__, __noinline__)); +char* g_strdup (const char *str) __attribute__((__malloc__, __noclone__, __noinline__)); +int g_strcmp0 (const char *str1, const char *str2); +static int +is_basic(char **user) +{ + char *passwd_ptr; + char *authent = foo(); + passwd_ptr = __builtin_strchr(authent, ':'); + if (passwd_ptr != ((void *)0)) { + *user = g_strdup(authent); + return 0; + } + return -1; +} +static int +is_digest(char **user) +{ + int ret_val = -1; + char *authent; + authent = ha_get_string_value(); + if (authent) { + *user = g_strdup(authent); + ret_val = 0; + } + return ret_val; +} +__attribute__((__noclone__, __noinline__)) +void g_free (void * mem); +static enum user_response +get_user_info_from_header(const realm_type type, + char **user_name, + struct user_info **user_item) +{ + int ret_val = no_user_response; + if ((type == ws_realm)) { + if (is_basic(user_name) == 0) + ret_val = access_denied_user_response; + if (is_digest(user_name) == 0) + ret_val = ok_user_response; + } else { + if (is_basic(user_name) < 0 && + /* Load of *user_name here, but not after the is_digest call. */ + is_digest(user_name) < 0) + ; + else if ((*user_item = find_user(*user_name)) != ((void *)0)) + ret_val = ok_user_response; + else + ret_val = access_denied_user_response; + if (ret_val != ok_user_response) + g_free(*user_name); + } + return ret_val; +} +static enum user_response +authenticate_user(request *req, + char **user_name, + struct user_info **user_item) +{ + char *authent = ((void *)0); + har resp = ha_no_value; + enum user_response user_resp; + int ret_val = no_user_response; + if (req->authent && __builtin_strlen(req->authent)) { + authent = req->authent; + user_resp = get_user_info_from_header(req->internal_realm, + user_name, + user_item); + if (user_resp == ok_user_response) { + resp = has_auth_user(authent, 0, req->internal_realm, "", 1); + if (resp == ha_no_error) + ret_val = ok_user_response; + else if (resp != he_stale_nonce) + ret_val = access_denied_user_response; + } else if (user_resp == access_denied_user_response) + ret_val = access_denied_user_response; + } + if (resp != he_memory_too_small && resp != ha_no_error) + resp = has_www_auth("", 1, req->internal_realm, resp); + return ret_val; +} + +int __attribute__ ((__noinline__, __noclone__)) +authent_author(request *req) +{ + struct realm *realm; + char *user_name = ((void *)0); + struct user_info *user_item = ((void *)0); + int res = 0; + asm (""); + realm = realms; + if (__builtin_strcmp("Wsd", realm->name) == 0) { + req->internal_realm = ws_realm; + is_digest(&user_name); + } + if (authenticate_user(req, &user_name, &user_item) < 0) { + if (user_name != ((void *)0)) + req->user = user_name; + res = -2; + goto authent_author_return; + } + if (is_member_of_groups(user_item, realm->groups) < 0) + res = -1; +authent_author_return: + return res; +} + +int good0, good1, good2; + +__attribute__ ((__noinline__, __noclone__)) +char *foo(void) +{ + asm (""); + good0++; + return ""; +} + +__attribute__ ((__noinline__, __noclone__)) +char *ha_get_string_value(void) +{ + asm (""); + good1++; + return "f"; +} + +__attribute__ ((__noinline__, __noclone__)) +har has_auth_user(const char *a, const char *b, realm_type c, char *d, size_t e) +{ + asm (""); + if (*a != 'z' || a[1] != 0 || b != 0 || c != axis_realm || *d != 0 + || e != 1) + __builtin_abort (); + return ha_no_error; +} + +__attribute__ ((__noinline__, __noclone__)) +har has_www_auth(char *a, size_t b, realm_type c, har d) +{ + (void)(*a+b+c+d); + asm (""); + __builtin_abort (); +} + + +char *strdupped_user = "me"; +__attribute__((__malloc__, __noclone__, __noinline__)) +char* g_strdup (const char *str) +{ + asm (""); + if (*str != 'f') + __builtin_abort (); + good2++; + return strdupped_user; +} + +__attribute__((__noclone__, __noinline__)) +void g_free (void * mem) +{ + (void)mem; + asm (""); + __builtin_abort (); +} + +struct user_info me = { .name = "me", .no_groups = 1, .groups = {42}, .next = 0}; +struct user_info you = { .name = "you", .next = &me}; +struct realm_group xgroups = { .name = "*", .id = 42, .next = 0}; + +int main(void) +{ + char *orig_user = "?"; + struct realm r = { .name = "x", .space = "space?", .groups = &xgroups, .next = 0}; + request req = { .user = orig_user, .realm = "!", .authent = "z", + .internal_realm = axis_realm}; + realms = &r; + users = &you; + if (authent_author (&req) != 0 || good0 != 1 || good1 != 1 || good2 != 1 + || req.user != orig_user + || req.internal_realm != axis_realm) + __builtin_abort (); + __builtin_exit (0); +} + |