From: Ken Raeburn Date: Tue, 20 Jun 2006 23:59:11 +0000 (+0000) Subject: getaddrinfo code uses vars outside of storage duration X-Git-Tag: krb5-1.6-alpha1~284 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=f5f7c801239586dfa38519dac0b46c2b11d0f0d9;p=krb5.git getaddrinfo code uses vars outside of storage duration The calls to gethostbyname_r and friends were wrapped in macros that declared automatic variables for the auxiliary storage needed, but the pointers returned by the functions would be used outside of that scope, when the storage would no longer be valid. Changed the macro interfaces to define new types for the auxiliary storage, and add a new argument to the macros referring to that storage. Changed call sites accordingly. ticket: new git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18180 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/util/support/fake-addrinfo.c b/src/util/support/fake-addrinfo.c index 922dc8d9b..89a789df7 100644 --- a/src/util/support/fake-addrinfo.c +++ b/src/util/support/fake-addrinfo.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001,2002,2003,2004,2005 by the Massachusetts Institute of Technology, + * Copyright (C) 2001,2002,2003,2004,2005,2006 by the Massachusetts Institute of Technology, * Cambridge, MA, USA. All Rights Reserved. * * This software is being provided to you, the LICENSEE, by the @@ -162,20 +162,23 @@ extern /*@dependent@*/ char *gai_strerror (int code) /*@*/; either getaddrinfo or one of these two flavors of gethostbyname_r? */ #if !defined(HAVE_GETHOSTBYNAME_R) || defined(THREADSAFE_GETHOSTBYNAME) -#define GET_HOST_BY_NAME(NAME, HP, ERR) \ - { (HP) = gethostbyname (NAME); (ERR) = h_errno; } -#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \ - { (HP) = gethostbyaddr ((ADDR), (ADDRLEN), (FAMILY)); (ERR) = h_errno; } +typedef struct hostent *GET_HOST_TMP; +#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \ + { TMP = gethostbyname (NAME); (ERR) = h_errno; (HP) = TMP; } +#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR, TMP) \ + { TMP = gethostbyaddr ((ADDR), (ADDRLEN), (FAMILY)); (ERR) = h_errno; (HP) = TMP; } #else #ifdef _AIX /* XXX should have a feature test! */ -#define GET_HOST_BY_NAME(NAME, HP, ERR) \ - { \ - struct hostent my_h_ent; \ - struct hostent_data my_h_ent_data; \ - (HP) = (gethostbyname_r((NAME), &my_h_ent, &my_h_ent_data) \ - ? 0 \ - : &my_h_ent); \ - (ERR) = h_errno; \ +typedef struct { + struct hostent ent; + struct hostent_data data; +} GET_HOST_TMP; +#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \ + { \ + (HP) = (gethostbyname_r((NAME), &TMP.ent, &TMP.data) \ + ? 0 \ + : &my_h_ent); \ + (ERR) = h_errno; \ } /* #define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \ @@ -191,48 +194,46 @@ extern /*@dependent@*/ char *gai_strerror (int code) /*@*/; */ #else #ifdef GETHOSTBYNAME_R_RETURNS_INT -#define GET_HOST_BY_NAME(NAME, HP, ERR) \ +typedef struct { + struct hostent ent, *hp; + int err; + char buf[8192]; +} GET_HOST_TMP; +#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \ { \ - struct hostent my_h_ent, *my_hp; \ - int my_h_err; \ - char my_h_buf[8192]; \ - (HP) = (gethostbyname_r((NAME), &my_h_ent, \ - my_h_buf, sizeof (my_h_buf), &my_hp, \ - &my_h_err) \ + (HP) = (gethostbyname_r((NAME), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf), &TMP.hp, \ + &TMP.err) \ ? 0 \ - : &my_h_ent); \ - (ERR) = my_h_err; \ + : &TMP.ent); \ + (ERR) = TMP.err; \ } -#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \ +#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR, TMP) \ { \ - struct hostent my_h_ent, *my_hp; \ - int my_h_err; \ - char my_h_buf[8192]; \ - (HP) = (gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent, \ - my_h_buf, sizeof (my_h_buf), &my_hp, \ - &my_h_err) \ + (HP) = (gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf), &TMP.hp, \ + &TMP.err) \ ? 0 \ - : &my_h_ent); \ - (ERR) = my_h_err; \ + : &TMP.ent); \ + (ERR) = TMP.err; \ } #else -#define GET_HOST_BY_NAME(NAME, HP, ERR) \ +typedef struct { + struct hostent ent; + int err; + char buf[8192]; +} GET_HOST_TMP; +#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \ { \ - struct hostent my_h_ent; \ - int my_h_err; \ - char my_h_buf[8192]; \ - (HP) = gethostbyname_r((NAME), &my_h_ent, \ - my_h_buf, sizeof (my_h_buf), &my_h_err); \ - (ERR) = my_h_err; \ + (HP) = gethostbyname_r((NAME), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf), &TMP.err); \ + (ERR) = TMP.err; \ } -#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \ +#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR, TMP) \ { \ - struct hostent my_h_ent; \ - int my_h_err; \ - char my_h_buf[8192]; \ - (HP) = gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent, \ - my_h_buf, sizeof (my_h_buf), &my_h_err); \ - (ERR) = my_h_err; \ + (HP) = gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf), &TMP.err); \ + (ERR) = TMP.err; \ } #endif /* returns int? */ #endif /* _AIX */ @@ -240,53 +241,56 @@ extern /*@dependent@*/ char *gai_strerror (int code) /*@*/; /* Now do the same for getservby* functions. */ #ifndef HAVE_GETSERVBYNAME_R -#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR) \ - ((SP) = getservbyname (NAME, PROTO), (ERR) = (SP) ? 0 : -1) -#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR) \ - ((SP) = getservbyport (PORT, PROTO), (ERR) = (SP) ? 0 : -1) +typedef struct servent *GET_SERV_TMP; +#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR, TMP) \ + (TMP = getservbyname (NAME, PROTO), (SP) = TMP, (ERR) = (SP) ? 0 : -1) +#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR, TMP) \ + (TMP = getservbyport (PORT, PROTO), (SP) = TMP, (ERR) = (SP) ? 0 : -1) #else #ifdef GETSERVBYNAME_R_RETURNS_INT -#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR) \ +typedef struct { + struct servent ent, *sp; + int err; + char buf[8192]; +} GET_SERV_TMP; +#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR, TMP) \ { \ - struct servent my_s_ent, *my_sp; \ - int my_s_err; \ - char my_s_buf[8192]; \ - (SP) = (getservbyname_r((NAME), (PROTO), &my_s_ent, \ - my_s_buf, sizeof (my_s_buf), &my_sp, \ - &my_s_err) \ + struct servent *my_sp; \ + (SP) = (getservbyname_r((NAME), (PROTO), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf), &my_sp, \ + &TMP.err) \ ? 0 \ - : &my_s_ent); \ - (ERR) = my_s_err; \ + : &TMP.ent); \ + (ERR) = TMP.err; \ } -#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR) \ +#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR, TMP) \ { \ - struct servent my_s_ent, *my_sp; \ - int my_s_err; \ - char my_s_buf[8192]; \ - (SP) = (getservbyport_r((PORT), (PROTO), &my_s_ent, \ - my_s_buf, sizeof (my_s_buf), &my_sp, \ - &my_s_err) \ + struct servent *my_sp; \ + (SP) = (getservbyport_r((PORT), (PROTO), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf), &my_sp, \ + &TMP.err) \ ? 0 \ - : &my_s_ent); \ - (ERR) = my_s_err; \ + : &TMP.ent); \ + (ERR) = TMP.err; \ } #else /* returns ptr -- IRIX? */ -#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR) \ +typedef struct { + struct servent ent; + char buf[8192]; +} GET_SERV_TMP; +#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR, TMP) \ { \ - struct servent my_s_ent; \ - char my_s_buf[8192]; \ - (SP) = getservbyname_r((NAME), (PROTO), &my_s_ent, \ - my_s_buf, sizeof (my_s_buf)); \ + (SP) = getservbyname_r((NAME), (PROTO), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf)); \ (ERR) = (SP) == NULL; \ } -#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR) \ +#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR, TMP) \ { \ - struct servent my_s_ent, *my_sp; \ - char my_s_buf[8192]; \ - my_sp = getservbyport_r((PORT), (PROTO), &my_s_ent, \ - my_s_buf, sizeof (my_s_buf)); \ + struct servent *my_sp; \ + my_sp = getservbyport_r((PORT), (PROTO), &TMP.ent, \ + TMP.buf, sizeof (TMP.buf)); \ (SP) = my_sp; \ (ERR) = my_sp == 0; \ (ERR) = (ERR); /* avoid "unused" warning */ \ @@ -774,8 +778,9 @@ static inline int fai_add_hosts_by_name (const char *name, struct hostent *hp; int i, r; int herr; + GET_HOST_TMP htmp; - GET_HOST_BY_NAME (name, hp, herr); + GET_HOST_BY_NAME (name, hp, herr, htmp); if (hp == 0) return translate_h_errno (herr); for (i = 0; hp->h_addr_list[i]; i++) { @@ -840,6 +845,7 @@ fake_getaddrinfo (const char *name, const char *serv, } else { struct servent *sp; int try_dgram_too = 0, s_err; + GET_SERV_TMP stmp; if (socktype == 0) { try_dgram_too = 1; @@ -847,7 +853,7 @@ fake_getaddrinfo (const char *name, const char *serv, } try_service_lookup: GET_SERV_BY_NAME(serv, socktype == SOCK_STREAM ? "tcp" : "udp", - sp, s_err); + sp, s_err, stmp); if (sp == 0) { if (try_dgram_too) { socktype = SOCK_DGRAM; @@ -952,9 +958,11 @@ fake_getnameinfo (const struct sockaddr *sa, socklen_t len, #endif } else { int herr; + GET_HOST_TMP htmp; + GET_HOST_BY_ADDR((const char *) &sinp->sin_addr, sizeof (struct in_addr), - sa->sa_family, hp, herr); + sa->sa_family, hp, herr, htmp); if (hp == 0) { if (herr == NO_ADDRESS && !(flags & NI_NAMEREQD)) /* ??? */ goto numeric_host; @@ -980,9 +988,11 @@ fake_getnameinfo (const struct sockaddr *sa, socklen_t len, strncpy (service, numbuf, slen); } else { int serr; + GET_SERV_TMP stmp; + GET_SERV_BY_PORT(sinp->sin_port, (flags & NI_DGRAM) ? "udp" : "tcp", - sp, serr); + sp, serr, stmp); if (sp == 0) goto numeric_service; strncpy (service, sp->s_name, slen); @@ -1185,13 +1195,14 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint, struct hostent *hp; const char *name2 = 0; int i, herr; + GET_HOST_TMP htmp; /* * Current versions of GET_HOST_BY_NAME will fail if the * target hostname has IPv6 addresses only. Make sure it * fails fairly cleanly. */ - GET_HOST_BY_NAME (name, hp, herr); + GET_HOST_BY_NAME (name, hp, herr, htmp); if (hp == 0) { /* * This case probably means it's an IPv6-only name. If diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c index 9d025942e..6a40b4a43 100644 --- a/src/util/support/plugins.c +++ b/src/util/support/plugins.c @@ -97,7 +97,7 @@ krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct void *handle = NULL; if (!err) { - handle = dlopen(filepath, RTLD_NOW | RTLD_GLOBAL); + handle = dlopen(filepath, RTLD_NOW /*| RTLD_GLOBAL*/); if (handle == NULL) { const char *e = dlerror(); Tprintf ("dlopen(%s): %s\n", filepath, e);