summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2017-03-27 16:33:52 +0200
committerUlf Hermann <[email protected]>2017-05-04 16:12:05 +0000
commit5e738a2deec976ffac6c313327f407d7e4760076 (patch)
tree443eb2e8617f8198ea21e085e099d9104f71de4a
parent741248144e6361548359ad7d9e394144a0312ecf (diff)
Skip fchown, fchmod, fadvise, fallocate if functions are unavailable
If fchmod or fchown are unavailable, then the file permission model is likely to be different from what we expect there. posix_fallocate is a rather fragile affair already on linux, and not guaranteed to do anything useful. If it's not available, the result will be the same as when it's available and unreliable. fadvise is an optimization. Change-Id: I28a77e976a0198cf80397b45eb1bc8cfb30664f5 Reviewed-by: Christian Kandeler <[email protected]>
-rw-r--r--ChangeLog5
-rw-r--r--configure.ac3
-rw-r--r--libasm/ChangeLog4
-rw-r--r--libasm/asm_end.c2
-rw-r--r--libelf/ChangeLog5
-rw-r--r--libelf/elf_update.c4
-rw-r--r--src/ChangeLog9
-rw-r--r--src/ar.c59
-rw-r--r--src/elfcompress.c4
-rw-r--r--src/ranlib.c21
-rw-r--r--src/strings.c2
-rw-r--r--src/strip.c5
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/elfstrmerge.c4
14 files changed, 103 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a86247c..7a40c9d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2017-05-04 Ulf Hermann <[email protected]>
+ * configure.ac: Check for posix_fallocate, posix_fadvise, fchown,
+ fchmod.
+
+2017-05-04 Ulf Hermann <[email protected]>
+
* configure.ac: Check for tdestroy and node_t. Declare tdestroy in
config.h if tdestroy is not available from search.h, but node_t is.
diff --git a/configure.ac b/configure.ac
index 88b9d0a9..e55360da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -631,6 +631,9 @@ void tdestroy(void *root, void (*free_node)(void *nodep));
#endif
])
+AC_CHECK_DECLS([posix_fallocate, posix_fadvise], [], [], [[#include <fcntl.h>]])
+AC_CHECK_DECLS([fchown, fchmod], [], [], [[#include <sys/stat.h>]])
+
dnl Check if we have <linux/bpf.h> for EM_BPF disassembly.
AC_CHECK_HEADERS(linux/bpf.h)
AM_CONDITIONAL(HAVE_LINUX_BPF_H, [test "x$ac_cv_header_linux_bpf_h" = "xyes"])
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 53212139..2b499c70 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2017-05-04 Ulf Hermann <[email protected]>
+
+ * asm_end.c: Don't fchmod the new file if fchmod is unavailable.
+
2017-02-28 Ulf Hermann <[email protected]>
* Makefile.am: Use the predefined common library names rather than
diff --git a/libasm/asm_end.c b/libasm/asm_end.c
index ced24f50..7fabe94d 100644
--- a/libasm/asm_end.c
+++ b/libasm/asm_end.c
@@ -512,12 +512,14 @@ asm_end (AsmCtx_t *ctx)
if (result != 0)
return result;
+#if HAVE_DECL_FCHMOD
/* Make the new file globally readable and user/group-writable. */
if (fchmod (ctx->fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) != 0)
{
__libasm_seterrno (ASM_E_CANNOT_CHMOD);
return -1;
}
+#endif
/* Rename output file. */
if (rename (ctx->tmp_fname, ctx->fname) != 0)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 0a5200f4..fd20ebb7 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-04 Ulf Hermann <[email protected]>
+
+ * elf_update.c: Don't try to posix_fallocate on systems where it isn't
+ available. Don't fchmod the output file if there is no fchmod.
+
2017-02-28 Ulf Hermann <[email protected]>
* Makefile.am: Use the predefined common library names rather than
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 8ce07829..b6014cdb 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -80,6 +80,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
if (elf->map_address != NULL)
{
+#if HAVE_DECL_POSIX_FALLOCATE
/* When using mmap we want to make sure the file content is
really there. Only using ftruncate might mean the file is
extended, but space isn't allocated yet. This might cause a
@@ -100,6 +101,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
__libelf_seterrno (ELF_E_WRITE_ERROR);
return -1;
}
+#endif
/* The file is mmaped. */
if ((class == ELFCLASS32
@@ -129,6 +131,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
size = -1;
}
+#if HAVE_DECL_FCHMOD
/* POSIX says that ftruncate and write may clear the S_ISUID and S_ISGID
mode bits. So make sure we restore them afterwards if they were set.
This is not atomic if someone else chmod's the file while we operate. */
@@ -140,6 +143,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
__libelf_seterrno (ELF_E_WRITE_ERROR);
size = -1;
}
+#endif
if (size != -1 && elf->parent == NULL)
elf->maximum_size = size;
diff --git a/src/ChangeLog b/src/ChangeLog
index 4a32604f..e0df2e13 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
2017-05-04 Ulf Hermann <[email protected]>
+ * ar.c: Don't fchmod or fchown the output file if fchmod or fchown
+ don't exist.
+ * elfcompress.c: Likewise.
+ * ranlib.c: Likewise.
+ * strip.c: Likewise.
+ * strings.c: Skip posix_fadvise if it doesn't exist.
+
+2017-05-04 Ulf Hermann <[email protected]>
+
* strings.c: If roundup() is not defined, define it.
2017-04-28 Ulf Hermann <[email protected]>
diff --git a/src/ar.c b/src/ar.c
index ec32cee5..45b219ac 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -655,6 +655,7 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc,
if (oper != oper_print)
{
+#if HAVE_DECL_FCHMOD
/* Fix up the mode. */
if (unlikely (fchmod (xfd, arhdr->ar_mode) != 0))
{
@@ -662,6 +663,7 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc,
arhdr->ar_name);
status = 0;
}
+#endif
if (preserve_dates)
{
@@ -788,20 +790,25 @@ cannot rename temporary file to %.*s"),
!= (ssize_t) symtab.symsofflen)
|| (write_retry (newfd, symtab.symsname,
symtab.symsnamelen)
- != (ssize_t) symtab.symsnamelen)))
+ != (ssize_t) symtab.symsnamelen))) ||
/* Even if the original file had content before the
symbol table, we write it in the correct order. */
- || (index_off != SARMAG
- && copy_content (elf, newfd, SARMAG, index_off - SARMAG))
- || copy_content (elf, newfd, rest_off, st.st_size - rest_off)
+ (index_off != SARMAG
+ && copy_content (elf, newfd, SARMAG, index_off - SARMAG)) ||
+ copy_content (elf, newfd, rest_off, st.st_size - rest_off) ||
+#if HAVE_DECL_FCHMOD
/* Set the mode of the new file to the same values the
original file has. */
- || fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+#endif
+ (
+#if HAVE_DECL_FCHOWN
/* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid,
+ ({asm ("" :: "r" (fchown (newfd, st.st_uid,
st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, arfname) != 0))
+#endif
+ close (newfd) != 0) ||
+ (newfd = -1, rename (tmpfname, arfname) != 0))
goto nonew_unlink;
}
}
@@ -1046,13 +1053,19 @@ do_oper_delete (const char *arfname, char **argv, int argc,
goto nonew_unlink;
}
- /* Set the mode of the new file to the same values the original file
- has. */
- if (fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ if (
+#if HAVE_DECL_FCHMOD
+ /* Set the mode of the new file to the same values the original file
+ has. */
+ fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+#endif
+ (
+#if HAVE_DECL_FCHOWN
/* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, arfname) != 0))
+ ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
+#endif
+ close (newfd) != 0) ||
+ (newfd = -1, rename (tmpfname, arfname) != 0))
goto nonew_unlink;
errout:
@@ -1503,14 +1516,20 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
goto nonew_unlink;
}
- /* Set the mode of the new file to the same values the original file
- has. */
if (fd != -1
- && (fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ && (
+#if HAVE_DECL_FCHMOD
+ /* Set the mode of the new file to the same values the original file
+ has. */
+ fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+#endif
+ (
+#if HAVE_DECL_FCHOWN
/* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, arfname) != 0)))
+ ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
+#endif
+ close (newfd) != 0) ||
+ (newfd = -1, rename (tmpfname, arfname) != 0)))
goto nonew_unlink;
errout:
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 8e0d5c55..e092e136 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -1235,13 +1235,17 @@ process_file (const char *fname)
elf_end (elfnew);
elfnew = NULL;
+#if HAVE_DECL_FCHMOD
/* Try to match mode and owner.group of the original file. */
if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
if (verbose >= 0)
error (0, errno, "Couldn't fchmod %s", fnew);
+#endif
+#if HAVE_DECL_FCHOWN
if (fchown (fdnew, st.st_uid, st.st_gid) != 0)
if (verbose >= 0)
error (0, errno, "Couldn't fchown %s", fnew);
+#endif
/* Finally replace the old file with the new file. */
if (foutput == NULL)
diff --git a/src/ranlib.c b/src/ranlib.c
index cc0ee233..ecaeb55a 100644
--- a/src/ranlib.c
+++ b/src/ranlib.c
@@ -252,19 +252,24 @@ handle_file (const char *fname)
!= (ssize_t) symtab.symsofflen)
|| (write_retry (newfd, symtab.symsname,
symtab.symsnamelen)
- != (ssize_t) symtab.symsnamelen)))
+ != (ssize_t) symtab.symsnamelen))) ||
/* Even if the original file had content before the
symbol table, we write it in the correct order. */
- || (index_off > SARMAG
- && copy_content (arelf, newfd, SARMAG, index_off - SARMAG))
- || copy_content (arelf, newfd, rest_off, st.st_size - rest_off)
+ (index_off > SARMAG
+ && copy_content (arelf, newfd, SARMAG, index_off - SARMAG)) ||
+ copy_content (arelf, newfd, rest_off, st.st_size - rest_off) ||
+#if HAVE_DECL_FCHMOD
/* Set the mode of the new file to the same values the
original file has. */
- || fchmod (newfd, st.st_mode & ALLPERMS) != 0
+ fchmod (newfd, st.st_mode & ALLPERMS) != 0 ||
+#endif
+ (
+#if HAVE_DECL_FCHOWN
/* Never complain about fchown failing. */
- || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
- close (newfd) != 0)
- || (newfd = -1, rename (tmpfname, fname) != 0))
+ ({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
+#endif
+ close (newfd) != 0) ||
+ (newfd = -1, rename (tmpfname, fname) != 0))
goto nonew_unlink;
}
}
diff --git a/src/strings.c b/src/strings.c
index 22cbfaca..46b23560 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -574,9 +574,11 @@ read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to)
elfmap_off = from & ~(ps - 1);
elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size);
+#if HAVE_DECL_POSIX_FADVISE
if (unlikely (elfmap == MAP_FAILED))
/* Let the kernel know we are going to read everything in sequence. */
(void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL);
+#endif
}
if (unlikely (elfmap == MAP_FAILED))
diff --git a/src/strip.c b/src/strip.c
index f7474418..f5920812 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -2007,7 +2007,10 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Create the real output file. First rename, then change the
mode. */
if (rename (tmp_debug_fname, debug_fname) != 0
- || fchmod (debug_fd, mode) != 0)
+#if HAVE_DECL_FCHMOD
+ || fchmod (debug_fd, mode) != 0
+#endif
+ )
{
error (0, errno, gettext ("while creating '%s'"), debug_fname);
result = 1;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index a9bc6faa..6dab8018 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-04 Ulf Hermann <[email protected]>
+
+ * elfstrmerge.c: Don't fchmod or fchown the output file if fchmod or
+ fchown don't exist.
+
2017-04-28 Ulf Hermann <[email protected]>
* run-disasm-x86-64.sh: Disable if the native binary format is not
diff --git a/tests/elfstrmerge.c b/tests/elfstrmerge.c
index c2c3fb97..17f40c7d 100644
--- a/tests/elfstrmerge.c
+++ b/tests/elfstrmerge.c
@@ -650,11 +650,15 @@ main (int argc, char **argv)
elf_end (elfnew);
elfnew = NULL;
+#if HAVE_DECL_FCHMOD
/* Try to match mode and owner.group of the original file. */
if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
error (0, errno, "Couldn't fchmod %s", fnew);
+#endif
+#if HAVE_DECL_FCHOWN
if (fchown (fdnew, st.st_uid, st.st_gid) != 0)
error (0, errno, "Couldn't fchown %s", fnew);
+#endif
/* Finally replace the old file with the new merged strings file. */
if (replace)