Thread: [BUG/PATCH] backend crashes during authentication if data/global/pg_pwd is empty
[BUG/PATCH] backend crashes during authentication if data/global/pg_pwd is empty
From
Michael Wildpaner
Date:
Hi, on Solaris 9 with PostgreSQL 7.4: when you - 'initdb' a fresh database, - _don't_ set a password for user 'postgres', - convert the 'trust' lines in data/pg_hba.confto 'md5' or 'password' and then try to connect as user 'postgres', the backend crashes in backend/libpq/hba.c:372: 368 static int 369 user_group_bsearch_cmp(const void *user, const void *list) 370 { 371 /* first node isline number */ 372 char *user2 = lfirst(lnext(*(List **) list)); due to 'list' being NULL, which might mean that 'user_sorted' was never allocated, due to user_length being zero for an missing or empty global/pg_pwd: 916 /* create sorted lines for binary searching */ 917 user_length = length(user_lines); 918 if (user_length) 919 { 920 int i = 0; 921 922 user_sorted= palloc(user_length * sizeof(List *)); I know this is looks like a case of "don't do it, then", but since it's a backend crash, I would suggest the following fix: --- postgresql-7.4.orig/src/backend/libpq/hba.c 2003-10-25 05:48:46.000001000 +0200 +++ postgresql-7.4/src/backend/libpq/hba.c 2003-12-05 15:21:54.000003000 +0100 @@ -62,7 +62,7 @@static List **user_sorted = NULL; /* sorted user list, for bsearch() */static List **group_sorted= NULL; /* sorted group list, for * bsearch() */ -static int user_length; +static int user_length = 0;static int group_length; static List *tokenize_file(FILE *file); @@ -395,6 +395,10 @@List **get_user_line(const char *user){ + /* fail if there is nothing to search in */ + if ((user_sorted == NULL) || (user_length == 0)) + return NULL; + return (List **) bsearch((void *) user, (void *) user_sorted, user_length, The initialization of user_length might not be necessary. Best wishes, Mike PS: This might be related to http://archives.postgresql.org/pgsql-admin/2003-03/msg00413.php -- Life is like a fire. DI Michael Wildpaner Flames which the passer-by forgets. Ph.D. Student Ashes which the wind scatters. A man lived. -- Omar Khayyam
Re: [BUG/PATCH] backend crashes during authentication if data/global/pg_pwd is empty
From
Tom Lane
Date:
Michael Wildpaner <mike@rainbow.studorg.tuwien.ac.at> writes: > + /* fail if there is nothing to search in */ > + if ((user_sorted == NULL) || (user_length == 0)) > + return NULL; Hm, Solaris' bsearch() fails on empty input? How bizarre. Easily worked around though --- thanks for the report! I suspect we'd better put a defense in get_group_line as well. It looks like there are no other places at risk in the backend. regards, tom lane
Re: [BUG/PATCH] backend crashes during authentication if data/global/pg_pwd is empty
From
Tom Lane
Date:
> Hm, Solaris' bsearch() fails on empty input? How bizarre. I was skeptical but apparently this is a known bug ... googling turned up a couple of references, eg http://www.opencm.org/pipermail/opencm-dev/2002-July/001077.html regards, tom lane
Hi, On Fri, 5 Dec 2003, Tom Lane wrote: > > Hm, Solaris' bsearch() fails on empty input? How bizarre. > > I was skeptical but apparently this is a known bug ... > googling turned up a couple of references, eg > http://www.opencm.org/pipermail/opencm-dev/2002-July/001077.html in defense of Solaris' bsearch it should be said that it only breaks if one passes NULL as the array base, a decidedly undefined (and unfriendly) case. Passing an array with zero elements works as advertised. Btw, the same happens on IRIX. Best wishes, Mike PS: A little program to demonstrate this: array with elements, empty array, NULL pointer as base: #include <stdio.h> #include <stdlib.h> #include <string.h> char strings[][4] = { "abc", "efg", "hij", "klm" }; typedef int (*cmp_t)(const void*, const void*); int main(int argc, char**argv) { char *s, *term = "hij"; s = bsearch(term, strings, sizeof(strings)/sizeof(char[4]), sizeof(char*), (cmp_t) strcmp); fprintf(stderr,"1: %s\n", (s != NULL) ? s : "<not found>"); s = bsearch(term, strings, 0, sizeof(char*), (cmp_t) strcmp); fprintf(stderr, "2: %s\n", (s != NULL) ? s : "<not found>"); s = bsearch(term, NULL, 0, sizeof(char*), (cmp_t) strcmp); fprintf(stderr, "3: %s\n", (s != NULL) ? s : "<not found>"); return 0; } Results: $ ./a.out # Solaris 9 1: hij 2: <not found> Segmentation Fault (core dumped) $ ./a.out # IRIX 6.5 1: hij 2: <not found> Segmentation fault (core dumped) $ ./a.out # Linux with glibc 2.2.5 1: hij 2: <not found> 3: <not found> $ ./a.out # OpenBSD 3.2 1: hij 2: <not found> 3: <not found> -- Life is like a fire. DI Michael Wildpaner Flames which the passer-by forgets. Ph.D. Student Ashes which the wind scatters. A man lived. -- Omar Khayyam