You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.5 KiB
127 lines
3.5 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
/*! @file
|
|
* Testing ptrace with PT_DENY_ATTACH is ignored by Pin (flag available only in macOS).
|
|
* Application may use this flag to deny being attached using ptrace system call.
|
|
* This will not be an issue when Pin is launching such an application, since it uses ptrace before running any application code
|
|
* and let it run "natively" after that (without ptrace-ing it)
|
|
* However PT_DENY_ATTACH will cause a segmentation fault in the following cases:
|
|
* 1. Pin decide to use ptrace again in one of his flows
|
|
* 2. A user want to attach with a debugger to the process for debugging
|
|
* 3. Pin attach to an application which has already used this flag
|
|
*
|
|
* This test only checks that Pin knows to handle cases 1 and 2.
|
|
* It doesn't check case 3, since Pin currently doesn't have a way to handle it (see mantis #3981 for more information)
|
|
*/
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <assert.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ptrace.h>
|
|
#include <sys/wait.h>
|
|
|
|
int main()
|
|
{
|
|
int parentToChildPipe[2];
|
|
int ChildToParentPipe[2];
|
|
pid_t child;
|
|
int res;
|
|
|
|
printf("Application started\n");
|
|
|
|
if (pipe(parentToChildPipe) < 0)
|
|
{
|
|
return 1;
|
|
}
|
|
if (pipe(ChildToParentPipe) < 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
child = fork();
|
|
if (child == 0)
|
|
{ // Child process
|
|
int ret =-1;
|
|
close(parentToChildPipe[1]);
|
|
close(ChildToParentPipe[0]);
|
|
|
|
// Deny attach in child
|
|
printf("Deny PTRACE requests from Child\n");
|
|
errno = 0;
|
|
ret = ptrace(PT_DENY_ATTACH, 0, 0 ,0);
|
|
// Pin ignore PT_DENY_ATTACH but still need to emulate a correct return value
|
|
assert(errno == 0);
|
|
assert(ret == 0);
|
|
|
|
// Notify Parent, child is ready to be traced
|
|
close(ChildToParentPipe[1]);
|
|
|
|
// Wait for parent process to notify it has attach to this process (child) before continuing
|
|
do
|
|
{
|
|
char dummy;
|
|
res = read(parentToChildPipe[0], &dummy, sizeof(dummy));
|
|
}
|
|
while (res < 0 && errno == EINTR);
|
|
assert(res == 0);
|
|
|
|
return 0;
|
|
}
|
|
else
|
|
{ // Parent process
|
|
|
|
long ret;
|
|
pid_t wpid;
|
|
close(parentToChildPipe[0]);
|
|
close(ChildToParentPipe[1]);
|
|
|
|
|
|
// Wait for child to notify it is ready to be traced
|
|
do
|
|
{
|
|
char dummy;
|
|
res = read(ChildToParentPipe[0], &dummy, sizeof(dummy));
|
|
}
|
|
while (res < 0 && errno == EINTR);
|
|
assert(res == 0);
|
|
|
|
// Attach to child
|
|
ret = ptrace (PT_ATTACH, child, 0, 0);
|
|
if (ret < 0 )
|
|
{
|
|
exit(1);
|
|
}
|
|
// Wait for child (tracee) to stop
|
|
wpid = waitpid(child, NULL, WUNTRACED);
|
|
if (wpid != child )
|
|
{
|
|
exit(1);
|
|
}
|
|
|
|
// Let child (tracee) continue
|
|
ret = ptrace (PT_CONTINUE , child, (caddr_t)1, 0);
|
|
if (ret < 0 )
|
|
{
|
|
exit(1);
|
|
}
|
|
|
|
// Notify child, parent has attached to it and it can continue
|
|
close(parentToChildPipe[1]);
|
|
|
|
}
|
|
|
|
printf("Application Finished, bye...\n");
|
|
return 0;
|
|
}
|