|
Carlos O'Donell |
0e17ea2 |
Short description: Work ld.so --verify crash on debuginfo files.
|
|
Carlos O'Donell |
0e17ea2 |
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
|
Carlos O'Donell |
0e17ea2 |
Origin: PATCH
|
|
Carlos O'Donell |
0e17ea2 |
Bug-RHEL: #741105, #767146
|
|
Carlos O'Donell |
0e17ea2 |
Upstream status: not-needed
|
|
Carlos O'Donell |
0e17ea2 |
|
|
Carlos O'Donell |
0e17ea2 |
This change is designed to work around running ld.so on a debuginfo
|
|
Carlos O'Donell |
0e17ea2 |
file. This is the wrong fix for this problem and should be dropped.
|
|
Carlos O'Donell |
0e17ea2 |
The correct solution is to mark debuginfo files as new types of
|
|
Carlos O'Donell |
0e17ea2 |
ELF files.
|
|
Carlos O'Donell |
0e17ea2 |
|
|
Arjun Shankar |
81c303b |
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
|
Arjun Shankar |
81c303b |
index 24e2819345995bd9..007121144e71d9cf 100644
|
|
Arjun Shankar |
81c303b |
--- a/elf/dl-load.c
|
|
Arjun Shankar |
81c303b |
+++ b/elf/dl-load.c
|
|
Arjun Shankar |
81c303b |
@@ -880,6 +880,18 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
|
Arjun Shankar |
81c303b |
in this information for the executable in case of an explicit
|
|
Arjun Shankar |
81c303b |
loader invocation. */
|
|
Siddhesh Poyarekar |
6223dbf |
struct r_file_id id;
|
|
Siddhesh Poyarekar |
6223dbf |
+ struct stat64 st;
|
|
Arjun Shankar |
81c303b |
+
|
|
Siddhesh Poyarekar |
6223dbf |
+ if (__glibc_unlikely (!_dl_get_file_id (fd, &id, &st)))
|
|
Arjun Shankar |
81c303b |
+ {
|
|
Arjun Shankar |
81c303b |
+ errstring = N_("cannot stat shared object");
|
|
Arjun Shankar |
81c303b |
+ call_lose_errno:
|
|
Arjun Shankar |
81c303b |
+ errval = errno;
|
|
Arjun Shankar |
81c303b |
+ call_lose:
|
|
Arjun Shankar |
81c303b |
+ lose (errval, fd, name, realname, l, errstring,
|
|
Arjun Shankar |
81c303b |
+ make_consistent ? r : NULL, nsid);
|
|
Arjun Shankar |
81c303b |
+ }
|
|
Arjun Shankar |
81c303b |
+
|
|
Arjun Shankar |
81c303b |
if (mode & __RTLD_OPENEXEC)
|
|
Arjun Shankar |
81c303b |
{
|
|
Arjun Shankar |
81c303b |
assert (nsid == LM_ID_BASE);
|
|
Arjun Shankar |
81c303b |
@@ -887,16 +899,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
|
Arjun Shankar |
81c303b |
}
|
|
Arjun Shankar |
81c303b |
else
|
|
Siddhesh Poyarekar |
6223dbf |
{
|
|
Arjun Shankar |
81c303b |
- if (__glibc_unlikely (!_dl_get_file_id (fd, &id)))
|
|
Arjun Shankar |
81c303b |
- {
|
|
Arjun Shankar |
81c303b |
- errstring = N_("cannot stat shared object");
|
|
Arjun Shankar |
81c303b |
- call_lose_errno:
|
|
Arjun Shankar |
81c303b |
- errval = errno;
|
|
Arjun Shankar |
81c303b |
- call_lose:
|
|
Arjun Shankar |
81c303b |
- lose (errval, fd, name, realname, l, errstring,
|
|
Arjun Shankar |
81c303b |
- make_consistent ? r : NULL, nsid);
|
|
Arjun Shankar |
81c303b |
- }
|
|
Arjun Shankar |
81c303b |
-
|
|
Arjun Shankar |
81c303b |
/* Look again to see if the real name matched another already loaded. */
|
|
Arjun Shankar |
81c303b |
for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
|
|
Arjun Shankar |
81c303b |
if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id))
|
|
Arjun Shankar |
81c303b |
@@ -1074,6 +1076,16 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
|
|
92f446a |
= N_("ELF load command address/offset not properly aligned");
|
|
|
92f446a |
goto call_lose;
|
|
|
92f446a |
}
|
|
Siddhesh Poyarekar |
c899b49 |
+ if (__glibc_unlikely (ph->p_offset + ph->p_filesz > st.st_size))
|
|
|
92f446a |
+ {
|
|
|
92f446a |
+ /* If the segment requires zeroing of part of its last
|
|
|
92f446a |
+ page, we'll crash when accessing the unmapped page.
|
|
|
92f446a |
+ There's still a possibility of a race, if the shared
|
|
|
92f446a |
+ object is truncated between the fxstat above and the
|
|
|
92f446a |
+ memset below. */
|
|
|
92f446a |
+ errstring = N_("ELF load command past end of file");
|
|
|
92f446a |
+ goto call_lose;
|
|
|
92f446a |
+ }
|
|
|
92f446a |
|
|
Siddhesh Poyarekar |
c899b49 |
struct loadcmd *c = &loadcmds[nloadcmds++];
|
|
Carlos O'Donell |
e61b8f4 |
c->mapstart = ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize));
|
|
Arjun Shankar |
81c303b |
diff --git a/sysdeps/generic/dl-fileid.h b/sysdeps/generic/dl-fileid.h
|
|
Arjun Shankar |
81c303b |
index 6310d46c2a6efc60..209580b6c0b8524b 100644
|
|
Arjun Shankar |
81c303b |
--- a/sysdeps/generic/dl-fileid.h
|
|
Arjun Shankar |
81c303b |
+++ b/sysdeps/generic/dl-fileid.h
|
|
Siddhesh Poyarekar |
6223dbf |
@@ -29,7 +29,8 @@ struct r_file_id
|
|
Siddhesh Poyarekar |
6223dbf |
On error, returns false, with errno set. */
|
|
Siddhesh Poyarekar |
6223dbf |
static inline bool
|
|
Siddhesh Poyarekar |
6223dbf |
_dl_get_file_id (int fd __attribute__ ((unused)),
|
|
Siddhesh Poyarekar |
6223dbf |
- struct r_file_id *id __attribute__ ((unused)))
|
|
Siddhesh Poyarekar |
6223dbf |
+ struct r_file_id *id __attribute__ ((unused)),
|
|
Siddhesh Poyarekar |
6223dbf |
+ struct stat64_t *st __attribute__((unused)))
|
|
Siddhesh Poyarekar |
6223dbf |
{
|
|
Siddhesh Poyarekar |
6223dbf |
return true;
|
|
Siddhesh Poyarekar |
6223dbf |
}
|
|
Arjun Shankar |
81c303b |
diff --git a/sysdeps/posix/dl-fileid.h b/sysdeps/posix/dl-fileid.h
|
|
Arjun Shankar |
81c303b |
index ae88a350788a5999..baa17b90a292a4d9 100644
|
|
Arjun Shankar |
81c303b |
--- a/sysdeps/posix/dl-fileid.h
|
|
Arjun Shankar |
81c303b |
+++ b/sysdeps/posix/dl-fileid.h
|
|
Siddhesh Poyarekar |
6223dbf |
@@ -27,18 +27,16 @@ struct r_file_id
|
|
Siddhesh Poyarekar |
6223dbf |
ino64_t ino;
|
|
Siddhesh Poyarekar |
6223dbf |
};
|
|
Siddhesh Poyarekar |
6223dbf |
|
|
Siddhesh Poyarekar |
6223dbf |
-/* Sample FD to fill in *ID. Returns true on success.
|
|
Siddhesh Poyarekar |
6223dbf |
+/* Sample FD to fill in *ID and *ST. Returns true on success.
|
|
Siddhesh Poyarekar |
6223dbf |
On error, returns false, with errno set. */
|
|
Siddhesh Poyarekar |
6223dbf |
static inline bool
|
|
Siddhesh Poyarekar |
6223dbf |
-_dl_get_file_id (int fd, struct r_file_id *id)
|
|
Siddhesh Poyarekar |
6223dbf |
+_dl_get_file_id (int fd, struct r_file_id *id, struct stat64 *st)
|
|
Siddhesh Poyarekar |
6223dbf |
{
|
|
Siddhesh Poyarekar |
6223dbf |
- struct stat64 st;
|
|
Siddhesh Poyarekar |
6223dbf |
-
|
|
Siddhesh Poyarekar |
6223dbf |
- if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, &st) < 0))
|
|
Siddhesh Poyarekar |
6223dbf |
+ if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, st) < 0))
|
|
Siddhesh Poyarekar |
6223dbf |
return false;
|
|
Siddhesh Poyarekar |
6223dbf |
|
|
Siddhesh Poyarekar |
6223dbf |
- id->dev = st.st_dev;
|
|
Siddhesh Poyarekar |
6223dbf |
- id->ino = st.st_ino;
|
|
Siddhesh Poyarekar |
6223dbf |
+ id->dev = st->st_dev;
|
|
Siddhesh Poyarekar |
6223dbf |
+ id->ino = st->st_ino;
|
|
Siddhesh Poyarekar |
6223dbf |
return true;
|
|
Siddhesh Poyarekar |
6223dbf |
}
|
|
Siddhesh Poyarekar |
6223dbf |
|