NetBSD Problem Report #51916

From www@NetBSD.org  Wed Jan 25 16:52:23 2017
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id D47667A13C
	for <gnats-bugs@gnats.NetBSD.org>; Wed, 25 Jan 2017 16:52:22 +0000 (UTC)
Message-Id: <20170125165221.B2A987A28D@mollari.NetBSD.org>
Date: Wed, 25 Jan 2017 16:52:21 +0000 (UTC)
From: n54@gmx.com
Reply-To: n54@gmx.com
To: gnats-bugs@NetBSD.org
Subject: ptrace(2) PT_IO option PIOD_READ_AUXV returns large piod_len on exit
X-Send-Pr-Version: www-1.0

>Number:         51916
>Category:       kern
>Synopsis:       ptrace(2) PT_IO option PIOD_READ_AUXV returns large piod_len on exit
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          closed
>Class:          support
>Submitter-Id:   net
>Arrival-Date:   Wed Jan 25 16:55:01 +0000 2017
>Closed-Date:    Thu Jan 26 01:08:30 +0000 2017
>Last-Modified:  Thu Jan 26 01:08:30 +0000 2017
>Originator:     Kamil Rytarowski
>Release:        NetBSD 7.99.59 amd64
>Organization:
TNF
>Environment:
NetBSD chieftec 7.99.59 NetBSD 7.99.59 (GENERIC) #0: Mon Jan 23 15:44:05 CET 2017  root@chieftec:/public/netbsd-tmp-root/sys/arch/amd64/compile/GENERIC amd64
>Description:
On OpenBSD (5.9) PIOD_READ_AUXV returns with piod_len set to the number of read bytes. On NetBSD it returns surprisingly large value.

OpenBSD the same code returns 64 bytes, on NetBSD 8496.

GDB code uses this information to determine the actual number of bytes read or written.

    case TARGET_OBJECT_AUXV:
#if defined (PT_IO) && defined (PIOD_READ_AUXV)
      /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO
	 request that allows us to read the auxilliary vector.  Other
	 BSD's may follow if they feel the need to support PIE.  */
      {
	struct ptrace_io_desc piod;

	if (writebuf)
	  return -1;
	piod.piod_op = PIOD_READ_AUXV;
	piod.piod_addr = readbuf;
	piod.piod_offs = (void *) (long) offset;
	piod.piod_len = len;

	errno = 0;
	if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
	  /* Return the actual number of bytes read or written.  */
	  return piod.piod_len;
      }
#endif
      return -1;


I'm not sure if this is intended, it looks suspicious.
>How-To-Repeat:
Code adapted to be compatible with NetBSD and OpenBSD.


chieftec$ cat aux.c 
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <stdio.h>
#include <unistd.h>
#include <err.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>

