summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-13 08:58:46 +0000
committerhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-13 08:58:46 +0000
commitba187736c174c79b085c205027799b62ae14634b (patch)
treee408266eb2bc72e5cd9cb46d1b3a54782a26c0de
parentcd734582c151824710104daceb0cd266ea3d2944 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr53908.c288
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);
+}
+