summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2006-05-11 22:03:23 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2006-05-11 22:03:23 +0000
commitf03f7d1bdcb4d37382d1eb9d2e02897f7768cea9 (patch)
treea22060248e171e7d6323b4063a9a0f2c1d724b4c
parent0a6e9ba40277f106bbc392648093762682567e0c (diff)
move prebind_strip(8) into ldconfig as the -D option; ok drahn
-rw-r--r--libexec/ld.so/Makefile4
-rw-r--r--libexec/ld.so/ldconfig/Makefile4
-rw-r--r--libexec/ld.so/ldconfig/ldconfig.822
-rw-r--r--libexec/ld.so/ldconfig/ldconfig.c41
-rw-r--r--libexec/ld.so/ldconfig/prebind_delete.c217
-rw-r--r--libexec/ld.so/prebind_strip/Makefile13
-rw-r--r--libexec/ld.so/prebind_strip/prebind_strip.848
-rw-r--r--libexec/ld.so/prebind_strip/prebind_strip.c227
8 files changed, 272 insertions, 304 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile
index 171457c1bf7..8d0b50d0df3 100644
--- a/libexec/ld.so/Makefile
+++ b/libexec/ld.so/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.33 2006/05/04 01:52:16 drahn Exp $
+# $OpenBSD: Makefile,v 1.34 2006/05/11 22:03:22 deraadt Exp $
SUBDIR=ldconfig ldd
-#SUBDIR+=prebind prebind_strip
+#SUBDIR+=prebind
VPATH=${.CURDIR}/../../lib/libc/string
SRCS= ldasm.S loader.c resolve.c dlfcn.c dl_printf.c rtld_machine.c
diff --git a/libexec/ld.so/ldconfig/Makefile b/libexec/ld.so/ldconfig/Makefile
index 663ef189494..4f0e1109827 100644
--- a/libexec/ld.so/ldconfig/Makefile
+++ b/libexec/ld.so/ldconfig/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.4 2004/11/10 22:03:18 drahn Exp $
+# $OpenBSD: Makefile,v 1.5 2006/05/11 22:03:22 deraadt Exp $
# $NetBSD: Makefile,v 1.10 1995/03/06 04:24:41 cgd Exp $
PROG= ldconfig
-SRCS= ldconfig.c shlib.c etc.c
+SRCS= ldconfig.c shlib.c etc.c prebind_delete.c
LDDIR?= $(.CURDIR)/..
#CFLAGS+=-Werror
#CFLAGS+=-I$(.CURDIR) -I$(LDDIR)/$(MACHINE_ARCH)
diff --git a/libexec/ld.so/ldconfig/ldconfig.8 b/libexec/ld.so/ldconfig/ldconfig.8
index 49042da5987..71ce8285479 100644
--- a/libexec/ld.so/ldconfig/ldconfig.8
+++ b/libexec/ld.so/ldconfig/ldconfig.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ldconfig.8,v 1.17 2005/12/31 15:08:22 jmc Exp $
+.\" $OpenBSD: ldconfig.8,v 1.18 2006/05/11 22:03:22 deraadt Exp $
.\"
.\" Copyright (c) 1993,1995 Paul Kranenburg
.\" All rights reserved.
@@ -37,8 +37,8 @@
.Nd configure the shared library cache
.Sh SYNOPSIS
.Nm ldconfig
-.Op Fl mRrsUv
-.Op Ar directory Ar ...
+.Op Fl DmRrsUv
+.Op Ar path Ar ...
.Sh DESCRIPTION
.Nm
is used to prepare a set of
@@ -91,6 +91,8 @@ for further information.
The following options are recognized by
.Nm ldconfig :
.Bl -tag -width indent
+.It Fl D
+Remove any prebind information in the specified binary or shared library.
.It Fl m
Merge the result of the scan of the directories given as arguments into
the existing hints file.
@@ -118,7 +120,19 @@ This option cannot be used with
.It Fl v
Switch on verbose mode.
.El
-.Sh Security
+.Sh PREBINDING
+Prebinding is loosely based on an earlier concept called Prelinking, which
+also accelerated
+.Xr ld.so 1
+performance but simultaneously impaired address space randomization.
+When prebinding information is added to libraries and programs using
+.Fl P ,
+program startup can be significantly improved because
+.Xr ld.so 1
+can initialize the shared library environment much faster.
+Prebinding information adds a small amount of data to the end of each
+specified library and program.
+.Sh SECURITY
Special care must be taken when loading shared libraries into the address
space of
.Ev set-user-Id
diff --git a/libexec/ld.so/ldconfig/ldconfig.c b/libexec/ld.so/ldconfig/ldconfig.c
index 2cda859a3c0..cab2ee9ba03 100644
--- a/libexec/ld.so/ldconfig/ldconfig.c
+++ b/libexec/ld.so/ldconfig/ldconfig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldconfig.c,v 1.18 2006/04/11 15:21:40 ray Exp $ */
+/* $OpenBSD: ldconfig.c,v 1.19 2006/05/11 22:03:22 deraadt Exp $ */
/*
* Copyright (c) 1993,1995 Paul Kranenburg
@@ -59,6 +59,8 @@
extern char *__progname;
static int verbose;
+static int delete;
+static int doprebind;
static int nostd;
static int justread;
static int merge;
@@ -85,13 +87,21 @@ static int buildhints(void);
static int readhints(void);
static void listhints(void);
+void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: %s [-DmRrsUv] [path ...]\n", __progname);
+ exit(1);
+}
+
int
main(int argc, char *argv[])
{
int i, c;
int rval = 0;
- while ((c = getopt(argc, argv, "RUmrsv")) != -1) {
+ while ((c = getopt(argc, argv, "DRmrsUv")) != -1) {
switch (c) {
case 'R':
rescan = 1;
@@ -111,10 +121,14 @@ main(int argc, char *argv[])
case 'v':
verbose = 1;
break;
+ case 'D':
+ delete = 1;
+ break;
+// case 'P':
+// doprebind = 1;
+ break;
default:
- fprintf(stderr,
- "usage: %s [-mRrsUv] [dir ...]\n", __progname);
- exit(1);
+ usage();
break;
}
}
@@ -125,6 +139,12 @@ main(int argc, char *argv[])
dir_list = xmalloc(1);
*dir_list = '\0';
+ if (delete) {
+ if (rescan || unconfig || merge || justread || nostd || doprebind)
+ errx(1, "cannot mix -U -R -r -s -P options with -D");
+ exit (prebind_delete(&argv[optind], verbose));
+ }
+
if (justread || merge || rescan) {
if ((rval = readhints()) != 0)
return rval;
@@ -135,9 +155,14 @@ main(int argc, char *argv[])
add_search_path(dir_list);
dir_list = xrealloc(dir_list, 1);
*dir_list = '\0';
- } else
- if (!nostd)
- std_search_path();
+ } else if (!nostd)
+ std_search_path();
+
+// if (doprebind) {
+// if (rescan || unconfig || justread || nostd)
+// errx(1, "cannot mix other options with -P");
+// exit (prebind(&argv[optind], verbose, merge));
+// }
if (unconfig) {
if (optind < argc)
diff --git a/libexec/ld.so/ldconfig/prebind_delete.c b/libexec/ld.so/ldconfig/prebind_delete.c
new file mode 100644
index 00000000000..6933f11acc9
--- /dev/null
+++ b/libexec/ld.so/ldconfig/prebind_delete.c
@@ -0,0 +1,217 @@
+/* $OpenBSD: prebind_delete.c,v 1.1 2006/05/11 22:03:22 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2006 Dale Rahn <drahn@dalerahn.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/exec_elf.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "../prebind.h"
+
+#define BUFSZ (256 * 1024)
+
+int strip_prebind(char *file, int verbose);
+int prebind_remove_load_section(int fd, char *name, int verbose);
+int prebind_newfile(int fd, char *name, struct stat *st,
+ struct prebind_footer *footer, int verbose);
+
+int
+prebind_delete(char **argv, int verbose)
+{
+ extern char *__progname;
+
+ while (*argv) {
+ if (strip_prebind(*argv, verbose) == -1)
+ return (1);
+ argv++;
+ }
+ return (0);
+}
+
+int
+strip_prebind(char *file, int verbose)
+{
+ struct prebind_footer footer;
+ extern char *__progname;
+ int fd, rdonly = 0;
+ struct stat st;
+ ssize_t bytes;
+
+ fd = open(file, O_RDWR);
+ if (fd == -1 && errno == ETXTBSY) {
+ fd = open(file, O_RDONLY);
+ rdonly = 1;
+ }
+ if (fd == -1) {
+ warn("%s", file);
+ return (-1);
+ }
+
+ if (fstat(fd, &st) == -1)
+ return (-1);
+
+ lseek(fd, -((off_t)sizeof(struct prebind_footer)), SEEK_END);
+ bytes = read(fd, &footer, sizeof(struct prebind_footer));
+ if (bytes != sizeof(struct prebind_footer))
+ goto done;
+
+ if (footer.bind_id[0] != BIND_ID0 || footer.bind_id[1] != BIND_ID1 ||
+ footer.bind_id[2] != BIND_ID2 || footer.bind_id[3] != BIND_ID3) {
+ if (verbose)
+ fprintf(stderr, "%s: no prebind header\n", file);
+ goto done;
+ }
+
+ if (rdonly) {
+ fd = prebind_newfile(fd, file, &st, &footer, verbose);
+ } else {
+ prebind_remove_load_section(fd, file, verbose);
+ ftruncate(fd, footer.orig_size);
+ }
+
+ if (verbose)
+ fprintf(stderr, "%s: stripped %lld bytes from %s\n",
+ __progname, st.st_size - footer.orig_size, file);
+
+done:
+ if (fd != -1)
+ close(fd);
+ return (0);
+}
+
+int
+prebind_remove_load_section(int fd, char *name, int verbose)
+{
+ Elf_Ehdr *ehdr;
+ Elf_Phdr *phdr;
+ int loadsection;
+ char *buf;
+
+ buf = mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_FILE | MAP_SHARED,
+ fd, 0);
+ if (buf == MAP_FAILED) {
+ if (verbose)
+ warn("%s: cannot mmap for for write", name);
+ return (-1);
+ }
+
+ ehdr = (Elf_Ehdr *)buf;
+ phdr = (Elf_Phdr *)(buf + ehdr->e_phoff);
+ loadsection = ehdr->e_phnum - 1;
+
+ if (ehdr->e_type != ET_EXEC ||
+ (phdr[loadsection].p_flags & 0x08000000) == 0)
+ goto done;
+
+ if (phdr[loadsection].p_type != PT_LOAD ||
+ ((phdr[loadsection].p_flags & 0x08000000) == 0)) {
+ /* doesn't look like ours */
+ if (verbose)
+ fprintf(stderr, "mapped, %s id doesn't match %lx\n", name,
+ (long)(phdr[loadsection].p_vaddr));
+ goto done;
+ }
+
+ bzero(&phdr[loadsection], sizeof(Elf_Phdr));
+ ehdr->e_phnum--;
+done:
+ munmap(buf, 8192);
+ return (0);
+}
+
+int
+prebind_newfile(int infd, char *name, struct stat *st,
+ struct prebind_footer *footer, int verbose)
+{
+ struct timeval tv[2];
+ char *newname, *buf;
+ ssize_t len, wlen;
+ int outfd;
+
+ if (asprintf(&newname, "%s.XXXXXXXXXX", name) == -1) {
+ if (verbose)
+ warn("asprintf");
+ return (-1);
+ }
+ outfd = open(newname, O_CREAT|O_RDWR|O_TRUNC, 0600);
+ if (outfd == -1) {
+ warn("%s", newname);
+ free(newname);
+ return (-1);
+ }
+
+ buf = malloc(BUFSZ);
+ if (buf == NULL) {
+ if (verbose)
+ warn("malloc");
+ goto fail;
+ }
+
+ /* copy old file to new file */
+ lseek(infd, (off_t)0, SEEK_SET);
+ while (1) {
+ len = read(infd, buf, BUFSIZ);
+ if (len == -1) {
+ if (verbose)
+ warn("read");
+ free(buf);
+ goto fail;
+ }
+ if (len == 0)
+ break;
+ wlen = write(outfd, buf, len);
+ if (wlen != len) {
+ free(buf);
+ goto fail;
+ }
+ }
+ free(buf);
+
+ /* now back track, and delete the header */
+ if (prebind_remove_load_section(outfd, newname, verbose) == -1)
+ goto fail;
+ if (ftruncate(outfd, footer->orig_size) == -1)
+ goto fail;
+
+ /* move new file into place */
+ TIMESPEC_TO_TIMEVAL(&tv[0], &st->st_atimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &st->st_mtimespec);
+ if (futimes(outfd, tv) == -1)
+ goto fail;
+ if (fchown(outfd, st->st_uid, st->st_gid) == -1)
+ goto fail;
+ if (fchmod(outfd, st->st_mode) == -1)
+ goto fail;
+ if (fchflags(outfd, st->st_flags) == -1)
+ goto fail;
+ if (rename(newname, name) == -1)
+ goto fail;
+
+ return (outfd);
+
+fail:
+ free(newname);
+ unlink(newname);
+ close(outfd);
+ return (-1);
+}
diff --git a/libexec/ld.so/prebind_strip/Makefile b/libexec/ld.so/prebind_strip/Makefile
deleted file mode 100644
index 6b0fa03bbd9..00000000000
--- a/libexec/ld.so/prebind_strip/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# $OpenBSD: Makefile,v 1.1 2006/05/03 16:10:52 drahn Exp $
-
-SRCS= prebind_strip.c
-
-PROG= prebind_strip
-MAN= prebind_strip.8
-
-BINDIR=/usr/sbin
-
-CFLAGS += -Wall -ggdb
-CFLAGS += -I${.CURDIR}/..
-
-.include <bsd.prog.mk>
diff --git a/libexec/ld.so/prebind_strip/prebind_strip.8 b/libexec/ld.so/prebind_strip/prebind_strip.8
deleted file mode 100644
index 112baa1e254..00000000000
--- a/libexec/ld.so/prebind_strip/prebind_strip.8
+++ /dev/null
@@ -1,48 +0,0 @@
-.\" $OpenBSD: prebind_strip.8,v 1.3 2006/05/05 13:52:42 jmc Exp $
-.\"
-.\" Copyright (c) 2006 Dale Rahn <drahn@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd May 1, 2006
-.Dt PREBIND_STRIP 8
-.Os
-.Sh NAME
-.Nm prebind_strip
-.Nd remove prebind info from binaries and libraries
-.Sh SYNOPSIS
-.Nm prebind_strip
-.Op Ar
-.Sh DESCRIPTION
-.Nm
-removes any prebind information from a binary or shared library.
-After this is run, the library length and md5 should match the original value.
-.Sh SEE ALSO
-.Xr ld.so 1 ,
-.Xr prebind 8
-.Sh STANDARDS
-None
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Ox 4.0 .
-.Nm
-is based loosely on Prelinking, however prelink removes the security
-feature of libraries appearing in random order on each invocation, thus
-it was incompatible with
-.Ox Ns 's
-goals.
-.Nm
-was written as an attempt to improve the speed of dynamic linking
-without the penalty of loss of security features.
diff --git a/libexec/ld.so/prebind_strip/prebind_strip.c b/libexec/ld.so/prebind_strip/prebind_strip.c
deleted file mode 100644
index a7b433af230..00000000000
--- a/libexec/ld.so/prebind_strip/prebind_strip.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* $OpenBSD: prebind_strip.c,v 1.4 2006/05/08 20:37:01 deraadt Exp $ */
-/*
- * Copyright (c) 2006 Dale Rahn <drahn@dalerahn.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/exec_elf.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include "prebind.h"
-
-void strip_prebind(char *file, char *output);
-void prebind_remove_load_section(int fd, char *name);
-int prebind_cat(int fd, struct prebind_footer *footer, char *name);
-
-extern char *__progname;
-
-void __dead
-usage(void)
-{
- fprintf(stderr, "Usage:%s [-o <outfile>] <filelist>\n", __progname);
- exit(1);
-}
-
-
-int
-main(int argc, char **argv)
-{
- char *outputfile = NULL;
- int i;
- int ch;
- while ((ch = getopt(argc, argv, "o:")) != -1) {
- switch (ch) {
- case 'o':
- outputfile = optarg;
- break;
- default:
- usage();
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
-
- if (outputfile != NULL && argc > 1) {
- fprintf(stderr, "%s:-o will not work with multiple files\n",
- __progname);
- usage();
- }
- for (i = 0; i < argc; i++) {
- strip_prebind(argv[i], outputfile);
- }
-
- return 0;
-}
-
-void
-strip_prebind(char *file, char *outfile)
-{
- struct prebind_footer footer;
- int fd;
- ssize_t bytes;
- int mode;
-
- if (outfile == NULL)
- mode = O_RDWR;
- else
- mode = O_RDONLY;
-
- fd = open(file, mode);
- if (fd == -1) {
- perror(file);
- return;
- }
- lseek(fd, -((off_t)sizeof(struct prebind_footer)), SEEK_END);
- bytes = read(fd, &footer, sizeof(struct prebind_footer));
- if (bytes != sizeof(struct prebind_footer)) {
- perror("short read\n");
- goto done;
- }
-
- if (footer.bind_id[0] == BIND_ID0 &&
- footer.bind_id[1] == BIND_ID1 &&
- footer.bind_id[2] == BIND_ID2 &&
- footer.bind_id[3] == BIND_ID3) {
-
- } else {
- fprintf(stderr, "%s: no prebind header\n", file);
- goto done;
- }
-
- if (outfile == NULL) {
- prebind_remove_load_section(fd, file);
-
- ftruncate(fd, footer.orig_size);
- } else {
- prebind_cat(fd, &footer, outfile);
- }
-done:
- close(fd);
-}
-
-void
-prebind_remove_load_section(int fd, char *name)
-{
- void *buf;
- Elf_Ehdr *ehdr;
- Elf_Phdr *phdr;
- int loadsection;
-
- buf = mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_FILE | MAP_SHARED,
- fd, 0);
- if (buf == MAP_FAILED) {
- perror(name);
- fprintf(stderr, "%s: cannot mmap for write\n", name);
- return;
- }
-
- ehdr = (Elf_Ehdr *) buf;
- phdr = (Elf_Phdr *)((char *)buf + ehdr->e_phoff);
-
- loadsection = ehdr->e_phnum - 1;
-
- if (ehdr->e_type != ET_EXEC ||
- (phdr[loadsection].p_flags & 0x08000000) == 0) {
- goto done;
- }
-
- if ((phdr[loadsection].p_type != PT_LOAD) ||
- ((phdr[loadsection].p_flags & 0x08000000) == 0)) {
- /* doesn't look like ours */
- fprintf(stderr, "mapped, %s id doesn't match %lx\n", name,
- (long)(phdr[loadsection].p_vaddr));
- goto done;
- }
-
- bzero(&phdr[loadsection], sizeof(Elf_Phdr));
-
- ehdr->e_phnum--;
-done:
- munmap(buf, 8192);
-}
-
-int
-prebind_cat(int fd, struct prebind_footer *footer, char *name)
-{
- int outfd;
- void *buf;
- Elf_Ehdr *ehdr;
- Elf_Phdr *phdr;
- size_t len, wlen, rlen, remlen;
- int header_done = 0;
- int err = 0;
- int loadsection;
-
- if (strcmp(name, "-") == 0)
- outfd = 1;
- else
- outfd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
-
- if (outfd == -1) {
- fprintf(stderr, "unable to open file %s\n", name);
- return 1;
- }
-#define BUFSZ (256 * 1024)
- buf = malloc(BUFSZ);
-
- if (buf == NULL) {
- fprintf(stderr, "failed to allocate copy buffer\n");
- return 1;
- }
-
- lseek(fd, 0, SEEK_SET);
- remlen = footer->orig_size;
- while (remlen > 0) {
- if (remlen > BUFSZ)
- rlen = BUFSZ;
- else
- rlen = remlen;
- len = read(fd, buf, rlen);
- if (len <= 0) {
- break; /* read failure */
- err=1;
- }
- remlen -= len;
- if (header_done == 0) {
- header_done = 1;
- ehdr = (Elf_Ehdr *) buf;
- phdr = (Elf_Phdr *)((char *)buf + ehdr->e_phoff);
-
- loadsection = ehdr->e_phnum - 1;
-
- if ((len >= ehdr->e_phoff +
- sizeof(Elf_Phdr) * ehdr->e_phnum) &&
- ehdr->e_type == ET_EXEC &&
- (phdr[loadsection].p_flags & 0x08000000) != 0 &&
- (phdr[loadsection].p_type == PT_LOAD)) {
- bzero(&phdr[loadsection], sizeof(Elf_Phdr));
- ehdr->e_phnum--;
- }
- }
- wlen = write(outfd, buf, len);
- if (wlen != len) {
- /* write failed */
- err=1;
- break;
- }
- }
-
- return err;
-}