NetBSD Problem Report #42239
From mlevins@users.sourceforge.net Tue Oct 27 16:15:24 2009
Return-Path: <mlevins@users.sourceforge.net>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by www.NetBSD.org (Postfix) with ESMTP id 835DC63B8B6
for <gnats-bugs@gnats.NetBSD.org>; Tue, 27 Oct 2009 16:15:24 +0000 (UTC)
Message-Id: <8712.1256649694@poultrygeist.com>
Date: Tue, 27 Oct 2009 12:12:54 -0400 (EDT)
From: "M. Levinson" <mlevins@users.sourceforge.net>
Reply-To: "M. Levinson" <mlevins@users.sourceforge.net>
To: gnats-bugs@gnats.NetBSD.org
Subject: paxctl(8) fails since binutils 2.19.1 upgrade
X-Send-Pr-Version: 3.95
>Number: 42239
>Category: bin
>Synopsis: paxctl(8) fails since binutils 2.19.1 upgrade
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 27 16:20:00 +0000 2009
>Closed-Date: Mon Nov 09 07:31:08 +0000 2009
>Last-Modified: Mon Nov 09 07:31:08 +0000 2009
>Originator: M. Levinson
>Release: NetBSD 5.99.20 from 2009-10-17
>Organization:
>Environment:
$NetBSD: paxctl.c,v 1.11 2009/05/02 16:19:36 christos Exp $
Architecture: x86_64
Machine: amd64
>Description:
A comment in src/external/gpl3/binutils/dist/bfd/elf.c says
that binutils 2.19.1 tries "to create just one PT_NOTE segment
for all adjacent loadable .note* sections." But paxctl(8)
relies on the behavior of the previous version of binutils,
which created a separate PT_NOTE segment for the PaX flags,
and so it fails to find the PaX note section in ELF binaries
produced using binutils 2.19.1. With the patch below, it
successfully finds the PaX note section in binaries produced
using either the new binutils 2.19.1 or the old binutils 2.16.1.
(Thank you to Jukka Ruohonen, who reported the same symptom
to current-users on 2009-10-01, for also testing this patch.)
>How-To-Repeat:
% paxctl /usr/bin/ssh
paxctl: Could not find an ELF PaX PT_NOTE section in `/usr/bin/ssh'
>Fix:
--- src/usr.sbin/paxctl/paxctl.c
+++ src/usr.sbin/paxctl/paxctl.c
@@ -172,9 +172,9 @@ process_one(const char *name, uint32_t add_flags, uint32_t del_flags,
Elf64_Ehdr h64;
} e;
union {
- Elf32_Phdr h32;
- Elf64_Phdr h64;
- } p;
+ Elf32_Shdr h32;
+ Elf64_Shdr h64;
+ } s;
union {
Elf32_Nhdr h32;
Elf64_Nhdr h64;
@@ -185,9 +185,9 @@ process_one(const char *name, uint32_t add_flags, uint32_t del_flags,
/*LINTED*/(sizeof(a) == 4 ? bswap32(a) : \
/*LINTED*/(sizeof(a) == 8 ? bswap64(a) : (abort(), (a)))))))
#define EH(field) (size == 32 ? SWAP(e.h32.field) : SWAP(e.h64.field))
-#define PH(field) (size == 32 ? SWAP(p.h32.field) : SWAP(p.h64.field))
+#define SH(field) (size == 32 ? SWAP(s.h32.field) : SWAP(s.h64.field))
#define NH(field) (size == 32 ? SWAP(n.h32.field) : SWAP(n.h64.field))
-#define PHSIZE (size == 32 ? sizeof(p.h32) : sizeof(p.h64))
+#define SHSIZE (size == 32 ? sizeof(s.h32) : sizeof(s.h64))
#define NHSIZE (size == 32 ? sizeof(n.h32) : sizeof(n.h64))
struct {
char name[ELF_NOTE_PAX_NAMESZ];
@@ -230,17 +230,17 @@ process_one(const char *name, uint32_t add_flags, uint32_t del_flags,
goto out;
}
- for (i = 0; i < EH(e_phnum); i++) {
- if ((size_t)pread(fd, &p, PHSIZE,
- (off_t)EH(e_phoff) + i * PHSIZE) != PHSIZE) {
- warn("Can't read program header data from `%s'", name);
+ for (i = 0; i < EH(e_shnum); i++) {
+ if ((size_t)pread(fd, &s, SHSIZE,
+ (off_t)EH(e_shoff) + i * SHSIZE) != SHSIZE) {
+ warn("Can't read section header data from `%s'", name);
goto out;
}
- if (PH(p_type) != PT_NOTE)
+ if (SH(sh_type) != SHT_NOTE)
continue;
- if (pread(fd, &n, NHSIZE, (off_t)PH(p_offset)) != NHSIZE) {
+ if (pread(fd, &n, NHSIZE, (off_t)SH(sh_offset)) != NHSIZE) {
warn("Can't read note header from `%s'", name);
goto out;
}
@@ -248,7 +248,7 @@ process_one(const char *name, uint32_t add_flags, uint32_t del_flags,
NH(n_descsz) != ELF_NOTE_PAX_DESCSZ ||
NH(n_namesz) != ELF_NOTE_PAX_NAMESZ)
continue;
- if (pread(fd, &pax_tag, sizeof(pax_tag), PH(p_offset) + NHSIZE)
+ if (pread(fd, &pax_tag, sizeof(pax_tag), SH(sh_offset) + NHSIZE)
!= sizeof(pax_tag)) {
warn("Can't read pax_tag from `%s'", name);
goto out;
@@ -289,13 +289,13 @@ process_one(const char *name, uint32_t add_flags, uint32_t del_flags,
}
if (pwrite(fd, &pax_tag, sizeof(pax_tag),
- (off_t)PH(p_offset) + NHSIZE) != sizeof(pax_tag))
+ (off_t)SH(sh_offset) + NHSIZE) != sizeof(pax_tag))
warn("Can't modify flags on `%s'", name);
break;
}
if (!ok) {
- warnx("Could not find an ELF PaX PT_NOTE section in `%s'",
+ warnx("Could not find an ELF PaX SHT_NOTE section in `%s'",
name);
goto out;
}
>Release-Note:
>Audit-Trail:
From: Christos Zoulas <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/42239 CVS commit: src/usr.sbin/paxctl
Date: Tue, 27 Oct 2009 12:27:47 -0400
Module Name: src
Committed By: christos
Date: Tue Oct 27 16:27:47 UTC 2009
Modified Files:
src/usr.sbin/paxctl: paxctl.c
Log Message:
PR/42239: M. Levinson: paxctl(8) fails since binutils 2.19.1 upgrade
binutils-2.19.1 tries to create one note section for all adjacent loadable
note sections, instead of the old behavior where each note is in its own
section. The fix looks at the section headers instead of the program headers
for the note.
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/paxctl/paxctl.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Mon, 09 Nov 2009 07:31:08 +0000
State-Changed-Why:
christos committed the fix.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.