summaryrefslogtreecommitdiff
path: root/libelf
diff options
context:
space:
mode:
Diffstat (limited to 'libelf')
-rw-r--r--libelf/_libelf.h6
-rw-r--r--libelf/_libelf_config.h8
-rw-r--r--libelf/elf.354
-rw-r--r--libelf/elf_data.c18
-rw-r--r--libelf/elf_end.c6
-rw-r--r--libelf/elf_flagdata.314
-rw-r--r--libelf/elf_getdata.311
-rw-r--r--libelf/elf_getident.c4
-rw-r--r--libelf/elf_next.37
-rw-r--r--libelf/elf_next.c16
-rw-r--r--libelf/elf_open.312
-rw-r--r--libelf/elf_rand.c13
-rw-r--r--libelf/elf_rawfile.c6
-rw-r--r--libelf/elf_scn.c7
-rw-r--r--libelf/elf_update.38
-rw-r--r--libelf/elf_update.c46
-rw-r--r--libelf/gelf.311
-rw-r--r--libelf/gelf_cap.c11
-rw-r--r--libelf/gelf_dyn.c10
-rw-r--r--libelf/gelf_getcap.310
-rw-r--r--libelf/gelf_getdyn.311
-rw-r--r--libelf/gelf_getmove.310
-rw-r--r--libelf/gelf_getrel.310
-rw-r--r--libelf/gelf_getrela.310
-rw-r--r--libelf/gelf_getsym.310
-rw-r--r--libelf/gelf_getsyminfo.310
-rw-r--r--libelf/gelf_getsymshndx.312
-rw-r--r--libelf/gelf_move.c10
-rw-r--r--libelf/gelf_newehdr.38
-rw-r--r--libelf/gelf_newphdr.38
-rw-r--r--libelf/gelf_rel.c12
-rw-r--r--libelf/gelf_rela.c12
-rw-r--r--libelf/gelf_sym.c10
-rw-r--r--libelf/gelf_syminfo.c10
-rw-r--r--libelf/gelf_symshndx.c10
-rw-r--r--libelf/libelf_allocate.c35
-rw-r--r--libelf/libelf_ar.c43
-rw-r--r--libelf/libelf_convert.m413
-rw-r--r--libelf/libelf_data.c10
-rw-r--r--libelf/libelf_ehdr.c16
-rw-r--r--libelf/libelf_extended.c12
-rw-r--r--libelf/libelf_memory.c6
-rw-r--r--libelf/libelf_msize.m415
-rw-r--r--libelf/libelf_phdr.c17
-rw-r--r--libelf/libelf_xlate.c7
-rw-r--r--libelf/os.Linux.mk31
46 files changed, 421 insertions, 215 deletions
diff --git a/libelf/_libelf.h b/libelf/_libelf.h
index 26f17276b170..f826d1c360a5 100644
--- a/libelf/_libelf.h
+++ b/libelf/_libelf.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: _libelf.h 3632 2018-10-10 21:12:43Z jkoshy $
+ * $Id: _libelf.h 3738 2019-05-05 21:49:06Z jkoshy $
*/
#ifndef __LIBELF_H_
@@ -90,7 +90,7 @@ struct _Elf {
Elf_Kind e_kind; /* ELF_K_* */
Elf *e_parent; /* non-NULL for archive members */
unsigned char *e_rawfile; /* uninterpreted bytes */
- size_t e_rawsize; /* size of uninterpreted bytes */
+ off_t e_rawsize; /* size of uninterpreted bytes */
unsigned int e_version; /* file version */
/*
@@ -226,7 +226,7 @@ size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version);
void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count);
Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror);
struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d);
-Elf *_libelf_release_elf(Elf *_e);
+void _libelf_release_elf(Elf *_e);
Elf_Scn *_libelf_release_scn(Elf_Scn *_s);
int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum);
int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum);
diff --git a/libelf/_libelf_config.h b/libelf/_libelf_config.h
index d70c04f97098..f28dc8ddf24e 100644
--- a/libelf/_libelf_config.h
+++ b/libelf/_libelf_config.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: _libelf_config.h 3566 2017-08-31 02:28:40Z emaste $
+ * $Id: _libelf_config.h 3764 2019-06-28 21:44:46Z emaste $
*/
#if defined(__APPLE__) || defined(__DragonFly__)
@@ -103,6 +103,12 @@
#define LIBELF_BYTEORDER ELFDATA2LSB
#define LIBELF_CLASS ELFCLASS64
+#elif defined(__riscv64)
+
+#define LIBELF_ARCH EM_RISCV
+#define LIBELF_BYTEORDER ELFDATA2LSB
+#define LIBELF_CLASS ELFCLASS64
+
#elif defined(__sparc__)
#define LIBELF_ARCH EM_SPARCV9
diff --git a/libelf/elf.3 b/libelf/elf.3
index 269725a09ac8..7e1d3cb9a5ed 100644
--- a/libelf/elf.3
+++ b/libelf/elf.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2006-2008,2011 Joseph Koshy. All rights reserved.
+.\" Copyright (c) 2006-2008,2011,2019 Joseph Koshy. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elf.3 3643 2018-10-14 21:09:24Z jkoshy $
+.\" $Id: elf.3 3743 2019-06-12 19:36:30Z jkoshy $
.\"
-.Dd October 10, 2018
+.Dd June 12, 2019
.Dt ELF 3
.Os
.Sh NAME
@@ -266,36 +266,43 @@ The operating version for the data in this buffer.
.El
.Pp
.Vt Elf_Data
-descriptors are usually associated with
+descriptors are usually used in conjunction with
.Vt Elf_Scn
descriptors.
-Existing data descriptors associated with an ELF section may be
-structures are retrieved using the
-.Fn elf_getdata
-and
-.Fn elf_rawdata
-functions.
-The
-.Fn elf_newdata
-function may be used to attach new data descriptors to an ELF section.
.It Vt Elf_Scn
.Vt Elf_Scn
-descriptors represent a section in an ELF object.
+descriptors represent sections in an ELF object.
+These descriptors are opaque and contain no application modifiable
+fields.
.Pp
-They are retrieved using the
+The
+.Vt Elf_Scn
+descriptor for a specific section in an ELF object can be
+retrieved using the
.Fn elf_getscn
function.
-An application may iterate through the existing sections of an ELF
-object using the
+The sections contained in an ELF object can be traversed using the
.Fn elf_nextscn
function.
-New sections may be allocated using the
+New sections are allocated using the
.Fn elf_newscn
function.
.Pp
The
-.Vt Elf_Scn
-descriptor is opaque and contains no application modifiable fields.
+.Vt Elf_Data
+descriptors associated with a given section can be retrieved
+using the
+.Fn elf_getdata
+function.
+New data descriptors can be added to a section
+descriptor using the
+.Fn elf_newdata
+function.
+The untranslated
+.Dq file
+representation of data in a section can be retrieved using the
+.Fn elf_rawdata
+function.
.El
.Ss Supported Elf Types
The following ELF datatypes are supported by the library.
@@ -608,8 +615,11 @@ descriptor itself.
.Xr ar 5 ,
.Xr elf 5
.Sh HISTORY
-The original ELF(3) API was developed for Unix System V.
-The current implementation of the ELF(3) API appeared in
+The original
+.Nm
+API was developed for
+.At V .
+The current implementation of the API appeared in
.Fx 7.0 .
.Sh AUTHORS
The ELF library was written by
diff --git a/libelf/elf_data.c b/libelf/elf_data.c
index bab70d003cee..6c6acb1441b0 100644
--- a/libelf/elf_data.c
+++ b/libelf/elf_data.c
@@ -32,7 +32,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_data.c 3632 2018-10-10 21:12:43Z jkoshy $");
+ELFTC_VCSID("$Id: elf_data.c 3732 2019-04-22 11:08:38Z jkoshy $");
Elf_Data *
elf_getdata(Elf_Scn *s, Elf_Data *ed)
@@ -42,7 +42,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
int elfclass, elftype;
size_t count, fsz, msz;
struct _Libelf_Data *d;
- uint64_t sh_align, sh_offset, sh_size;
+ uint64_t sh_align, sh_offset, sh_size, raw_size;
_libelf_translator_function *xlate;
d = (struct _Libelf_Data *) ed;
@@ -59,7 +59,8 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
return (&d->d_data);
if (d != NULL)
- return (&STAILQ_NEXT(d, d_next)->d_data);
+ return (STAILQ_NEXT(d, d_next) ?
+ &STAILQ_NEXT(d, d_next)->d_data : NULL);
if (e->e_rawfile == NULL) {
/*
@@ -91,9 +92,10 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
return (NULL);
}
+ raw_size = (uint64_t) e->e_rawsize;
if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
- (sh_offset > e->e_rawsize || sh_size > e->e_rawsize - sh_offset))) {
+ (sh_offset > raw_size || sh_size > raw_size - sh_offset))) {
LIBELF_SET_ERROR(SECTION, 0);
return (NULL);
}
@@ -116,7 +118,8 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
count = (size_t) (sh_size / fsz);
- msz = _libelf_msize(elftype, elfclass, e->e_version);
+ if ((msz = _libelf_msize(elftype, elfclass, e->e_version)) == 0)
+ return (NULL);
if (count > 0 && msz > SIZE_MAX / count) {
LIBELF_SET_ERROR(RANGE, 0);
@@ -215,7 +218,7 @@ elf_rawdata(Elf_Scn *s, Elf_Data *ed)
int elf_class;
uint32_t sh_type;
struct _Libelf_Data *d;
- uint64_t sh_align, sh_offset, sh_size;
+ uint64_t sh_align, sh_offset, sh_size, raw_size;
if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) {
LIBELF_SET_ERROR(ARGUMENT, 0);
@@ -253,8 +256,9 @@ elf_rawdata(Elf_Scn *s, Elf_Data *ed)
return (NULL);
}
+ raw_size = (uint64_t) e->e_rawsize;
if (sh_type != SHT_NOBITS &&
- (sh_offset > e->e_rawsize || sh_size > e->e_rawsize - sh_offset)) {
+ (sh_offset > raw_size || sh_size > raw_size - sh_offset)) {
LIBELF_SET_ERROR(SECTION, 0);
return (NULL);
}
diff --git a/libelf/elf_end.c b/libelf/elf_end.c
index 3f32ebbee8ec..ed0c3ef845a9 100644
--- a/libelf/elf_end.c
+++ b/libelf/elf_end.c
@@ -34,7 +34,7 @@
#include <sys/mman.h>
#endif
-ELFTC_VCSID("$Id: elf_end.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: elf_end.c 3738 2019-05-05 21:49:06Z jkoshy $");
int
elf_end(Elf *e)
@@ -81,14 +81,14 @@ elf_end(Elf *e)
free(e->e_rawfile);
#if ELFTC_HAVE_MMAP
else if (e->e_flags & LIBELF_F_RAWFILE_MMAP)
- (void) munmap(e->e_rawfile, e->e_rawsize);
+ (void) munmap(e->e_rawfile, (size_t) e->e_rawsize);
#endif
}
sv = e;
if ((e = e->e_parent) != NULL)
e->e_u.e_ar.e_nchildren--;
- sv = _libelf_release_elf(sv);
+ _libelf_release_elf(sv);
}
return (0);
diff --git a/libelf/elf_flagdata.3 b/libelf/elf_flagdata.3
index c210e4a56971..997da1e570be 100644
--- a/libelf/elf_flagdata.3
+++ b/libelf/elf_flagdata.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elf_flagdata.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: elf_flagdata.3 3743 2019-06-12 19:36:30Z jkoshy $
.\"
-.Dd December 3, 2011
+.Dd June 12, 2019
.Dt ELF_FLAGDATA 3
.Os
.Sh NAME
@@ -34,7 +34,7 @@
.Nm elf_flagphdr ,
.Nm elf_flagscn ,
.Nm elf_flagshdr
-.Nd manipulate flags associated with ELF(3) data structures
+.Nd manipulate flags associated with ELF data structures
.Sh LIBRARY
.Lb libelf
.Sh SYNOPSIS
@@ -65,7 +65,9 @@ and
.Ar scn
denote the data structures whose flags need to be changed.
These values should have been returned by prior calls to
-functions in the ELF(3) API set:
+functions in the
+.Xr elf 3
+API set:
.Bl -bullet -compact
.It
Argument
@@ -175,7 +177,9 @@ function and the
.Dv ELF_F_ARCHIVE
and
.Dv ELF_F_ARCHIVE_SYSV
-flags are an extension to the ELF(3) API.
+flags are an extension to the
+.Xr elf 3
+API.
.Sh ERRORS
These functions may fail with the following errors:
.Bl -tag -width "[ELF_E_RESOURCE]"
diff --git a/libelf/elf_getdata.3 b/libelf/elf_getdata.3
index b287a25a00bc..66a6ef4fa9dd 100644
--- a/libelf/elf_getdata.3
+++ b/libelf/elf_getdata.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elf_getdata.3 3643 2018-10-14 21:09:24Z jkoshy $
+.\" $Id: elf_getdata.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd January 26, 2011
+.Dd April 22, 2019
.Dt ELF_GETDATA 3
.Os
.Sh NAME
@@ -214,7 +214,12 @@ is incorrect.
.It Bq Er ELF_E_UNIMPL
The section type associated with section
.Ar scn
-is currently unsupported by the library.
+is not supported.
+.It Bq Er ELF_E_VERSION
+Section
+.Ar scn
+was associated with an ELF object with an unsupported
+version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/elf_getident.c b/libelf/elf_getident.c
index a69139c932cf..1196a76329f6 100644
--- a/libelf/elf_getident.c
+++ b/libelf/elf_getident.c
@@ -30,7 +30,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_getident.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: elf_getident.c 3712 2019-03-16 22:23:34Z jkoshy $");
char *
elf_getident(Elf *e, size_t *sz)
@@ -54,7 +54,7 @@ elf_getident(Elf *e, size_t *sz)
else if (e->e_kind == ELF_K_ELF)
*sz = EI_NIDENT;
else
- *sz = e->e_rawsize;
+ *sz = (size_t) e->e_rawsize;
}
return ((char *) e->e_rawfile);
diff --git a/libelf/elf_next.3 b/libelf/elf_next.3
index 0c2d92d67e2d..1ef02a9851b9 100644
--- a/libelf/elf_next.3
+++ b/libelf/elf_next.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elf_next.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: elf_next.3 3698 2019-02-28 06:34:42Z jkoshy $
.\"
-.Dd June 17, 2006
+.Dd February 27, 2019
.Dt ELF_NEXT 3
.Os
.Sh NAME
@@ -88,6 +88,9 @@ Argument
was not associated with a containing
.Xr ar 1
archive.
+.It Bq Er ELF_E_ARGUMENT
+An error was encountered while parsing the archive containing argument
+.Ar elf .
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/elf_next.c b/libelf/elf_next.c
index 4c33714f291a..dd5a93e4ed1d 100644
--- a/libelf/elf_next.c
+++ b/libelf/elf_next.c
@@ -30,7 +30,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_next.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: elf_next.c 3710 2019-03-12 09:42:35Z jkoshy $");
Elf_Cmd
elf_next(Elf *e)
@@ -60,5 +60,19 @@ elf_next(Elf *e)
parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ?
(off_t) 0 : next;
+ /*
+ * Return an error if the 'e_next' field falls outside the current
+ * file.
+ *
+ * This check is performed after updating the parent descriptor's
+ * 'e_next' field so that the next call to elf_begin(3) will terminate
+ * traversal of a too-small archive even if client code forgets to
+ * check the return value from elf_next(3).
+ */
+ if (next > (off_t) parent->e_rawsize) {
+ LIBELF_SET_ERROR(ARGUMENT, 0);
+ return (ELF_C_NULL);
+ }
+
return (ELF_C_READ);
}
diff --git a/libelf/elf_open.3 b/libelf/elf_open.3
index acfbe8bc1cfd..054036a24935 100644
--- a/libelf/elf_open.3
+++ b/libelf/elf_open.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elf_open.3 3643 2018-10-14 21:09:24Z jkoshy $
+.\" $Id: elf_open.3 3743 2019-06-12 19:36:30Z jkoshy $
.\"
-.Dd May 31, 2012
+.Dd June 12, 2019
.Dt ELF_OPEN 3
.Os
.Sh NAME
@@ -43,7 +43,9 @@ The functions
.Fn elf_open
and
.Fn elf_openmemory
-are extensions to the ELF(3) API, for the internal use of the
+are extensions to the
+.Xr elf 3
+API, for the internal use of the
Elftoolchain project.
Portable applications should not use these functions.
.Pp
@@ -71,7 +73,9 @@ specifies the size of the memory area in bytes.
The function returns a pointer to a ELF descriptor if successful, or
NULL if an error occurred.
.Sh COMPATIBILITY
-These functions are non-standard extensions to the ELF(3) API set.
+These functions are non-standard extensions to the
+.Xr elf 3
+API set.
.Pp
The behavior of these functions differs from their counterparts
.Xr elf_begin 3
diff --git a/libelf/elf_rand.c b/libelf/elf_rand.c
index eb2c9eaa2c1a..ac3bd0bc60e0 100644
--- a/libelf/elf_rand.c
+++ b/libelf/elf_rand.c
@@ -29,16 +29,25 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_rand.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: elf_rand.c 3716 2019-03-18 22:01:01Z jkoshy $");
off_t
elf_rand(Elf *ar, off_t offset)
{
struct ar_hdr *arh;
+ off_t offset_of_member;
if (ar == NULL || ar->e_kind != ELF_K_AR ||
(offset & 1) || offset < SARMAG ||
- (size_t) offset + sizeof(struct ar_hdr) >= ar->e_rawsize) {
+ offset >= ar->e_rawsize) {
+ LIBELF_SET_ERROR(ARGUMENT, 0);
+ return 0;
+ }
+
+ offset_of_member = offset + (off_t) sizeof(struct ar_hdr);
+
+ if (offset_of_member <= 0 || /* Numeric overflow. */
+ offset_of_member >= ar->e_rawsize) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return 0;
}
diff --git a/libelf/elf_rawfile.c b/libelf/elf_rawfile.c
index f63982fb0b4b..97abf06a2267 100644
--- a/libelf/elf_rawfile.c
+++ b/libelf/elf_rawfile.c
@@ -28,15 +28,13 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_rawfile.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: elf_rawfile.c 3712 2019-03-16 22:23:34Z jkoshy $");
char *
elf_rawfile(Elf *e, size_t *sz)
{
- size_t size;
unsigned char *ptr;
- size = e ? e->e_rawsize : 0;
ptr = NULL;
if (e == NULL)
@@ -45,7 +43,7 @@ elf_rawfile(Elf *e, size_t *sz)
LIBELF_SET_ERROR(SEQUENCE, 0);
if (sz)
- *sz = size;
+ *sz = e ? (size_t) e->e_rawsize : 0;
return ((char *) ptr);
}
diff --git a/libelf/elf_scn.c b/libelf/elf_scn.c
index b72fef66c46b..f702474f35b2 100644
--- a/libelf/elf_scn.c
+++ b/libelf/elf_scn.c
@@ -36,7 +36,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_scn.c 3632 2018-10-10 21:12:43Z jkoshy $");
+ELFTC_VCSID("$Id: elf_scn.c 3712 2019-03-16 22:23:34Z jkoshy $");
/*
* Load an ELF section table and create a list of Elf_Scn structures.
@@ -58,10 +58,11 @@ _libelf_load_section_headers(Elf *e, void *ehdr)
assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0);
#define CHECK_EHDR(E,EH) do { \
- if (shoff > e->e_rawsize || \
+ uintmax_t rawsize = (uintmax_t) e->e_rawsize; \
+ if (shoff > (uintmax_t) e->e_rawsize || \
fsz != (EH)->e_shentsize || \
shnum > SIZE_MAX / fsz || \
- fsz * shnum > e->e_rawsize - shoff) { \
+ fsz * shnum > rawsize - shoff) { \
LIBELF_SET_ERROR(HEADER, 0); \
return (0); \
} \
diff --git a/libelf/elf_update.3 b/libelf/elf_update.3
index b6419cf9bf53..b87ab1640d1f 100644
--- a/libelf/elf_update.3
+++ b/libelf/elf_update.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elf_update.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: elf_update.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 14, 2011
+.Dd April 22, 2019
.Dt ELF_UPDATE 3
.Os
.Sh NAME
@@ -345,6 +345,10 @@ operation was requested after a prior call to
disassociated the ELF descriptor
.Ar elf
from its underlying file.
+.It Bq Er ELF_E_UNIMPL
+Argument
+.Ar elf
+contained a section with an unsupported ELF type.
.It Bq Er ELF_E_VERSION
Argument
.Ar elf
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 25fa98d0bb12..d99a7bf937c6 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -41,7 +41,7 @@
#include <sys/mman.h>
#endif
-ELFTC_VCSID("$Id: elf_update.c 3632 2018-10-10 21:12:43Z jkoshy $");
+ELFTC_VCSID("$Id: elf_update.c 3763 2019-06-28 21:43:27Z emaste $");
/*
* Layout strategy:
@@ -142,7 +142,7 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS);
elftype = _libelf_xlate_shtype(sh_type);
- if (elftype > ELF_T_LAST) {
+ if (elftype < ELF_T_FIRST || elftype > ELF_T_LAST) {
LIBELF_SET_ERROR(SECTION, 0);
return (0);
}
@@ -222,10 +222,16 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
}
/*
+ * The data buffer's ELF type, ELF class and ELF version
+ * should be supported.
+ */
+ if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 0)
+ return (0);
+
+ /*
* The buffer's size should be a multiple of the
* memory size of the underlying type.
*/
- msz = _libelf_msize(d->d_type, ec, e->e_version);
if (d->d_size % msz) {
LIBELF_SET_ERROR(DATA, 0);
return (0);
@@ -800,7 +806,8 @@ _libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
d = &ld->d_data;
- msz = _libelf_msize(d->d_type, ec, e->e_version);
+ if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 0)
+ return ((off_t) -1);
if ((uint64_t) rc < sh_off + d->d_off)
(void) memset(nf + rc,
@@ -812,6 +819,7 @@ _libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
assert(d->d_buf != NULL);
assert(d->d_version == e->e_version);
assert(d->d_size % msz == 0);
+ assert(msz != 0);
nobjects = (size_t) (d->d_size / msz);
@@ -851,7 +859,8 @@ _libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
assert(ehdr != NULL);
fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
- msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version)) == 0)
+ return ((off_t) -1);
em = _libelf_elfmachine(e);
@@ -885,15 +894,17 @@ _libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
Elf_Data dst, src;
- size_t fsz, phnum;
+ size_t fsz, msz, phnum;
uint64_t phoff;
assert(ex->ex_type == ELF_EXTENT_PHDR);
ec = e->e_class;
+
ehdr = _libelf_ehdr(e, ec, 0);
- phnum = e->e_u.e_elf.e_nphdr;
+ assert(ehdr != NULL);
+ phnum = e->e_u.e_elf.e_nphdr;
assert(phnum > 0);
if (ec == ELFCLASS32) {
@@ -913,14 +924,15 @@ _libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
(void) memset(&dst, 0, sizeof(dst));
(void) memset(&src, 0, sizeof(src));
+ if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0)
+ return ((off_t) -1);
fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum);
assert(fsz > 0);
src.d_buf = _libelf_getphdr(e, ec);
src.d_version = dst.d_version = e->e_version;
src.d_type = ELF_T_PHDR;
- src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec,
- e->e_version);
+ src.d_size = phnum * msz;
dst.d_size = fsz;
dst.d_buf = nf + ex->ex_start;
@@ -945,13 +957,16 @@ _libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
uint64_t shoff;
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
- size_t fsz, nscn;
+ size_t fsz, msz, nscn;
Elf_Data dst, src;
assert(ex->ex_type == ELF_EXTENT_SHDR);
ec = e->e_class;
+
ehdr = _libelf_ehdr(e, ec, 0);
+ assert(ehdr != NULL);
+
nscn = e->e_u.e_elf.e_nscn;
if (ec == ELFCLASS32) {
@@ -971,8 +986,11 @@ _libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
(void) memset(&dst, 0, sizeof(dst));
(void) memset(&src, 0, sizeof(src));
+ if ((msz = _libelf_msize(ELF_T_SHDR, ec, e->e_version)) == 0)
+ return ((off_t) -1);
+
src.d_type = ELF_T_SHDR;
- src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version);
+ src.d_size = msz;
src.d_version = dst.d_version = e->e_version;
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1);
@@ -1084,7 +1102,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
assert(e->e_rawfile != NULL);
assert(e->e_cmd == ELF_C_RDWR);
- if (munmap(e->e_rawfile, e->e_rawsize) < 0) {
+ if (munmap(e->e_rawfile, (size_t) e->e_rawsize) < 0) {
LIBELF_SET_ERROR(IO, errno);
goto error;
}
@@ -1109,12 +1127,14 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) ||
(e->e_flags & LIBELF_F_RAWFILE_MMAP));
if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) {
+ assert((e->e_flags & LIBELF_F_RAWFILE_MMAP) == 0);
free(e->e_rawfile);
e->e_rawfile = newfile;
newfile = NULL;
}
#if ELFTC_HAVE_MMAP
else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
+ assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) == 0);
if ((e->e_rawfile = mmap(NULL, (size_t) newsize,
PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) ==
MAP_FAILED) {
@@ -1125,7 +1145,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
#endif /* ELFTC_HAVE_MMAP */
/* Record the new size of the file. */
- e->e_rawsize = (size_t) newsize;
+ e->e_rawsize = newsize;
} else {
/* File opened in ELF_C_WRITE mode. */
assert(e->e_rawfile == NULL);
diff --git a/libelf/gelf.3 b/libelf/gelf.3
index 704ae154700f..d703c1b3f65e 100644
--- a/libelf/gelf.3
+++ b/libelf/gelf.3
@@ -21,13 +21,13 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf.3 3643 2018-10-14 21:09:24Z jkoshy $
+.\" $Id: gelf.3 3743 2019-06-12 19:36:30Z jkoshy $
.\"
-.Dd September 1, 2006
+.Dd June 12, 2019
.Dt GELF 3
.Os
.Sh NAME
-.Nm GElf
+.Nm gelf
.Nd class-independent API for ELF manipulation
.Sh LIBRARY
.Lb libelf
@@ -192,7 +192,10 @@ Copy back an ELF symbol table entry.
.Xr elf 3 ,
.Xr elf 5
.Sh HISTORY
-The GELF(3) API first appeared in System V Release 4.
+The
+.Nm
+API first appeared in
+.At V.4 .
This implementation of the API first appeared in
.Fx 7.0 .
.Sh AUTHORS
diff --git a/libelf/gelf_cap.c b/libelf/gelf_cap.c
index f509c69c2ba5..6ebdd97a0c52 100644
--- a/libelf/gelf_cap.c
+++ b/libelf/gelf_cap.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_cap.c 3177 2015-03-30 18:19:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_cap.c 3732 2019-04-22 11:08:38Z jkoshy $");
GElf_Cap *
gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
@@ -67,9 +67,8 @@ gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
return (NULL);
}
- msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
-
- assert(msz > 0);
+ if ((msz = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0)
+ return (NULL);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
@@ -127,8 +126,8 @@ gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc)
return (0);
}
- msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
- assert(msz > 0);
+ if ((msz = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0)
+ return (0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
diff --git a/libelf/gelf_dyn.c b/libelf/gelf_dyn.c
index 74233094bf6c..1c8b133ceada 100644
--- a/libelf/gelf_dyn.c
+++ b/libelf/gelf_dyn.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_dyn.c 3177 2015-03-30 18:19:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_dyn.c 3732 2019-04-22 11:08:38Z jkoshy $");
GElf_Dyn *
gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst)
@@ -67,9 +67,9 @@ gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst)
return (NULL);
}
- msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0)
+ return (NULL);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -127,9 +127,9 @@ gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds)
return (0);
}
- msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0)
+ return (0);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
diff --git a/libelf/gelf_getcap.3 b/libelf/gelf_getcap.3
index 276933a8365a..d1c1c2c76c1d 100644
--- a/libelf/gelf_getcap.3
+++ b/libelf/gelf_getcap.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getcap.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getcap.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 29, 2006
+.Dd April 22, 2019
.Dt GELF_GETCAP 3
.Os
.Sh NAME
@@ -113,6 +113,12 @@ was not associated with a section of type
.Dv SHT_SUNW_cap .
.It Bq Er ELF_E_RANGE
A value was not representable in the target type.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptor denoted by argument
+.Ar data
+is associated with an ELF object with an unsupported version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_getdyn.3 b/libelf/gelf_getdyn.3
index a4e51ecd0ee2..1db1a5a5e918 100644
--- a/libelf/gelf_getdyn.3
+++ b/libelf/gelf_getdyn.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getdyn.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getdyn.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 29, 2006
+.Dd April 22, 2019
.Dt GELF_GETDYN 3
.Os
.Sh NAME
@@ -115,6 +115,13 @@ was not associated with a section of type
.Dv SHT_DYNAMIC .
.It Bq Er ELF_E_RANGE
A value was not representable in the target type.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptor denoted by argument
+.Ar data
+is associated with an ELF object with an unsupported version.
+.El
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_getmove.3 b/libelf/gelf_getmove.3
index 64c52d9682ed..7f10d2c0d1ca 100644
--- a/libelf/gelf_getmove.3
+++ b/libelf/gelf_getmove.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getmove.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getmove.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 29, 2006
+.Dd April 22, 2019
.Dt GELF_GETMOVE 3
.Os
.Sh NAME
@@ -112,6 +112,12 @@ Data descriptor
was not associated with a section containing move information.
.It Bq Er ELF_E_RANGE
A value was not representable in the target type.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptor denoted by argument
+.Ar data
+is associated with an ELF object with an unsupported version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_getrel.3 b/libelf/gelf_getrel.3
index c21be0da8b46..056bf1a67fcc 100644
--- a/libelf/gelf_getrel.3
+++ b/libelf/gelf_getrel.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getrel.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getrel.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 29, 2006
+.Dd April 22, 2019
.Dt GELF_GETREL 3
.Os
.Sh NAME
@@ -113,6 +113,12 @@ was not associated with a section of type
.Dv SHT_REL .
.It Bq Er ELF_E_RANGE
A value was not representable in the target type.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptor denoted by argument
+.Ar data
+is associated with an ELF object with an unsupported version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_getrela.3 b/libelf/gelf_getrela.3
index 946482e605ef..0eb0ab31ce10 100644
--- a/libelf/gelf_getrela.3
+++ b/libelf/gelf_getrela.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getrela.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getrela.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 29, 2006
+.Dd April 22, 2019
.Dt GELF_GETRELA 3
.Os
.Sh NAME
@@ -113,6 +113,12 @@ was not associated with a section of type
.Dv SHT_RELA .
.It Bq Er ELF_E_RANGE
A value was not representable in the target type.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptor denoted by argument
+.Ar data
+is associated with an ELF object with an unsupported version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_getsym.3 b/libelf/gelf_getsym.3
index a139c152d15d..e2bbc9eb2f49 100644
--- a/libelf/gelf_getsym.3
+++ b/libelf/gelf_getsym.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getsym.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getsym.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 29, 2006
+.Dd April 22, 2019
.Dt GELF_GETSYM 3
.Os
.Sh NAME
@@ -115,6 +115,12 @@ Data descriptor
was not associated with a section containing symbol information.
.It Bq Er ELF_E_RANGE
A value was not representable in the target type.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptor denoted by argument
+.Ar data
+is associated with an ELF object with an unsupported version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_getsyminfo.3 b/libelf/gelf_getsyminfo.3
index 0f602c289795..71a69b87cff1 100644
--- a/libelf/gelf_getsyminfo.3
+++ b/libelf/gelf_getsyminfo.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getsyminfo.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getsyminfo.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd August 29, 2006
+.Dd April 22, 2019
.Dt GELF_GETSYMINFO 3
.Os
.Sh NAME
@@ -105,6 +105,12 @@ descriptor.
Data descriptor
.Ar data
was not associated with a section containing symbol information.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptor denoted by argument
+.Ar data
+is associated with an ELF object with an unsupported version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_getsymshndx.3 b/libelf/gelf_getsymshndx.3
index 595472a429e3..66b3efd3d89e 100644
--- a/libelf/gelf_getsymshndx.3
+++ b/libelf/gelf_getsymshndx.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_getsymshndx.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_getsymshndx.3 3734 2019-04-22 14:10:49Z jkoshy $
.\"
-.Dd November 5, 2006
+.Dd April 22, 2019
.Dt GELF_GETSYMSHNDX 3
.Os
.Sh NAME
@@ -152,6 +152,14 @@ Data descriptor
and
.Ar xndxdata
were associated with different ELF objects.
+.It Bq Er ELF_E_VERSION
+The
+.Vt Elf_Data
+descriptors denoted by arguments
+.Ar symdata
+and
+.Ar xndxdata
+are associated with an ELF object with an unsupported version.
.El
.Sh SEE ALSO
.Xr elf 3 ,
diff --git a/libelf/gelf_move.c b/libelf/gelf_move.c
index 2ec8f251f8fa..e5187bf05cf9 100644
--- a/libelf/gelf_move.c
+++ b/libelf/gelf_move.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_move.c 3177 2015-03-30 18:19:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_move.c 3732 2019-04-22 11:08:38Z jkoshy $");
GElf_Move *
gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst)
@@ -67,9 +67,9 @@ gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst)
return (NULL);
}
- msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0)
+ return (NULL);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -130,9 +130,9 @@ gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm)
return (0);
}
- msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0)
+ return (0);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
diff --git a/libelf/gelf_newehdr.3 b/libelf/gelf_newehdr.3
index 38698c32e8b0..5a15ea7d76c6 100644
--- a/libelf/gelf_newehdr.3
+++ b/libelf/gelf_newehdr.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_newehdr.3 3643 2018-10-14 21:09:24Z jkoshy $
+.\" $Id: gelf_newehdr.3 3743 2019-06-12 19:36:30Z jkoshy $
.\"
-.Dd October 22, 2007
+.Dd June 12, 2019
.Dt GELF_NEWEHDR 3
.Os
.Sh NAME
@@ -134,7 +134,9 @@ The
function uses a type of
.Ft "void *"
for its returned value.
-This differs from some other implementations of the ELF(3) API, which use an
+This differs from some other implementations of the
+.Xr elf 3
+API, which use an
.Ft "unsigned long"
return type.
.Sh ERRORS
diff --git a/libelf/gelf_newphdr.3 b/libelf/gelf_newphdr.3
index a881aab4dd6e..01d6cbc38118 100644
--- a/libelf/gelf_newphdr.3
+++ b/libelf/gelf_newphdr.3
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: gelf_newphdr.3 3639 2018-10-14 14:07:02Z jkoshy $
+.\" $Id: gelf_newphdr.3 3743 2019-06-12 19:36:30Z jkoshy $
.\"
-.Dd October 22, 2007
+.Dd June 12, 2019
.Dt GELF_NEWPHDR 3
.Os
.Sh NAME
@@ -103,7 +103,9 @@ The
function uses a type of
.Ft "void *"
for its returned value.
-This differs from some other implementations of the ELF(3) API, which use an
+This differs from some other implementations of the
+.Xr elf 3
+API, which use an
.Ft "unsigned long"
return type.
.Sh ERRORS
diff --git a/libelf/gelf_rel.c b/libelf/gelf_rel.c
index 02a613383dfb..54a1002c8679 100644
--- a/libelf/gelf_rel.c
+++ b/libelf/gelf_rel.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_rel.c 3177 2015-03-30 18:19:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_rel.c 3739 2019-05-06 05:18:15Z jkoshy $");
GElf_Rel *
gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
@@ -67,9 +67,9 @@ gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
return (NULL);
}
- msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0)
+ return (NULL);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -129,9 +129,9 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr)
return (0);
}
- msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0)
+ return (0);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -144,7 +144,7 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr)
LIBELF_COPY_U32(rel32, dr, r_offset);
- if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) ||
+ if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) ||
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
LIBELF_SET_ERROR(RANGE, 0);
return (0);
diff --git a/libelf/gelf_rela.c b/libelf/gelf_rela.c
index d485ab909299..0fa20a515292 100644
--- a/libelf/gelf_rela.c
+++ b/libelf/gelf_rela.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_rela.c 3177 2015-03-30 18:19:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_rela.c 3739 2019-05-06 05:18:15Z jkoshy $");
GElf_Rela *
gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst)
@@ -67,9 +67,9 @@ gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst)
return (NULL);
}
- msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0)
+ return (NULL);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -130,9 +130,9 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr)
return (0);
}
- msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0)
+ return (0);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -145,7 +145,7 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr)
LIBELF_COPY_U32(rela32, dr, r_offset);
- if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) ||
+ if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) ||
ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
LIBELF_SET_ERROR(RANGE, 0);
return (0);
diff --git a/libelf/gelf_sym.c b/libelf/gelf_sym.c
index ecd85fceefb4..c5f4484d56e6 100644
--- a/libelf/gelf_sym.c
+++ b/libelf/gelf_sym.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_sym.c 3177 2015-03-30 18:19:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_sym.c 3732 2019-04-22 11:08:38Z jkoshy $");
GElf_Sym *
gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
@@ -67,9 +67,9 @@ gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
return (NULL);
}
- msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0)
+ return (NULL);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -129,9 +129,9 @@ gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs)
return (0);
}
- msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0)
+ return (0);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
diff --git a/libelf/gelf_syminfo.c b/libelf/gelf_syminfo.c
index f6d7b6c367fa..9f3cd0e6f701 100644
--- a/libelf/gelf_syminfo.c
+++ b/libelf/gelf_syminfo.c
@@ -29,7 +29,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_syminfo.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_syminfo.c 3732 2019-04-22 11:08:38Z jkoshy $");
GElf_Syminfo *
gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
@@ -65,9 +65,9 @@ gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
return (NULL);
}
- msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0)
+ return (NULL);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
@@ -126,9 +126,9 @@ gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs)
return (0);
}
- msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0)
+ return (0);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
diff --git a/libelf/gelf_symshndx.c b/libelf/gelf_symshndx.c
index b490aa2bb11f..4a48a43d12b8 100644
--- a/libelf/gelf_symshndx.c
+++ b/libelf/gelf_symshndx.c
@@ -29,7 +29,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: gelf_symshndx.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: gelf_symshndx.c 3732 2019-04-22 11:08:38Z jkoshy $");
GElf_Sym *
gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
@@ -69,9 +69,9 @@ gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
return (NULL);
}
- msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0)
+ return (NULL);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= id->d_size) {
@@ -121,9 +121,9 @@ gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs,
return (0);
}
- msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
+ if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0)
+ return (0);
- assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= id->d_size) {
diff --git a/libelf/libelf_allocate.c b/libelf/libelf_allocate.c
index 0a74facc9fc4..2146b05141fd 100644
--- a/libelf/libelf_allocate.c
+++ b/libelf/libelf_allocate.c
@@ -36,33 +36,26 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_allocate.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: libelf_allocate.c 3738 2019-05-05 21:49:06Z jkoshy $");
Elf *
_libelf_allocate_elf(void)
{
Elf *e;
- if ((e = malloc(sizeof(*e))) == NULL) {
+ if ((e = calloc((size_t) 1, sizeof(*e))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, errno);
return NULL;
}
e->e_activations = 1;
- e->e_hdr.e_rawhdr = NULL;
e->e_byteorder = ELFDATANONE;
e->e_class = ELFCLASSNONE;
e->e_cmd = ELF_C_NULL;
e->e_fd = -1;
- e->e_flags = 0;
e->e_kind = ELF_K_NONE;
- e->e_parent = NULL;
- e->e_rawfile = NULL;
- e->e_rawsize = 0;
e->e_version = LIBELF_PRIVATE(version);
- (void) memset(&e->e_u, 0, sizeof(e->e_u));
-
return (e);
}
@@ -83,31 +76,25 @@ _libelf_init_elf(Elf *e, Elf_Kind kind)
}
}
-#define FREE(P) do { \
- if (P) \
- free(P); \
- } while (0)
-
-
-Elf *
+void
_libelf_release_elf(Elf *e)
{
Elf_Arhdr *arh;
switch (e->e_kind) {
case ELF_K_AR:
- FREE(e->e_u.e_ar.e_symtab);
+ free(e->e_u.e_ar.e_symtab);
break;
case ELF_K_ELF:
switch (e->e_class) {
case ELFCLASS32:
- FREE(e->e_u.e_elf.e_ehdr.e_ehdr32);
- FREE(e->e_u.e_elf.e_phdr.e_phdr32);
+ free(e->e_u.e_elf.e_ehdr.e_ehdr32);
+ free(e->e_u.e_elf.e_phdr.e_phdr32);
break;
case ELFCLASS64:
- FREE(e->e_u.e_elf.e_ehdr.e_ehdr64);
- FREE(e->e_u.e_elf.e_phdr.e_phdr64);
+ free(e->e_u.e_elf.e_ehdr.e_ehdr64);
+ free(e->e_u.e_elf.e_phdr.e_phdr64);
break;
}
@@ -115,8 +102,8 @@ _libelf_release_elf(Elf *e)
if (e->e_flags & LIBELF_F_AR_HEADER) {
arh = e->e_hdr.e_arhdr;
- FREE(arh->ar_name);
- FREE(arh->ar_rawname);
+ free(arh->ar_name);
+ free(arh->ar_rawname);
free(arh);
}
@@ -127,8 +114,6 @@ _libelf_release_elf(Elf *e)
}
free(e);
-
- return (NULL);
}
struct _Libelf_Data *
diff --git a/libelf/libelf_ar.c b/libelf/libelf_ar.c
index 8fce7419726e..6634d2c73c33 100644
--- a/libelf/libelf_ar.c
+++ b/libelf/libelf_ar.c
@@ -33,7 +33,7 @@
#include "_libelf.h"
#include "_libelf_ar.h"
-ELFTC_VCSID("$Id: libelf_ar.c 3446 2016-05-03 01:31:17Z emaste $");
+ELFTC_VCSID("$Id: libelf_ar.c 3712 2019-03-16 22:23:34Z jkoshy $");
#define LIBELF_NALLOC_SIZE 16
@@ -123,8 +123,16 @@ _libelf_ar_gethdr(Elf *e)
arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr;
assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG);
- assert((uintptr_t) arh <= (uintptr_t) parent->e_rawfile +
- parent->e_rawsize - sizeof(struct ar_hdr));
+
+ /*
+ * There needs to be enough space remaining in the file for the
+ * archive header.
+ */
+ if ((uintptr_t) arh > (uintptr_t) parent->e_rawfile +
+ (uintptr_t) parent->e_rawsize - sizeof(struct ar_hdr)) {
+ LIBELF_SET_ERROR(ARCHIVE, 0);
+ return (NULL);
+ }
if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
@@ -199,8 +207,8 @@ Elf *
_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
{
Elf *e;
- off_t next;
size_t nsz, sz;
+ off_t next, end;
struct ar_hdr *arh;
char *member, *namelen;
@@ -217,6 +225,17 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
assert((next & 1) == 0);
+ /*
+ * There needs to be enough space in the file to contain an
+ * ar(1) header.
+ */
+ end = next + (off_t) sizeof(struct ar_hdr);
+ if ((uintmax_t) end < (uintmax_t) next || /* Overflow. */
+ end > (off_t) elf->e_rawsize) {
+ LIBELF_SET_ERROR(ARCHIVE, 0);
+ return (NULL);
+ }
+
arh = (struct ar_hdr *) (elf->e_rawfile + next);
/*
@@ -229,6 +248,17 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
}
/*
+ * Check if the archive member that follows will fit in the
+ * containing archive.
+ */
+ end += (off_t) sz;
+ if (end < next || /* Overflow. */
+ end > (off_t) elf->e_rawsize) {
+ LIBELF_SET_ERROR(ARCHIVE, 0);
+ return (NULL);
+ }
+
+ /*
* Adjust the size field for members in BSD archives using
* extended naming.
*/
@@ -286,7 +316,8 @@ Elf_Arsym *
_libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
{
Elf_Arsym *symtab, *sym;
- unsigned int n, nentries;
+ unsigned int n;
+ size_t nentries;
unsigned char *end, *p, *p0, *s, *s0;
const size_t entrysize = 2 * sizeof(long);
long arraysize, fileoffset, stroffset, strtabsize;
@@ -343,7 +374,7 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
GET_LONG(p, fileoffset);
if (stroffset < 0 || fileoffset < 0 ||
- (size_t) fileoffset >= e->e_rawsize)
+ (off_t) fileoffset >= e->e_rawsize)
goto symtaberror;
s = s0 + stroffset;
diff --git a/libelf/libelf_convert.m4 b/libelf/libelf_convert.m4
index 04adeb3114a7..bb601ad92841 100644
--- a/libelf/libelf_convert.m4
+++ b/libelf/libelf_convert.m4
@@ -30,7 +30,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_convert.m4 3632 2018-10-10 21:12:43Z jkoshy $");
+ELFTC_VCSID("$Id: libelf_convert.m4 3712 2019-03-16 22:23:34Z jkoshy $");
/* WARNING: GENERATED FROM __file__. */
@@ -820,7 +820,7 @@ _libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
if (dsz < srcsz) /* Destination lacks space. */
return (0);
- nchains = srcsz / sizeof(uint32_t);
+ nchains = (uint32_t) (srcsz / sizeof(uint32_t));
chains = (uint32_t *) (uintptr_t) dst;
for (n = 0; n < nchains; n++) {
@@ -901,7 +901,7 @@ _libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src,
if (dsz < srcsz)
return (0);
- nchains = srcsz / sizeof(uint32_t);
+ nchains = (uint32_t) (srcsz / sizeof(uint32_t));
for (n = 0; n < nchains; n++) {
t32 = *s32++;
if (byteswap)
@@ -1078,13 +1078,8 @@ _libelf_translator_function *
_libelf_get_translator(Elf_Type t, int direction, int elfclass, int elfmachine)
{
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
- assert(elfmachine >= EM_NONE && elfmachine < EM__LAST__);
assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);
-
- if (t >= ELF_T_NUM ||
- (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) ||
- (direction != ELF_TOFILE && direction != ELF_TOMEMORY))
- return (NULL);
+ assert(t >= ELF_T_FIRST && t <= ELF_T_LAST);
/* TODO: Handle MIPS64 REL{,A} sections (ticket #559). */
(void) elfmachine;
diff --git a/libelf/libelf_data.c b/libelf/libelf_data.c
index fcffd8bd9d1c..968394d9bf9a 100644
--- a/libelf/libelf_data.c
+++ b/libelf/libelf_data.c
@@ -28,7 +28,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_data.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: libelf_data.c 3737 2019-05-05 14:49:50Z jkoshy $");
int
_libelf_xlate_shtype(uint32_t sht)
@@ -89,8 +89,14 @@ _libelf_xlate_shtype(uint32_t sht)
* OS, processor and user-defined section types) are
* legal, but since we do not know anything more about
* their semantics, we return a type of ELF_T_BYTE.
+ *
+ * The ELF specification uses 32 bit unsigned values for
+ * denoting section types, and defines SHT_HIUSER to be
+ * 0xFFFFFFFFUL (i.e., UINT32_MAX). Consequently, we only
+ * need to check that 'sht' is greater than or equal to
+ * SHT_LOOS.
*/
- if (sht >= SHT_LOOS && sht <= SHT_HIUSER)
+ if (sht >= SHT_LOOS)
return (ELF_T_BYTE);
/*
diff --git a/libelf/libelf_ehdr.c b/libelf/libelf_ehdr.c
index 38e4e74e14d2..e06c03355038 100644
--- a/libelf/libelf_ehdr.c
+++ b/libelf/libelf_ehdr.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_ehdr.c 3632 2018-10-10 21:12:43Z jkoshy $");
+ELFTC_VCSID("$Id: libelf_ehdr.c 3732 2019-04-22 11:08:38Z jkoshy $");
/*
* Retrieve counts for sections, phdrs and the section string table index
@@ -51,7 +51,12 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1);
assert(fsz > 0);
- if (e->e_rawsize < shoff + fsz) { /* raw file too small */
+ if (shoff + fsz < shoff) { /* Numeric overflow. */
+ LIBELF_SET_ERROR(HEADER, 0);
+ return (0);
+ }
+
+ if ((uint64_t) e->e_rawsize < shoff + fsz) {
LIBELF_SET_ERROR(HEADER, 0);
return (0);
}
@@ -138,14 +143,13 @@ _libelf_ehdr(Elf *e, int ec, int allocate)
fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
assert(fsz > 0);
- if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) {
+ if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < (off_t) fsz) {
LIBELF_SET_ERROR(HEADER, 0);
return (NULL);
}
- msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT);
-
- assert(msz > 0);
+ if ((msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT)) == 0)
+ return (NULL);
if ((ehdr = calloc((size_t) 1, msz)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
diff --git a/libelf/libelf_extended.c b/libelf/libelf_extended.c
index 96765a8293e1..59376e430861 100644
--- a/libelf/libelf_extended.c
+++ b/libelf/libelf_extended.c
@@ -29,7 +29,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_extended.c 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: libelf_extended.c 3712 2019-03-16 22:23:34Z jkoshy $");
/*
* Retrieve section #0, allocating a new section if needed.
@@ -57,7 +57,7 @@ _libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum)
assert(scn->s_ndx == SHN_UNDEF);
if (ec == ELFCLASS32)
- scn->s_shdr.s_shdr32.sh_size = shnum;
+ scn->s_shdr.s_shdr32.sh_size = (Elf32_Word) shnum;
else
scn->s_shdr.s_shdr64.sh_size = shnum;
@@ -87,9 +87,9 @@ _libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx)
assert(scn->s_ndx == SHN_UNDEF);
if (ec == ELFCLASS32)
- scn->s_shdr.s_shdr32.sh_link = shstrndx;
+ scn->s_shdr.s_shdr32.sh_link = (Elf32_Word) shstrndx;
else
- scn->s_shdr.s_shdr64.sh_link = shstrndx;
+ scn->s_shdr.s_shdr64.sh_link = (Elf64_Word) shstrndx;
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
@@ -116,9 +116,9 @@ _libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum)
assert(scn->s_ndx == SHN_UNDEF);
if (ec == ELFCLASS32)
- scn->s_shdr.s_shdr32.sh_info = phnum;
+ scn->s_shdr.s_shdr32.sh_info = (Elf32_Word) phnum;
else
- scn->s_shdr.s_shdr64.sh_info = phnum;
+ scn->s_shdr.s_shdr64.sh_info = (Elf64_Word) phnum;
(void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);
diff --git a/libelf/libelf_memory.c b/libelf/libelf_memory.c
index cb8e8f20438a..12ab12aed70e 100644
--- a/libelf/libelf_memory.c
+++ b/libelf/libelf_memory.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $");
+ELFTC_VCSID("$Id: libelf_memory.c 3738 2019-05-05 21:49:06Z jkoshy $");
/*
* Create an ELF descriptor for a memory image, optionally reporting
@@ -54,7 +54,7 @@ _libelf_memory(unsigned char *image, size_t sz, int reporterror)
e->e_cmd = ELF_C_READ;
e->e_rawfile = image;
- e->e_rawsize = sz;
+ e->e_rawsize = (off_t) sz;
#undef LIBELF_IS_ELF
#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \
@@ -78,7 +78,7 @@ _libelf_memory(unsigned char *image, size_t sz, int reporterror)
if (error != ELF_E_NONE) {
if (reporterror) {
LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0);
- (void) _libelf_release_elf(e);
+ _libelf_release_elf(e);
return (NULL);
}
} else {
diff --git a/libelf/libelf_msize.m4 b/libelf/libelf_msize.m4
index 179880c43278..2751f5be8b82 100644
--- a/libelf/libelf_msize.m4
+++ b/libelf/libelf_msize.m4
@@ -30,7 +30,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_msize.m4 3174 2015-03-27 17:13:41Z emaste $");
+ELFTC_VCSID("$Id: libelf_msize.m4 3732 2019-04-22 11:08:38Z jkoshy $");
/* WARNING: GENERATED FROM __file__. */
@@ -87,6 +87,14 @@ static struct msize msize[ELF_T_NUM] = {
MSIZES(ELF_TYPE_LIST)
};
+/*
+ * Returns the memory size of the specified ELF type 't' of ELF
+ * class 'ec' and ELF version 'version'.
+ *
+ * If the specified combination of ELF type, class, and version is
+ * unsupported then a value of 0 will be returned and the appropriate
+ * library error code set.
+ */
size_t
_libelf_msize(Elf_Type t, int elfclass, unsigned int version)
{
@@ -102,5 +110,10 @@ _libelf_msize(Elf_Type t, int elfclass, unsigned int version)
sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64;
+ if (sz == 0) {
+ LIBELF_SET_ERROR(UNIMPL, 0);
+ return (0);
+ }
+
return (sz);
}
diff --git a/libelf/libelf_phdr.c b/libelf/libelf_phdr.c
index 336ef3877f6f..5675a2e8c54c 100644
--- a/libelf/libelf_phdr.c
+++ b/libelf/libelf_phdr.c
@@ -31,7 +31,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_phdr.c 3632 2018-10-10 21:12:43Z jkoshy $");
+ELFTC_VCSID("$Id: libelf_phdr.c 3732 2019-04-22 11:08:38Z jkoshy $");
void *
_libelf_getphdr(Elf *e, int ec)
@@ -77,14 +77,18 @@ _libelf_getphdr(Elf *e, int ec)
assert(fsz > 0);
- if ((uint64_t) e->e_rawsize < (phoff + fsz)) {
+ if (phoff + fsz < phoff) { /* Numeric overflow. */
LIBELF_SET_ERROR(HEADER, 0);
return (NULL);
}
- msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT);
+ if ((uint64_t) e->e_rawsize < (phoff + fsz)) {
+ LIBELF_SET_ERROR(HEADER, 0);
+ return (NULL);
+ }
- assert(msz > 0);
+ if ((msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT)) == 0)
+ return (NULL);
if ((phdr = calloc(phnum, msz)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
@@ -125,9 +129,8 @@ _libelf_newphdr(Elf *e, int ec, size_t count)
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
assert(e->e_version == EV_CURRENT);
- msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version);
-
- assert(msz > 0);
+ if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0)
+ return (NULL);
newphdr = NULL;
if (count > 0 && (newphdr = calloc(count, msz)) == NULL) {
diff --git a/libelf/libelf_xlate.c b/libelf/libelf_xlate.c
index cfe6a0bdfdbd..7bb0e0f9d683 100644
--- a/libelf/libelf_xlate.c
+++ b/libelf/libelf_xlate.c
@@ -29,7 +29,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_xlate.c 3632 2018-10-10 21:12:43Z jkoshy $");
+ELFTC_VCSID("$Id: libelf_xlate.c 3732 2019-04-22 11:08:38Z jkoshy $");
/*
* Translate to/from the file representation of ELF objects.
@@ -83,9 +83,8 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding,
(src->d_type, (size_t) 1, src->d_version)) == 0)
return (NULL);
- msz = _libelf_msize(src->d_type, elfclass, src->d_version);
-
- assert(msz > 0);
+ if ((msz = _libelf_msize(src->d_type, elfclass, src->d_version)) == 0)
+ return (NULL);
if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) {
LIBELF_SET_ERROR(DATA, 0);
diff --git a/libelf/os.Linux.mk b/libelf/os.Linux.mk
new file mode 100644
index 000000000000..2292b6ec5f02
--- /dev/null
+++ b/libelf/os.Linux.mk
@@ -0,0 +1,31 @@
+# Enable additional warnings.
+CFLAGS+= -Wa,--fatal-warnings
+CFLAGS+= -Wall
+CFLAGS+= -Wcast-align
+CFLAGS+= -Wcast-qual
+CFLAGS+= -Wchar-subscripts
+CFLAGS+= -Wconversion
+CFLAGS+= -Werror
+CFLAGS+= -Wextra
+CFLAGS+= -Wformat=2
+CFLAGS+= -Winline
+CFLAGS+= -Wmissing-prototypes
+CFLAGS+= -Wnested-externs
+CFLAGS+= -Wempty-body
+CFLAGS+= -Wformat-y2k
+CFLAGS+= -Wformat-zero-length
+CFLAGS+= -Wpointer-sign
+CFLAGS+= -Wpointer-to-int-cast
+CFLAGS+= -Wsign-compare
+CFLAGS+= -Wunused-const-variable
+CFLAGS+= -Wunused-parameter
+CFLAGS+= -Wold-style-definition
+CFLAGS+= -Wpointer-arith
+CFLAGS+= -Wredundant-decls
+CFLAGS+= -Wreturn-type
+CFLAGS+= -Wshadow
+CFLAGS+= -Wstrict-prototypes
+CFLAGS+= -Wstrict-overflow
+CFLAGS+= -Wswitch
+CFLAGS+= -Wunused-parameter
+CFLAGS+= -Wwrite-strings