Author: brane
Date: Sun Oct 14 15:57:51 2018
New Revision: 1843844
URL: http://svn.apache.org/viewvc?rev=1843844&view=rev
Log:
On Linux, only check ELF headers of loaded shared libraries when
we have the ELF API available. Also, include executable files
in the list.
* configure.ac: Check for elf.h
* subversion/libsvn_subr/sysinfo.c: Optionally include elf.h.
(parse_pointer_value): Move to conditional block.
(check_elf_heade): New.
(linux_shared_libs): Make all ELF-specific checks conditional.
Modified:
subversion/trunk/configure.ac
subversion/trunk/subversion/libsvn_subr/sysinfo.c
Modified: subversion/trunk/configure.ac
URL:
http://svn.apache.org/viewvc/subversion/trunk/configure.ac?rev=1843844&r1=1843843&r2=1843844&view=diff
==============================================================================
--- subversion/trunk/configure.ac (original)
+++ subversion/trunk/configure.ac Sun Oct 14 15:57:51 2018
@@ -948,8 +948,9 @@ AC_FUNC_VPRINTF
dnl check for functions needed in special file handling
AC_CHECK_FUNCS(symlink readlink)
-dnl check for uname
+dnl check for uname and ELF headers
AC_CHECK_HEADERS(sys/utsname.h, [AC_CHECK_FUNCS(uname)], [])
+AC_CHECK_HEADERS(elf.h)
dnl check for termios
AC_CHECK_HEADER(termios.h,[
Modified: subversion/trunk/subversion/libsvn_subr/sysinfo.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/sysinfo.c?rev=1843844&r1=1843843&r2=1843844&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/trunk/subversion/libsvn_subr/sysinfo.c Sun Oct 14 15:57:51 2018
@@ -55,12 +55,16 @@
#include <sys/types.h>
#endif
+#if HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
-#if HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
+#if HAVE_ELF_H
+#include <elf.h>
#endif
#ifdef SVN_HAVE_MACOS_PLIST
@@ -672,6 +676,7 @@ linux_release_name(apr_pool_t *pool)
return apr_psprintf(pool, "%s [%s]", release_name, uname_release);
}
+#if HAVE_ELF_H
/* Parse a hexadecimal number as a pointer value. */
static const unsigned char *
parse_pointer_value(const char *start, const char *limit, char **end)
@@ -691,6 +696,48 @@ parse_pointer_value(const char *start, c
return ptr;
}
+/* Read the ELF header at the mapping position to check if this is a shared
+ library. We only look at the ELF identification and the type. The format is
+ described here:
+ http://www.skyfree.org/linux/references/ELF_Format.pdf
+*/
+static svn_boolean_t
+check_elf_header(const unsigned char *map_start,
+ const unsigned char *map_end)
+{
+ /* A union of all known ELF header types, for size checks. */
+ union max_elf_header_size_t
+ {
+ Elf32_Ehdr header_32;
+ Elf64_Ehdr header_64;
+ };
+
+ /* Check the size of the mapping and the ELF magic tag. */
+ if (map_end < map_start
+ || map_end - map_start < sizeof(union max_elf_header_size_t)
+ || memcmp(map_start, ELFMAG, SELFMAG))
+ {
+ return FALSE;
+ }
+
+ /* Check that this is an ELF shared library or executable file. This also
+ implicitly checks that the data encoding of the current process is the
+ same as in the loaded library. */
+ if (map_start[EI_CLASS] == ELFCLASS32)
+ {
+ const Elf32_Ehdr *hdr = (void*)map_start;
+ return (hdr->e_type == ET_DYN || hdr->e_type == ET_EXEC);
+ }
+ else if (map_start[EI_CLASS] == ELFCLASS64)
+ {
+ const Elf64_Ehdr *hdr = (void*)map_start;
+ return (hdr->e_type == ET_DYN || hdr->e_type == ET_EXEC);
+ }
+
+ return FALSE;
+}
+#endif /* HAVE_ELF_H */
+
static const apr_array_header_t *
linux_shared_libs(apr_pool_t *pool)
{
@@ -716,8 +763,11 @@ linux_shared_libs(apr_pool_t *pool)
while (!eof)
{
svn_stringbuf_t *line;
+
+#if HAVE_ELF_H
const unsigned char *map_start;
const unsigned char *map_end;
+#endif
err = svn_stream_readline(stream, &line, "\n", &eof, pool);
if (err)
@@ -726,6 +776,7 @@ linux_shared_libs(apr_pool_t *pool)
return NULL;
}
+#if HAVE_ELF_H
/* Address: The mapped memory address range. */
{
const char *const limit = line->data + line->len;
@@ -741,6 +792,7 @@ linux_shared_libs(apr_pool_t *pool)
if (!map_end || !svn_ctype_isspace(*end))
continue;
}
+#endif
stringbuf_skip_whitespace_field(line); /* skip address */
@@ -766,31 +818,10 @@ linux_shared_libs(apr_pool_t *pool)
{
svn_version_ext_loaded_lib_t *lib;
- /* Read the ELF header at the mapping position to check if this is
- a shared library. We only look at the ELF identification and the
- type. The format is described here:
- http://www.skyfree.org/linux/references/ELF_Format.pdf
- */
- if (map_end < map_start || map_end - map_start < 18
- || memcmp(map_start, "\x7f" "ELF", 4))
+#if HAVE_ELF_H
+ if (!check_elf_header(map_start, map_end))
continue;
-
- /* The ELF Type is 0x0003 for shared object files. */
- switch (map_start[5]) /* Data encoding */
- {
- case 1: /* Little-Endian */
- if (map_start[16] != 3 || map_start[17] != 0)
- continue;
- break;
-
- case 2: /* Big-Endian */
- if (map_start[16] != 0 || map_start[17] != 3)
- continue;
- break;
-
- default:
- continue;
- }
+#endif
/* We've done our best to find a mapped shared library. */
if (!result)