diff --git a/ChangeLog b/ChangeLog index a254cc09aa..e6995d9a8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,33 @@ DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ. Add DF_ORIGIN, DF_SYMBOLIC, DF_TEXTREL, and DF_BIND_NOW. + * posix/unistd.h: Move declaration of __libc_enable_secure to... + * include/unistd.h: ...here. + + * elf/dl-open.c (dl_open_worker): If DST is used in SUID program punt. + * elf/dl-deps.c (expand_dst): Likewise. + + * elf/dynamic-link.h: Set DT_SYMBOLIC, DT_TEXTREL, and DT_BIND_NOW + based on DT_FLAGS value. + + * elf/do-lookup.h: Remove reference_name parameter, add undef_map. + Add test for symbols marked STV_HIDDEN. + * elf/dl-lookup.c (_dl_lookup_symbol): Remove reference_name parameter, + add undef_map. Compute reference_name locally. Update call to + do_lookup. + (_dl_lookup_symbol_skip): Likewise. + (_dl_lookup_versioned_symbol): Likewise. + (_dl_lookup_versioned_symbol_skip): Likewise. + * elf/dl-libc.c: Update call to _dl_lookup_*symbol. + * elf/dl-runtime.c: Likewise. + * elf/dl-sym.c: Likewise. + * elf/dl-symbol.c: Likewise. + * elf/ldsodefs.h: Adjust prototypes. + + * elf/dl-reloc.c (RESOLV): Add test for STV_PROTECTED flag set and + handle appropriately. Add comment about DT_TEXTREL. + * elf/dl-runtime.c: Likewise. + 1999-07-21 Roland McGrath * elf/dl-reloc.c (_dl_reloc_bad_type): New function. diff --git a/elf/dl-deps.c b/elf/dl-deps.c index b981d490df..68e4921ce5 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -96,9 +97,15 @@ struct list \ if (__cnt != 0) \ { \ - char *__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, \ - strlen (__str), \ - __cnt)); \ + char *__newp; \ + \ + /* DST must not appear in SUID/SGID programs. */ \ + if (__libc_enable_secure) \ + _dl_signal_error (0, __str, \ + "DST not allowed in SUID/SGID programs"); \ + \ + __newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str), \ + __cnt)); \ \ __result = DL_DST_SUBSTITUTE (l, __str, __newp, 0); \ \ diff --git a/elf/dl-libc.c b/elf/dl-libc.c index afb3f2d14e..784af27c3d 100644 --- a/elf/dl-libc.c +++ b/elf/dl-libc.c @@ -82,9 +82,8 @@ do_dlsym (void *ptr) { struct do_dlsym_args *args = (struct do_dlsym_args *) ptr; args->ref = NULL; - args->loadbase = _dl_lookup_symbol (args->name, &args->ref, - args->map->l_local_scope, - args->map->l_name, 0); + args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref, + args->map->l_local_scope, 0); } static void diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 16173c9068..4120cb1e64 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -75,11 +75,11 @@ unsigned long int _dl_num_relocations; ElfW(Addr) internal_function -_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, - struct r_scope_elem *symbol_scope[], - const char *reference_name, +_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, + const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], int reloc_type) { + const char *reference_name = undef_map ? undef_map->l_name : NULL; const unsigned long int hash = _dl_elf_hash (undef_name); struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; @@ -88,8 +88,8 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, /* Search the relevant loaded objects for a definition. */ for (scope = symbol_scope; *scope; ++scope) - if (do_lookup (undef_name, hash, *ref, ¤t_value, - *scope, 0, reference_name, NULL, reloc_type)) + if (do_lookup (undef_name, undef_map, hash, *ref, ¤t_value, + *scope, 0, NULL, reloc_type)) break; if (current_value.s == NULL) @@ -125,11 +125,12 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, SKIP_MAP is only skipped. */ ElfW(Addr) internal_function -_dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref, +_dl_lookup_symbol_skip (const char *undef_name, + struct link_map *undef_map, const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], - const char *reference_name, struct link_map *skip_map) { + const char *reference_name = undef_map ? undef_map->l_name : NULL; const unsigned long int hash = _dl_elf_hash (undef_name); struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; @@ -143,11 +144,11 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref, assert (i < (*scope)->r_nduplist); if (i >= (*scope)->r_nlist - || ! do_lookup (undef_name, hash, *ref, ¤t_value, - *scope, i, reference_name, skip_map, 0)) + || ! do_lookup (undef_name, undef_map, hash, *ref, ¤t_value, + *scope, i, skip_map, 0)) while (*++scope) - if (do_lookup (undef_name, hash, *ref, ¤t_value, - *scope, 0, reference_name, skip_map, 0)) + if (do_lookup (undef_name, undef_map, hash, *ref, ¤t_value, + *scope, 0, skip_map, 0)) break; if (current_value.s == NULL) @@ -177,12 +178,13 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref, XXX We'll see whether we need this separate function. */ ElfW(Addr) internal_function -_dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref, +_dl_lookup_versioned_symbol (const char *undef_name, + struct link_map *undef_map, const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], - const char *reference_name, const struct r_found_version *version, int reloc_type) { + const char *reference_name = undef_map ? undef_map->l_name : NULL; const unsigned long int hash = _dl_elf_hash (undef_name); struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; @@ -192,8 +194,8 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref, /* Search the relevant loaded objects for a definition. */ for (scope = symbol_scope; *scope; ++scope) { - int res = do_lookup_versioned (undef_name, hash, *ref, ¤t_value, - *scope, 0, reference_name, version, NULL, + int res = do_lookup_versioned (undef_name, undef_map, hash, *ref, + ¤t_value, *scope, 0, version, NULL, reloc_type); if (res > 0) break; @@ -250,12 +252,13 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref, ElfW(Addr) internal_function _dl_lookup_versioned_symbol_skip (const char *undef_name, + struct link_map *undef_map, const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], - const char *reference_name, const struct r_found_version *version, struct link_map *skip_map) { + const char *reference_name = undef_map ? undef_map->l_name : NULL; const unsigned long int hash = _dl_elf_hash (undef_name); struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; @@ -269,11 +272,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name, assert (i < (*scope)->r_nduplist); if (i >= (*scope)->r_nlist - || ! do_lookup_versioned (undef_name, hash, *ref, ¤t_value, *scope, - i, reference_name, version, skip_map, 0)) + || ! do_lookup_versioned (undef_name, undef_map, hash, *ref, + ¤t_value, *scope, i, version, skip_map, + 0)) while (*++scope) - if (do_lookup_versioned (undef_name, hash, *ref, ¤t_value, *scope, - 0, reference_name, version, skip_map, 0)) + if (do_lookup_versioned (undef_name, undef_map, hash, *ref, + ¤t_value, *scope, 0, version, skip_map, + 0)) break; if (current_value.s == NULL) diff --git a/elf/dl-open.c b/elf/dl-open.c index a3cd8a05a3..097fd372c0 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -20,9 +20,10 @@ #include #include #include +#include #include #include -#include +#include #include /* Check whether MAP_COPY is defined. */ #include #include @@ -100,6 +101,12 @@ dl_open_worker (void *a) struct link_map *call_map; char *new_file; + /* DSTs must not appear in SUID/SGID programs. */ + if (__libc_enable_secure) + /* This is an error. */ + _dl_signal_error (0, "dlopen", + "DST not allowed in SUID/SGID programs"); + /* We have to find out from which object the caller is calling. Find the highest-addressed object that ADDRESS is not below. */ call_map = NULL; diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 0bf39a8b5e..a1c235a398 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -71,11 +71,13 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ #define RESOLVE(ref, version, flags) \ - ((version) != NULL && (version)->hash != 0 \ - ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \ - l->l_name, (version), (flags)) \ - : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \ - l->l_name, (flags))) + (ELFW(ST_VISIBILITY) ((*ref)->st_other) != STV_PROTECTED \ + ? ((version) != NULL && (version)->hash != 0 \ + ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \ + scope, (version), (flags)) \ + : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope, \ + (flags))) \ + : l->l_addr) #include "dynamic-link.h" ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); @@ -96,6 +98,9 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], /* Mark the object so we know this work has been done. */ l->l_relocated = 1; + /* DT_TEXTREL is now in level 2 and might phase out at some time. + But we rewrite the DT_FLAGS entry to make testing easier and + therefore it will be available at all time. */ if (l->l_info[DT_TEXTREL]) { /* Undo the protection change we made before relocating. */ diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 9f3004ecf5..a55fbf6e4b 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -66,32 +66,40 @@ fixup ( /* Sanity check that we're really looking at a PLT relocation. */ assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - /* Look up the target symbol. */ - switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + /* Look up the target symbol. If the symbol is marked STV_PROTEXTED + don't look in the global scope. */ + if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED) { - default: - { - const ElfW(Half) *vernum = - (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr; - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; - const struct r_found_version *version = &l->l_versions[ndx]; - - if (version->hash != 0) + switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + { + default: { - value = _dl_lookup_versioned_symbol(strtab + sym->st_name, - &sym, l->l_scope, l->l_name, - version, ELF_MACHINE_JMP_SLOT); - break; - } - } - case 0: - value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope, - l->l_name, ELF_MACHINE_JMP_SLOT); - } + const ElfW(Half) *vernum = + (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr; + ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; + const struct r_found_version *version = &l->l_versions[ndx]; - /* Currently value contains the base load address of the object - that defines sym. Now add in the symbol offset. */ - value = (sym ? value + sym->st_value : 0); + if (version->hash != 0) + { + value = _dl_lookup_versioned_symbol(strtab + sym->st_name, l, + &sym, l->l_scope, version, + ELF_MACHINE_JMP_SLOT); + break; + } + } + case 0: + value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, + l->l_scope, ELF_MACHINE_JMP_SLOT); + } + + /* Currently value contains the base load address of the object + that defines sym. Now add in the symbol offset. */ + value = (sym ? value + sym->st_value : 0); + } + else + /* We already found the symbol. The module (and therefore its load + address) is also known. */ + value = l->l_addr + sym->st_value; /* And now perhaps the relocation addend. */ value = elf_machine_plt_value (l, reloc, value); @@ -141,33 +149,41 @@ profile_fixup ( /* Sanity check that we're really looking at a PLT relocation. */ assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - /* Look up the target symbol. */ - switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + /* Look up the target symbol. If the symbol is marked STV_PROTEXTED + don't look in the global scope. */ + if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED) { - default: - { - const ElfW(Half) *vernum = - (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr; - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; - const struct r_found_version *version = &l->l_versions[ndx]; - - if (version->hash != 0) + switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + { + default: { - value = _dl_lookup_versioned_symbol(strtab + sym->st_name, - &sym, l->l_scope, - l->l_name, version, - ELF_MACHINE_JMP_SLOT); - break; - } - } - case 0: - value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope, - l->l_name, ELF_MACHINE_JMP_SLOT); - } + const ElfW(Half) *vernum = + (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr; + ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; + const struct r_found_version *version = &l->l_versions[ndx]; - /* Currently value contains the base load address of the object - that defines sym. Now add in the symbol offset. */ - value = (sym ? value + sym->st_value : 0); + if (version->hash != 0) + { + value = _dl_lookup_versioned_symbol(strtab + sym->st_name, + l, &sym, l->l_scope, + version, + ELF_MACHINE_JMP_SLOT); + break; + } + } + case 0: + value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, + l->l_scope, ELF_MACHINE_JMP_SLOT); + } + + /* Currently value contains the base load address of the object + that defines sym. Now add in the symbol offset. */ + value = (sym ? value + sym->st_value : 0); + } + else + /* We already found the symbol. The module (and therefore its load + address) is also known. */ + value = l->l_addr + sym->st_value; /* And now perhaps the relocation addend. */ value = elf_machine_plt_value (l, reloc, value); diff --git a/elf/dl-sym.c b/elf/dl-sym.c index 441b54fe45..91ca1277df 100644 --- a/elf/dl-sym.c +++ b/elf/dl-sym.c @@ -34,7 +34,7 @@ _dl_sym (void *handle, const char *name, void *who) if (handle == RTLD_DEFAULT) /* Search the global scope. */ - loadbase = _dl_lookup_symbol (name, &ref, _dl_global_scope, NULL, 0); + loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0); else if (handle == RTLD_NEXT) { struct link_map *l, *match; @@ -54,15 +54,14 @@ RTLD_NEXT used in code not dynamically loaded")); while (l->l_loader) l = l->l_loader; - loadbase = _dl_lookup_symbol_skip (name, &ref, l->l_local_scope, - NULL, match); + loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope, + match); } else { /* Search the scope of the given object. */ struct link_map *map = handle; - loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope, - map->l_name, 0); + loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0); } if (loadbase) @@ -88,8 +87,8 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who) if (handle == RTLD_DEFAULT) /* Search the global scope. */ - loadbase = _dl_lookup_versioned_symbol (name, &ref, _dl_global_scope, - NULL, &vers, 0); + loadbase = _dl_lookup_versioned_symbol (name, NULL, &ref, _dl_global_scope, + &vers, 0); else if (handle == RTLD_NEXT) { struct link_map *l, *match; @@ -109,17 +108,16 @@ RTLD_NEXT used in code not dynamically loaded")); while (l->l_loader) l = l->l_loader; - loadbase = _dl_lookup_versioned_symbol_skip (name, &ref, + loadbase = _dl_lookup_versioned_symbol_skip (name, l, &ref, l->l_local_scope, - NULL, &vers, match); + &vers, match); } else { /* Search the scope of the given object. */ struct link_map *map = handle; - loadbase = _dl_lookup_versioned_symbol (name, &ref, - map->l_local_scope, - map->l_name, &vers, 0); + loadbase = _dl_lookup_versioned_symbol (name, map, &ref, + map->l_local_scope, &vers, 0); } if (loadbase) diff --git a/elf/dl-symbol.c b/elf/dl-symbol.c index 3ae44d6bea..945f5446ae 100644 --- a/elf/dl-symbol.c +++ b/elf/dl-symbol.c @@ -1,5 +1,5 @@ /* Look up a symbol's run-time value in the scope of a loaded object. - Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1998, 1999 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 @@ -28,7 +28,6 @@ _dl_symbol_value (struct link_map *map, const char *name) { ElfW(Addr) loadbase; const ElfW(Sym) *ref = NULL; - loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope, map->l_name, - 0); + loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0); return loadbase + ref->st_value; } diff --git a/elf/do-lookup.h b/elf/do-lookup.h index 147560bd32..f83b13ccf3 100644 --- a/elf/do-lookup.h +++ b/elf/do-lookup.h @@ -29,10 +29,10 @@ found the symbol, the value 0 if nothing is found and < 0 if something bad happened. */ static inline int -FCT (const char *undef_name, unsigned long int hash, - const ElfW(Sym) *ref, struct sym_val *result, - struct r_scope_elem *scope, size_t i, const char *reference_name, - ARG struct link_map *skip, int reloc_type) +FCT (const char *undef_name, struct link_map *undef_map, + unsigned long int hash, const ElfW(Sym) *ref, struct sym_val *result, + struct r_scope_elem *scope, size_t i, ARG struct link_map *skip, + int reloc_type) { struct link_map **list = scope->r_list; size_t n = scope->r_nlist; @@ -154,7 +154,12 @@ FCT (const char *undef_name, unsigned long int hash, sym = num_versions == 1 ? versioned_sym : NULL; #endif - if (sym != NULL) + if (sym != NULL + /* Don't allow binding if the symbol is hidden. When processor + specific definitions for STV_INTERNAL are defined we might + have to extend this conditional. */ + && (ELFW(ST_VISIBILITY) (sym->st_other) != STV_HIDDEN + || map == undef_map)) { found_it: switch (ELFW(ST_BIND) (sym->st_info)) diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index d322c1231f..59a6001069 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -93,6 +93,19 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr, info[DT_JMPREL]->d_un.d_ptr += l_addr; if (info[VERSYMIDX (DT_VERSYM)] != NULL) info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr; + if (info[DT_FLAGS] != NULL) + { + /* Flags are used. Translate to the old form where available. + Since these l_info entries are only tested for NULL pointers it + is ok if they point to the DT_FLAGS entry. */ + ElfW(Word) flags = info[DT_FLAGS]->d_un.d_val; + if (flags & DF_SYMBOLIC) + info[DT_SYMBOLIC] = info[DT_FLAGS]; + if (flags & DF_TEXTREL) + info[DT_TEXTREL] = info[DT_FLAGS]; + if (flags & DF_BIND_NOW) + info[DT_BIND_NOW] = info[DT_FLAGS]; + } } #ifdef RESOLVE diff --git a/elf/ldsodefs.h b/elf/ldsodefs.h index 483e85b085..15b7cc6037 100644 --- a/elf/ldsodefs.h +++ b/elf/ldsodefs.h @@ -260,35 +260,35 @@ extern void _dl_setup_hash (struct link_map *map) internal_function; the `elf_machine_lookup_*_p' macros in dl-machine.h to affect which symbols can be chosen. */ extern ElfW(Addr) _dl_lookup_symbol (const char *undef, + struct link_map *undef_map, const ElfW(Sym) **sym, struct r_scope_elem *symbol_scope[], - const char *reference_name, int reloc_type) internal_function; /* Lookup versioned symbol. */ extern ElfW(Addr) _dl_lookup_versioned_symbol (const char *undef, + struct link_map *undef_map, const ElfW(Sym) **sym, struct r_scope_elem *symbol_scope[], - const char *reference_name, const struct r_found_version *version, int reloc_type) internal_function; /* For handling RTLD_NEXT we must be able to skip shared objects. */ extern ElfW(Addr) _dl_lookup_symbol_skip (const char *undef, + struct link_map *undef_map, const ElfW(Sym) **sym, struct r_scope_elem *symbol_scope[], - const char *reference_name, struct link_map *skip_this) internal_function; /* For handling RTLD_NEXT with versioned symbols we must be able to skip shared objects. */ extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef, + struct link_map *undef_map, const ElfW(Sym) **sym, struct r_scope_elem *symbol_scope[], - const char *reference_name, const struct r_found_version *version, struct link_map *skip_this) internal_function; diff --git a/include/unistd.h b/include/unistd.h index 955637e0fb..06fa8fbd93 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -63,4 +63,13 @@ extern int __profil __P ((unsigned short int *__sample_buffer, size_t __size, size_t __offset, unsigned int __scale)); extern int __getdtablesize __P ((void)); extern int __brk __P ((__ptr_t __addr)); + + +/* This variable is set nonzero at startup if the process's effective + IDs differ from its real IDs, or it is otherwise indicated that + extra security should be used. When this is set the dynamic linker + and some functions contained in the C library ignore various + environment variables that normally affect them. */ +extern int __libc_enable_secure; + #endif diff --git a/posix/unistd.h b/posix/unistd.h index ea1d47b2fb..d8800b7b3b 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -927,16 +927,7 @@ extern int lockf64 __P ((int __fd, int __cmd, __off64_t __len)); ({ long int __result; \ do __result = (long int) (expression); \ while (__result == -1L && errno == EINTR); \ - __result; })) \ - - -/* This variable is set nonzero at startup if the process's effective - IDs differ from its real IDs, or it is otherwise indicated that - extra security should be used. When this is set the dynamic linker - and some functions contained in the C library ignore various - environment variables that normally affect them. */ -extern int __libc_enable_secure; - + __result; })) #endif #if defined __USE_POSIX199309 || defined __USE_UNIX98