Do not obliterate errno value in the main thread during ptrace(2) call on x86.

Since ptrace(2) syscall can return -1 for non-error situations, libc
wrappers set errno to 0 before performing the syscall, as the service
to the caller.  On both i386 and amd64, the errno symbol was directly
referenced, which only works correctly in single-threaded process.

Change assembler wrappers for ptrace(2) to get current thread errno
location by calling __error().  Allow __error interposing, as
currently allowed in cerror().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
kib 2016-08-27 23:03:23 +00:00
parent 7b64fd1139
commit 11a326dc31
3 changed files with 22 additions and 12 deletions

View File

@ -38,14 +38,16 @@ __FBSDID("$FreeBSD$");
#include "SYS.h"
.globl CNAME(__error)
.type CNAME(__error),@function
ENTRY(ptrace)
xorl %eax,%eax
#ifdef PIC
movq PIC_GOT(CNAME(errno)),%r8
movl %eax,(%r8)
callq PIC_PLT(CNAME(__error))
#else
movl %eax,CNAME(errno)(%rip)
callq CNAME(__error)
#endif
movl $0,(%rax)
mov $SYS_ptrace,%eax
KERNCALL
jb HIDENAME(cerror)

View File

@ -38,16 +38,18 @@ __FBSDID("$FreeBSD$");
#include "SYS.h"
.globl CNAME(__error)
.type CNAME(__error),@function
ENTRY(ptrace)
xorl %eax,%eax
#ifdef PIC
PIC_PROLOGUE
movl PIC_GOT(CNAME(errno)),%edx
movl %eax,(%edx)
call PIC_PLT(CNAME(__error))
PIC_EPILOGUE
#else
movl %eax,CNAME(errno)
call CNAME(__error)
#endif
movl $0,(%eax)
mov $SYS_ptrace,%eax
KERNCALL
jb HIDENAME(cerror)

View File

@ -2,7 +2,7 @@
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
.\"
.\" This file is in the public domain.
.Dd July 28, 2016
.Dd August 28, 2016
.Dt PTRACE 2
.Os
.Sh NAME
@ -906,7 +906,13 @@ to return
\-1
as a non-error value; to disambiguate,
.Va errno
can be set to 0 before the call and checked afterwards.
is set to 0 in the libc wrapper for the
.Fn ptrace
system call and
.Fn ptrace
callers can reliably check
.Va errno
for non-zero value afterwards.
.Sh ERRORS
The
.Fn ptrace