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:

NetBSD Home
NetBSD PR Database Search

(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.