NaCl: Use open_resource API for shared objects

This commit is contained in:
Roland McGrath 2015-11-10 19:44:48 -08:00
parent 71d1b0166b
commit c0d6f2a33e
6 changed files with 159 additions and 8 deletions

View File

@ -1,3 +1,16 @@
2015-11-10 Roland McGrath <roland@hack.frob.com>
* elf/dl-load.c (open_verify): Take new argument FD.
Skip __open call if passed FD is not -1.
(_dl_map_object, open_path): Update callers.
* elf/dl-sysdep-open.h: New file.
* elf/dl-load.c: Include it.
(_dl_map_object): Try _dl_sysdep_open_object before ldconfig cache.
* sysdeps/nacl/dl-sysdep.c (_dl_sysdep_open_object): New function.
* sysdeps/nacl/dl-sysdep-open.h: New file.
* sysdeps/nacl/nacl-interface-list.h: Move nacl_irt_resource_open
from libc to rtld.
2015-11-10 Joseph Myers <joseph@codesourcery.com>
[BZ #19228]

View File

@ -43,6 +43,7 @@
#include <dl-map-segments.h>
#include <dl-unmap-segments.h>
#include <dl-machine-reject-phdr.h>
#include <dl-sysdep-open.h>
#include <endian.h>
@ -1483,9 +1484,13 @@ print_search_path (struct r_search_path_elem **list,
ignore only ELF files for other architectures. Non-ELF files and
ELF files with different header information cause fatal errors since
this could mean there is something wrong in the installation and the
user might want to know about this. */
user might want to know about this.
If FD is not -1, then the file is already open and FD refers to it.
In that case, FD is consumed for both successful and error returns. */
static int
open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
open_verify (const char *name, int fd,
struct filebuf *fbp, struct link_map *loader,
int whatcode, int mode, bool *found_other_class, bool free_name)
{
/* This is the expected ELF header. */
@ -1526,6 +1531,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
&& loader->l_auditing == 0)
{
const char *original_name = name;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
@ -1540,11 +1546,21 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
afct = afct->next;
}
if (fd != -1 && name != original_name && strcmp (name, original_name))
{
/* An audit library changed what we're supposed to open,
so FD no longer matches it. */
__close (fd);
fd = -1;
}
}
#endif
/* Open the file. We always open files read-only. */
int fd = __open (name, O_RDONLY | O_CLOEXEC);
if (fd == -1)
/* Open the file. We always open files read-only. */
fd = __open (name, O_RDONLY | O_CLOEXEC);
if (fd != -1)
{
ElfW(Ehdr) *ehdr;
@ -1813,7 +1829,7 @@ open_path (const char *name, size_t namelen, int mode,
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
_dl_debug_printf (" trying file=%s\n", buf);
fd = open_verify (buf, fbp, loader, whatcode, mode,
fd = open_verify (buf, -1, fbp, loader, whatcode, mode,
found_other_class, false);
if (this_dir->status[cnt] == unknown)
{
@ -2064,6 +2080,20 @@ _dl_map_object (struct link_map *loader, const char *name,
&loader->l_runpath_dirs, &realname, &fb, loader,
LA_SER_RUNPATH, &found_other_class);
if (fd == -1)
{
realname = _dl_sysdep_open_object (name, namelen, &fd);
if (realname != NULL)
{
fd = open_verify (realname, fd,
&fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
LA_SER_CONFIG, mode, &found_other_class,
false);
if (fd == -1)
free (realname);
}
}
#ifdef USE_LDCONFIG
if (fd == -1
&& (__glibc_likely ((mode & __RTLD_SECURE) == 0)
@ -2109,7 +2139,7 @@ _dl_map_object (struct link_map *loader, const char *name,
if (cached != NULL)
{
fd = open_verify (cached,
fd = open_verify (cached, -1,
&fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
LA_SER_CONFIG, mode, &found_other_class,
false);
@ -2144,7 +2174,7 @@ _dl_map_object (struct link_map *loader, const char *name,
fd = -1;
else
{
fd = open_verify (realname, &fb,
fd = open_verify (realname, -1, &fb,
loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode,
&found_other_class, true);
if (__glibc_unlikely (fd == -1))

45
elf/dl-sysdep-open.h Normal file
View File

@ -0,0 +1,45 @@
/* System-specific call to open a shared object by name. Stub version.
Copyright (C) 2015 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/>. */
#ifndef _DL_SYSDEP_OPEN_H
#define _DL_SYSDEP_OPEN_H 1
#include <assert.h>
#include <stddef.h>
/* NAME is a name without slashes, as it appears in a DT_NEEDED entry
or a dlopen call's argument or suchlike. NAMELEN is (strlen (NAME) + 1).
Find NAME in an OS-dependent fashion, and return its "real" name.
Optionally fill in *FD with a file descriptor open on that file (or
else leave its initial value of -1). The return value is a new
malloc'd string, which will be free'd by the caller. If NAME is
resolved to an actual file that can be opened, then the return
value should name that file (and if *FD was not set, then a normal
__open call on that string will be made). If *FD was set by some
other means than a normal open and there is no "real" name to use,
then __strdup (NAME) is fine (modulo error checking). */
static inline char *
_dl_sysdep_open_object (const char *name, size_t namelen, int *fd)
{
assert (*fd == -1);
return NULL;
}
#endif /* dl-sysdep-open.h */

View File

@ -0,0 +1,40 @@
/* System-specific call to open a shared object by name. NaCl version.
Copyright (C) 2015 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/>. */
#ifndef _DL_SYSDEP_OPEN_H
#define _DL_SYSDEP_OPEN_H 1
#include <stddef.h>
/* NAME is a name without slashes, as it appears in a DT_NEEDED entry
or a dlopen call's argument or suchlike. NAMELEN is (strlen (NAME) + 1).
Find NAME in an OS-dependent fashion, and return its "real" name.
Optionally fill in *FD with a file descriptor open on that file (or
else leave its initial value of -1). The return value is a new
malloc'd string, which will be free'd by the caller. If NAME is
resolved to an actual file that can be opened, then the return
value should name that file (and if *FD was not set, then a normal
__open call on that string will be made). If *FD was set by some
other means than a normal open and there is no "real" name to use,
then __strdup (NAME) is fine (modulo error checking). */
extern char *_dl_sysdep_open_object (const char *name, size_t namelen, int *fd)
internal_function attribute_hidden;
#endif /* dl-sysdep-open.h */

View File

@ -87,3 +87,26 @@ _dl_start_user (void (*user_entry) (uint32_t info[]), uint32_t info[])
#endif /* SHARED */
#include <elf/dl-sysdep.c>
#include <dl-sysdep-open.h>
#include <nacl-interfaces.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
char *
internal_function
_dl_sysdep_open_object (const char *name, size_t namelen, int *fd)
{
int error = __nacl_irt_resource_open.open_resource (name, fd);
if (error)
return NULL;
assert (*fd != -1);
char *realname = __strdup (name);
if (__glibc_unlikely (realname == NULL))
{
__close (*fd);
*fd = -1;
}
return realname;
}

View File

@ -28,7 +28,7 @@ NACL_MANDATORY_INTERFACE (rtld,
NACL_IRT_FUTEX_v0_1, nacl_irt_futex)
NACL_MANDATORY_INTERFACE (rtld,
NACL_IRT_TLS_v0_1, nacl_irt_tls)
NACL_MANDATORY_INTERFACE (libc,
NACL_MANDATORY_INTERFACE (rtld,
NACL_IRT_RESOURCE_OPEN_v0_1, nacl_irt_resource_open)
NACL_MANDATORY_INTERFACE (rtld,
NACL_IRT_CODE_DATA_ALLOC_v0_1,