NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/41332: paxctl(8) leaks file descriptors
>Number: 41332
>Category: bin
>Synopsis: paxctl(8) leaks file descriptors
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat May 02 05:10:00 +0000 2009
>Originator: Jason V. Miller
>Release: custom build netbsd-5
>Organization:
>Environment:
NetBSD lust 5.0 NetBSD 5.0 (LUST) #0: Thu Apr 30 14:47:02 MDT 2009
src@lust:/home/src/cvs/netbsd/netbsd-5/obj/sys/arch/i386/compile/LUST i386
>Description:
After open() succeeds in process_one(), a subsequent error processing the file
will cause the function to return an error immediately without closing the file
descriptor. This causes a leak and can prevent successful processing of a large
set of files during a single execution.
>How-To-Repeat:
Run something like this on a large directory, which should contain several
non-ELF files:
bash-4.0$ paxctl -m /usr/pkg/bin/*
Note that you'll be required to have a ulimit (-n) less than the number of
files that will error to reproduce the issue.
>Fix:
The following patch fixes the problem by closing the file descriptor of the
file currently processing if an error is encountered after open() succeeds.
--- paxctl.c 2009-05-01 22:53:14.000000000 -0600
+++ paxctl.c_orig 2009-05-01 22:51:10.000000000 -0600
@@ -203,12 +203,12 @@
if (read(fd, &e, sizeof(e)) != sizeof(e)) {
warn("Can't read ELF header from `%s'", name);
- goto error;
+ return 1;
}
if (memcmp(e.h32.e_ident, ELFMAG, SELFMAG) != 0) {
warnx("Bad ELF magic from `%s' (maybe it's not an ELF?)", name);
- goto error;
+ return 1;
}
if (e.h32.e_ehsize == sizeof(e.h32)) {
@@ -226,14 +226,14 @@
} else {
warnx("Bad ELF size %d from `%s' (maybe it's not an ELF?)",
(int)e.h32.e_ehsize, name);
- goto error;
+ return 1;
}
for (i = 0; i < EH(e_phnum); i++) {
if (pread(fd, &p, PHSIZE, (off_t)EH(e_phoff) + i * PHSIZE) !=
PHSIZE) {
warn("Can't read program header data from `%s'", name);
- goto error;
+ return 1;
}
if (PH(p_type) != PT_NOTE)
@@ -241,7 +241,7 @@
if (pread(fd, &n, NHSIZE, (off_t)PH(p_offset)) != NHSIZE) {
warn("Can't read note header from `%s'", name);
- goto error;
+ return 1;
}
if (NH(n_type) != ELF_NOTE_TYPE_PAX_TAG ||
NH(n_descsz) != ELF_NOTE_PAX_DESCSZ ||
@@ -250,14 +250,14 @@
if (pread(fd, &pax_tag, sizeof(pax_tag), PH(p_offset) + NHSIZE)
!= sizeof(pax_tag)) {
warn("Can't read pax_tag from `%s'", name);
- goto error;
+ return 1;
}
if (memcmp(pax_tag.name, ELF_NOTE_PAX_NAME,
sizeof(pax_tag.name)) != 0) {
warn("Unknown pax_tag name `%*.*s' from `%s'",
ELF_NOTE_PAX_NAMESZ, ELF_NOTE_PAX_NAMESZ,
pax_tag.name, name);
- goto error;
+ return 1;
}
ok = 1;
@@ -286,7 +286,7 @@
if (!pax_flags_sane(SWAP(pax_tag.flags))) {
warnx("New flags 0x%x don't make sense",
(uint32_t)SWAP(pax_tag.flags));
- goto error;
+ return 1;
}
if (pwrite(fd, &pax_tag, sizeof(pax_tag),
@@ -309,10 +309,6 @@
(void)printf("No PaX flags.\n");
}
return 0;
-
-error:
- (void)close(fd);
- return 1;
}
int
Home |
Main Index |
Thread Index |
Old Index