int
main(int argc, char **argv)
{
        int child;
        int status;
        int wpid;
        char ai[10000] = {};
        struct ptrace_io_desc io = {
                .piod_op = PIOD_READ_AUXV,
                .piod_offs = 0,
                .piod_addr = ai,
                .piod_len = sizeof(ai)
        };
        size_t i;

        child = fork();
        if (child == 0) {
                ptrace(PT_TRACE_ME, 0, NULL, 0);

                raise(SIGSTOP);

                _exit(0);
        }

        wpid = wait(&status);
        if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
                err(EXIT_FAILURE, "wait");

        int rrr = ptrace(PT_IO, child, (caddr_t)&io, 0);
        printf("ret = %d errno=%d piod_len=%zu\n", rrr, errno, io.piod_len);

        for (i = 0; i < io.piod_len; i++)
                if (ai[i] != 0)
                        printf("ai[%zu]=%#x ", i, ai[i]);

        return 0;
}
chieftec$ gcc aux.c                                                                                                                  
chieftec$ ./a
a.out   aux.c   aux.c~  
chieftec$ ./a.out                                                                                                                    
ret = 0 errno=0 piod_len=8496
ai[0]=0x3 ai[8]=0x40 ai[10]=0x40 ai[16]=0x4 ai[24]=0x38 ai[32]=0x5 ai[40]=0x7 ai[48]=0x6 ai[57]=0x10 ai[64]=0x7 ai[74]=0xffffff80 ai[75]=0xfffffff7 ai[76]=0x7f ai[77]=0x7f ai[80]=0x8 ai[96]=0x9 ai[104]=0xffffff90 ai[105]=0x8 ai[106]=0x40 ai[112]=0xffffffd0 ai[113]=0x7 ai[120]=0xffffffe8 ai[121]=0x3 ai[128]=0xffffffd1 ai[129]=0x7 ai[136]=0xffffffe8 ai[137]=0x3 ai[144]=0xffffffd2 ai[145]=0x7 ai[152]=0x64 ai[160]=0xffffffd3 ai[161]=0x7 ai[168]=0x64 ai[176]=0xd ai[185]=0xffffffc0 ai[186]=0x74 ai[187]=0xffffffff ai[188]=0x7f ai[189]=0x7f ai[192]=0xffffffde ai[193]=0x7 ai[200]=0x68 ai[201]=0xffffff90 ai[202]=0x74 ai[203]=0xffffffff ai[204]=0x7f ai[205]=0x7f ai[224]=0x2f ai[225]=0x74 ai[226]=0x6d ai[227]=0x70 ai[228]=0x2f ai[229]=0x2e ai[230]=0x2f ai[231]=0x61 ai[232]=0x2e ai[233]=0x6f ai[234]=0x75 ai[235]=0x74 sorry, pid 17406 was killed: orphaned traced process
>Fix:
N/A

>Release-Note:

>Audit-Trail:
From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/51916: ptrace(2) PT_IO option PIOD_READ_AUXV returns large
 piod_len on exit
Date: Wed, 25 Jan 2017 17:06:50 +0000

 On Wed, Jan 25, 2017 at 04:55:01PM +0000, n54@gmx.com wrote:
  > On OpenBSD (5.9) PIOD_READ_AUXV returns with piod_len set to the
  > number of read bytes. On NetBSD it returns surprisingly large
  > value.
  > 
  > OpenBSD the same code returns 64 bytes, on NetBSD 8496.

 It would be easier for those of us following along from the couch to
 look at this if you included the offending ptrace code itself :-)

 Looks like process_auxv_offset() illegally adjusts uio_resid. Please
 just fix it :-)

 -- 
 David A. Holland
 dholland@netbsd.org

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/51916 CVS commit: src/sys/kern
Date: Wed, 25 Jan 2017 12:55:47 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Wed Jan 25 17:55:47 UTC 2017

 Modified Files:
 	src/sys/kern: core_elf32.c sys_ptrace_common.c

 Log Message:
 PR/51916: Kamil Rytarowski: Don't multiply es_arglen with ptrsz since it is
 already in bytes and contains the maximum possible size:
 	ELF_AUX_ENTRIES * sizeof(auxv) + MAXPATHLEN + ALIGN


 To generate a diff of this commit:
 cvs rdiff -u -r1.50 -r1.51 src/sys/kern/core_elf32.c
 cvs rdiff -u -r1.10 -r1.11 src/sys/kern/sys_ptrace_common.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: kamil@NetBSD.org
State-Changed-When: Thu, 26 Jan 2017 02:08:30 +0100
State-Changed-Why:
The original problem has been fixed by Christos Zoulas.
It might still be improved.
cvs rdiff -u -r1.50 -r1.51 src/sys/kern/core_elf32.c
cvs rdiff -u -r1.10 -r1.11 src/sys/kern/sys_ptrace_common.c
cvs rdiff -u -r1.141 -r1.142 src/sys/kern/exec_elf32.c
cvs rdiff -u -r1.6 -r1.7 src/sys/kern/exec_elf64.c
cvs rdiff -u -r1.440 -r1.441 src/sys/kern/kern_exec.c

Patch by Jonathan Kollash
cvs rdiff -u -r1.32 -r1.33 src/sys/compat/netbsd32/netbsd32_exec.h


>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-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.