diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 3 | ||||
-rw-r--r-- | sysdeps/posix/getaddrinfo.c | 130 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/glob64.c | 22 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S | 16 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S | 16 |
9 files changed, 119 insertions, 88 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index ffeb093..9d767b6 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -590,9 +590,6 @@ struct rtld_global_ro /* List of auditing interfaces. */ struct audit_ifaces *_dl_audit; unsigned int _dl_naudit; - - /* 0 if internal pointer values should not be guarded, 1 if they should. */ - EXTERN int _dl_pointer_guard; }; # define __rtld_global_attribute__ # ifdef IS_IN_rtld diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index d2283bc..df6ce8b 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -168,9 +168,58 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, return 0; } +/* Convert struct hostent to a list of struct gaih_addrtuple objects. + h_name is not copied, and the struct hostent object must not be + deallocated prematurely. *RESULT must be NULL or a pointer to an + object allocated using malloc, which is freed. */ +static bool +convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, + int family, + struct hostent *h, + struct gaih_addrtuple **result) +{ + free (*result); + *result = NULL; + + /* Count the number of addresses in h->h_addr_list. */ + size_t count = 0; + for (char **p = h->h_addr_list; *p != NULL; ++p) + ++count; + + /* Report no data if no addresses are available, or if the incoming + address size is larger than what we can store. */ + if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr)) + return true; + + struct gaih_addrtuple *array = calloc (count, sizeof (*array)); + if (array == NULL) + return false; + + for (size_t i = 0; i < count; ++i) + { + if (family == AF_INET && req->ai_family == AF_INET6) + { + /* Perform address mapping. */ + array[i].family = AF_INET6; + memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t)); + array[i].addr[2] = htonl (0xffff); + } + else + { + array[i].family = family; + memcpy (array[i].addr, h->h_addr_list[i], h->h_length); + } + array[i].next = array + i + 1; + } + array[0].name = h->h_name; + array[count - 1].next = NULL; + + *result = array; + return true; +} + #define gethosts(_family, _type) \ { \ - int i; \ int herrno; \ struct hostent th; \ struct hostent *h; \ @@ -219,36 +268,23 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, } \ else if (h != NULL) \ { \ - for (i = 0; h->h_addr_list[i]; i++) \ + /* Make sure that addrmem can be freed. */ \ + if (!malloc_addrmem) \ + addrmem = NULL; \ + if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \ { \ - if (*pat == NULL) \ - { \ - *pat = __alloca (sizeof (struct gaih_addrtuple)); \ - (*pat)->scopeid = 0; \ - } \ - uint32_t *addr = (*pat)->addr; \ - (*pat)->next = NULL; \ - (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \ - if (_family == AF_INET && req->ai_family == AF_INET6) \ - { \ - (*pat)->family = AF_INET6; \ - addr[3] = *(uint32_t *) h->h_addr_list[i]; \ - addr[2] = htonl (0xffff); \ - addr[1] = 0; \ - addr[0] = 0; \ - } \ - else \ - { \ - (*pat)->family = _family; \ - memcpy (addr, h->h_addr_list[i], sizeof(_type)); \ - } \ - pat = &((*pat)->next); \ + _res.options |= old_res_options & RES_USE_INET6; \ + result = -EAI_SYSTEM; \ + goto free_and_return; \ } \ + *pat = addrmem; \ + /* The conversion uses malloc unconditionally. */ \ + malloc_addrmem = true; \ \ if (localcanon != NULL && canon == NULL) \ canon = strdupa (localcanon); \ \ - if (_family == AF_INET6 && i > 0) \ + if (_family == AF_INET6 && *pat != NULL) \ got_ipv6 = true; \ } \ } @@ -612,44 +648,16 @@ gaih_inet (const char *name, const struct gaih_service *service, { if (h != NULL) { - int i; - /* We found data, count the number of addresses. */ - for (i = 0; h->h_addr_list[i]; ++i) - ; - if (i > 0 && *pat != NULL) - --i; - - if (__libc_use_alloca (alloca_used - + i * sizeof (struct gaih_addrtuple))) - addrmem = alloca_account (i * sizeof (struct gaih_addrtuple), - alloca_used); - else - { - addrmem = malloc (i - * sizeof (struct gaih_addrtuple)); - if (addrmem == NULL) - { - result = -EAI_MEMORY; - goto free_and_return; - } - malloc_addrmem = true; - } - - /* Now convert it into the list. */ - struct gaih_addrtuple *addrfree = addrmem; - for (i = 0; h->h_addr_list[i]; ++i) + /* We found data, convert it. */ + if (!convert_hostent_to_gaih_addrtuple + (req, AF_INET, h, &addrmem)) { - if (*pat == NULL) - { - *pat = addrfree++; - (*pat)->scopeid = 0; - } - (*pat)->next = NULL; - (*pat)->family = AF_INET; - memcpy ((*pat)->addr, h->h_addr_list[i], - h->h_length); - pat = &((*pat)->next); + result = -EAI_MEMORY; + goto free_and_return; } + *pat = addrmem; + /* The conversion uses malloc unconditionally. */ + malloc_addrmem = true; } } else diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/i386/glob64.c index b4fcd1a..802c957 100644 --- a/sysdeps/unix/sysv/linux/i386/glob64.c +++ b/sysdeps/unix/sysv/linux/i386/glob64.c @@ -1,3 +1,21 @@ +/* Two glob variants with 64-bit support, for dirent64 and __olddirent64. + Copyright (C) 1998-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + #include <dirent.h> #include <glob.h> #include <sys/stat.h> @@ -38,11 +56,15 @@ int __old_glob64 (const char *__pattern, int __flags, #undef dirent #define dirent __old_dirent64 +#undef GL_READDIR +# define GL_READDIR(pglob, stream) \ + ((struct __old_dirent64 *) (pglob)->gl_readdir (stream)) #undef __readdir #define __readdir(dirp) __old_readdir64 (dirp) #undef glob #define glob(pattern, flags, errfunc, pglob) \ __old_glob64 (pattern, flags, errfunc, pglob) +#define convert_dirent __old_convert_dirent #define glob_in_dir __old_glob_in_dir #define GLOB_ATTRIBUTE attribute_compat_text_section diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S index 83cf0d8..67ea206 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S @@ -17,6 +17,14 @@ #include <sysdep.h> +/* We do not want .eh_frame info so that __makecontext_ret stops unwinding + if backtrace was called within a context created by makecontext. (There + is also no .eh_frame info for _start or thread_start.) */ +#undef cfi_startproc +#define cfi_startproc +#undef cfi_endproc +#define cfi_endproc + ENTRY(__makecontext_ret) basr %r14,%r7 ltr %r8,%r8 /* Check whether uc_link is 0. */ diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S index 42839e2..b263773 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S @@ -34,7 +34,7 @@ ENTRY(__setcontext) lr %r1,%r2 /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */ - la %r2,SIG_BLOCK + la %r2,SIG_SETMASK la %r3,SC_MASK(%r1) slr %r4,%r4 lhi %r5,_NSIG8 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S index 9206aa3..8f9cfd8 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S @@ -24,7 +24,7 @@ /* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) Saves the machine context in oucp such that when it is activated, - it appears as if __swapcontextt() returned again, restores the + it appears as if __swapcontext() returned again, restores the machine context in ucp and thereby resumes execution in that context. @@ -39,13 +39,6 @@ ENTRY(__swapcontext) lr %r1,%r2 lr %r0,%r3 - /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ - la %r2,SIG_BLOCK - slr %r3,%r3 - la %r4,SC_MASK(%r1) - lhi %r5,_NSIG8 - svc SYS_ify(rt_sigprocmask) - /* Store fpu context. */ stfpc SC_FPC(%r1) std %f0,SC_FPRS(%r1) @@ -74,11 +67,12 @@ ENTRY(__swapcontext) /* Store general purpose registers. */ stm %r0,%r15,SC_GPRS(%r1) - /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ - la %r2,SIG_BLOCK + /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, + sigsetsize). */ + la %r2,SIG_SETMASK lr %r5,%r0 la %r3,SC_MASK(%r5) - slr %r4,%r4 + la %r4,SC_MASK(%r1) lhi %r5,_NSIG8 svc SYS_ify(rt_sigprocmask) diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S index 71ecbab..a2bf3ca 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S @@ -17,6 +17,14 @@ #include <sysdep.h> +/* We do not want .eh_frame info so that __makecontext_ret stops unwinding + if backtrace was called within a context created by makecontext. (There + is also no .eh_frame info for _start or thread_start.) */ +#undef cfi_startproc +#define cfi_startproc +#undef cfi_endproc +#define cfi_endproc + ENTRY(__makecontext_ret) basr %r14,%r7 ltgr %r8,%r8 /* Check whether uc_link is 0. */ diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S index 83df5ce..1464e6a 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S @@ -34,7 +34,7 @@ ENTRY(__setcontext) lgr %r1,%r2 /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ - la %r2,SIG_BLOCK + la %r2,SIG_SETMASK la %r3,SC_MASK(%r1) slgr %r4,%r4 lghi %r5,_NSIG8 diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S index e3e624c..8346fd5 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S @@ -24,7 +24,7 @@ /* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) Saves the machine context in oucp such that when it is activated, - it appears as if __swapcontextt() returned again, restores the + it appears as if __swapcontext() returned again, restores the machine context in ucp and thereby resumes execution in that context. @@ -39,13 +39,6 @@ ENTRY(__swapcontext) lgr %r1,%r2 lgr %r0,%r3 - /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ - la %r2,SIG_BLOCK - slgr %r3,%r3 - la %r4,SC_MASK(%r1) - lghi %r5,_NSIG8 - svc SYS_ify(rt_sigprocmask) - /* Store fpu context. */ stfpc SC_FPC(%r1) std %f0,SC_FPRS(%r1) @@ -74,12 +67,13 @@ ENTRY(__swapcontext) /* Store general purpose registers. */ stmg %r0,%r15,SC_GPRS(%r1) - /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */ - la %r2,SIG_BLOCK + /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, + sigsetsize). */ + la %r2,SIG_SETMASK lgr %r5,%r0 la %r3,SC_MASK(%r5) + la %r4,SC_MASK(%r1) lghi %r5,_NSIG8 - slgr %r4,%r4 svc SYS_ify(rt_sigprocmask) /* Load fpu context. */ |