NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/51916: ptrace(2) PT_IO option PIOD_READ_AUXV returns large piod_len on exit

>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:          open
>Class:          support
>Submitter-Id:   net
>Arrival-Date:   Wed Jan 25 16:55:01 +0000 2017
>Originator:     Kamil Rytarowski
>Release:        NetBSD 7.99.59 amd64
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
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.

#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;
      return -1;

I'm not sure if this is intended, it looks suspicious.
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>

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);



        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

Home | Main Index | Thread Index | Old Index