Skip to content

Commit 76e4f12

Browse files
Merge pull request #1040 from lukaszstolarczuk/ptrace
Add info about ptrace permissions
2 parents f4b0715 + da7706c commit 76e4f12

File tree

12 files changed

+49
-78
lines changed

12 files changed

+49
-78
lines changed

.github/workflows/reusable_basic.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,6 @@ jobs:
145145
- name: Install libhwloc
146146
run: .github/scripts/install_hwloc.sh
147147

148-
- name: Set ptrace value for IPC test
149-
run: sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
150-
151148
- name: Get UMF version
152149
run: |
153150
VERSION=$(git describe --tags --abbrev=0 | grep -oP '\d+\.\d+\.\d+')

.github/workflows/reusable_fast.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@ jobs:
8888
sudo apt-get install -y cmake libnuma-dev libtbb-dev
8989
.github/scripts/install_hwloc.sh # install hwloc-2.3.0 instead of hwloc-2.1.0 present in the OS package
9090
91-
- name: Set ptrace value for IPC test (on Linux only)
92-
if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-20.04' }}
93-
run: sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
94-
9591
- name: Configure CMake
9692
if: matrix.simple_cmake == 'OFF'
9793
run: >

.github/workflows/reusable_proxy_lib.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ jobs:
3434
sudo apt-get update
3535
sudo apt-get install -y cmake libhwloc-dev libtbb-dev lcov
3636
37-
- name: Set ptrace value for IPC test
38-
run: sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
39-
4037
- name: Configure build
4138
run: >
4239
cmake

.github/workflows/reusable_sanitizers.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ jobs:
4040
sudo apt-get update
4141
sudo apt-get install -y intel-oneapi-ippcp-devel intel-oneapi-ipp-devel intel-oneapi-common-oneapi-vars intel-oneapi-compiler-dpcpp-cpp
4242
43-
44-
- name: Set ptrace value for IPC test
45-
run: sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
46-
4743
- name: Configure build
4844
run: >
4945
${{ matrix.compiler.cxx == 'icpx' && '. /opt/intel/oneapi/setvars.sh &&' || ''}}

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,12 @@ OS memory provider supports two types of memory mappings (set by the `visibility
159159
IPC API requires the `UMF_MEM_MAP_SHARED` memory `visibility` mode
160160
(`UMF_RESULT_ERROR_INVALID_ARGUMENT` is returned otherwise).
161161

162-
IPC API uses the file descriptor duplication. It requires using `pidfd_getfd(2)` to obtain
163-
a duplicate of another process's file descriptor (`pidfd_getfd(2)` is supported since Linux 5.6).
164-
Permission to duplicate another process's file descriptor is governed by a ptrace access mode
165-
`PTRACE_MODE_ATTACH_REALCREDS` check (see `ptrace(2)`) that can be changed using
166-
the `/proc/sys/kernel/yama/ptrace_scope` interface in the following way:
162+
IPC API uses file descriptor duplication, which requires the `pidfd_getfd(2)` system call to obtain
163+
a duplicate of another process's file descriptor. This system call is supported since Linux 5.6.
164+
Required permission ("restricted ptrace") is governed by the `PTRACE_MODE_ATTACH_REALCREDS` check
165+
(see `ptrace(2)`). To allow file descriptor duplication in a binary that opens IPC handle, you can call
166+
`prctl(PR_SET_PTRACER, ...)` in the producer binary that gets the IPC handle.
167+
Alternatively you can change the `ptrace_scope` globally in the system, e.g.:
167168

168169
```sh
169170
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
@@ -194,16 +195,16 @@ Packages required for tests (Linux-only yet):
194195

195196
A memory provider that provides memory from L0 device.
196197

197-
IPC API uses the file descriptor duplication. It requires using `pidfd_getfd(2)` to obtain
198-
a duplicate of another process's file descriptor (`pidfd_getfd(2)` is supported since Linux 5.6).
199-
Permission to duplicate another process's file descriptor is governed by a ptrace access mode
200-
`PTRACE_MODE_ATTACH_REALCREDS` check (see `ptrace(2)`) that can be changed using
201-
the `/proc/sys/kernel/yama/ptrace_scope` interface in the following way:
198+
IPC API uses file descriptor duplication, which requires the `pidfd_getfd(2)` system call to obtain
199+
a duplicate of another process's file descriptor. This system call is supported since Linux 5.6.
200+
Required permission ("restricted ptrace") is governed by the `PTRACE_MODE_ATTACH_REALCREDS` check
201+
(see `ptrace(2)`). To allow file descriptor duplication in a binary that opens IPC handle, you can call
202+
`prctl(PR_SET_PTRACER, ...)` in the producer binary that gets the IPC handle.
203+
Alternatively you can change the `ptrace_scope` globally in the system, e.g.:
202204

203205
```sh
204206
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
205207
```
206-
207208
##### Requirements
208209

209210
1) Linux or Windows OS
@@ -359,7 +360,7 @@ The memory used by the proxy memory allocator is mmap'ed:
359360
1) with the `MAP_PRIVATE` flag by default or
360361
2) with the `MAP_SHARED` flag if the `UMF_PROXY` environment variable contains one of two following strings: `page.disposition=shared-shm` or `page.disposition=shared-fd`. These two options differ in a mechanism used during IPC:
361362
- `page.disposition=shared-shm` - IPC uses the named shared memory. An SHM name is generated using the `umf_proxy_lib_shm_pid_$PID` pattern, where `$PID` is the PID of the process. It creates the `/dev/shm/umf_proxy_lib_shm_pid_$PID` file.
362-
- `page.disposition=shared-fd` - IPC uses the file descriptor duplication. It requires using `pidfd_getfd(2)` to obtain a duplicate of another process's file descriptor. Permission to duplicate another process's file descriptor is governed by a ptrace access mode `PTRACE_MODE_ATTACH_REALCREDS` check (see `ptrace(2)`) that can be changed using the `/proc/sys/kernel/yama/ptrace_scope` interface. `pidfd_getfd(2)` is supported since Linux 5.6.
363+
- `page.disposition=shared-fd` - IPC API uses file descriptor duplication, which requires the `pidfd_getfd(2)` system call to obtain a duplicate of another process's file descriptor. This system call is supported since Linux 5.6. Required permission ("restricted ptrace") is governed by the `PTRACE_MODE_ATTACH_REALCREDS` check (see `ptrace(2)`). To allow file descriptor duplication in a binary that opens IPC handle, you can call `prctl(PR_SET_PTRACER, ...)` in the producer binary that gets the IPC handle. Alternatively you can change the `ptrace_scope` globally in the system, e.g.: `sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"`.
363364

364365
**Size threshold**
365366

examples/ipc_ipcapi/ipc_ipcapi_anon_fd.sh

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (C) 2024 Intel Corporation
2+
# Copyright (C) 2024-2025 Intel Corporation
33
#
44
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
55
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -16,16 +16,8 @@ PORT=$(( 1024 + ( $$ % ( 65535 - 1024 ))))
1616
# to obtain a duplicate of another process's file descriptor.
1717
# Permission to duplicate another process's file descriptor
1818
# is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
19-
# that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
20-
PTRACE_SCOPE_FILE="/proc/sys/kernel/yama/ptrace_scope"
21-
VAL=0
22-
if [ -f $PTRACE_SCOPE_FILE ]; then
23-
PTRACE_SCOPE_VAL=$(cat $PTRACE_SCOPE_FILE)
24-
if [ $PTRACE_SCOPE_VAL -ne $VAL ]; then
25-
echo "SKIP: ptrace_scope is not set to 0 (classic ptrace permissions) - skipping the test"
26-
exit 125 # skip code defined in CMakeLists.txt
27-
fi
28-
fi
19+
# In the producer binary used in this example prctl(PR_SET_PTRACER, getppid()) is used
20+
# to allow consumer to duplicate file descriptor of producer.
2921

3022
UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"
3123

examples/ipc_ipcapi/ipc_ipcapi_producer.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2024 Intel Corporation
2+
* Copyright (C) 2024-2025 Intel Corporation
33
*
44
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
55
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -9,6 +9,7 @@
99
#include <stdio.h>
1010
#include <stdlib.h>
1111
#include <string.h>
12+
#include <sys/prctl.h>
1213
#include <sys/socket.h>
1314
#include <unistd.h>
1415

@@ -69,6 +70,21 @@ int main(int argc, char *argv[]) {
6970

7071
int port = atoi(argv[1]);
7172

73+
// The prctl() function with PR_SET_PTRACER is used here to allow parent process and its children
74+
// to ptrace the current process. This is necessary because UMF's memory providers on Linux (except CUDA)
75+
// use the pidfd_getfd(2) system call to duplicate another process's file descriptor, which is
76+
// governed by ptrace permissions. By default on Ubuntu /proc/sys/kernel/yama/ptrace_scope is
77+
// set to 1 ("restricted ptrace"), which prevents pidfd_getfd from working unless ptrace_scope
78+
// is set to 0.
79+
// To overcome this limitation without requiring users to change the ptrace_scope
80+
// setting (which requires root privileges), we use prctl() to allow the consumer process
81+
// to copy producer's file descriptor, even when ptrace_scope is set to 1.
82+
ret = prctl(PR_SET_PTRACER, getppid());
83+
if (ret == -1) {
84+
perror("PR_SET_PTRACER may be not supported. prctl() call failed");
85+
goto err_end;
86+
}
87+
7288
umf_memory_provider_handle_t OS_memory_provider = NULL;
7389
umf_os_memory_provider_params_handle_t os_params = NULL;
7490
enum umf_result_t umf_result;
@@ -259,6 +275,7 @@ int main(int argc, char *argv[]) {
259275
err_destroy_OS_params:
260276
umfOsMemoryProviderParamsDestroy(os_params);
261277

278+
err_end:
262279
if (ret == 0) {
263280
fprintf(stderr, "[producer] Shutting down (status OK) ...\n");
264281
} else if (ret == 1) {

scripts/qemu/run-tests.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# Copyright (C) 2024 Intel Corporation
2+
# Copyright (C) 2024-2025 Intel Corporation
33
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
44
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

@@ -23,8 +23,6 @@ UMF_DIR=$(pwd)
2323
# Drop caches, restores free memory on NUMA nodes
2424
echo password | sudo sync;
2525
echo password | sudo sh -c "/usr/bin/echo 3 > /proc/sys/vm/drop_caches"
26-
# Set ptrace value for IPC test
27-
echo password | sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
2826

2927
numactl -H
3028

src/utils/utils_posix_common.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2024 Intel Corporation
3+
* Copyright (C) 2024-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -91,9 +91,8 @@ umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out) {
9191
return UMF_RESULT_ERROR_NOT_SUPPORTED;
9292
#else
9393
// pidfd_getfd(2) is used to obtain a duplicate of another process's file descriptor.
94-
// Permission to duplicate another process's file descriptor
95-
// is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
96-
// that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
94+
// Calling prctl(PR_SET_PTRACER, getppid()) in a producer binary that creates IPC handle
95+
// allows file descriptor duplication for parent process and its children.
9796
// pidfd_getfd(2) is supported since Linux 5.6
9897
// pidfd_open(2) is supported since Linux 5.3
9998
errno = 0;

test/common/ipc_common.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2024 Intel Corporation
2+
* Copyright (C) 2024-2025 Intel Corporation
33
*
44
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
55
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -9,6 +9,7 @@
99
#include <stdio.h>
1010
#include <stdlib.h>
1111
#include <string.h>
12+
#include <sys/prctl.h>
1213
#include <sys/socket.h>
1314
#include <unistd.h>
1415

@@ -336,6 +337,12 @@ int run_producer(int port, umf_memory_pool_ops_t *pool_ops, void *pool_params,
336337
int producer_socket = -1;
337338
char consumer_message[MSG_SIZE];
338339

340+
ret = prctl(PR_SET_PTRACER, getppid());
341+
if (ret == -1) {
342+
perror("PR_SET_PTRACER may be not supported. prctl() call failed");
343+
goto err_end;
344+
}
345+
339346
// create OS memory provider
340347
umf_result =
341348
umfMemoryProviderCreate(provider_ops, provider_params, &provider);
@@ -528,6 +535,7 @@ int run_producer(int port, umf_memory_pool_ops_t *pool_ops, void *pool_params,
528535
err_umfMemoryProviderDestroy:
529536
umfMemoryProviderDestroy(provider);
530537

538+
err_end:
531539
if (ret == 0) {
532540
fprintf(stderr, "[producer] Shutting down (status OK) ...\n");
533541
} else if (ret == 1) {

test/ipc_os_prov_anon_fd.sh

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (C) 2024 Intel Corporation
2+
# Copyright (C) 2024-2025 Intel Corporation
33
#
44
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
55
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -12,21 +12,6 @@ set -e
1212
# port should be a number from the range <1024, 65535>
1313
PORT=$(( 1024 + ( $$ % ( 65535 - 1024 ))))
1414

15-
# The ipc_os_prov_anon_fd example requires using pidfd_getfd(2)
16-
# to obtain a duplicate of another process's file descriptor.
17-
# Permission to duplicate another process's file descriptor
18-
# is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
19-
# that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
20-
PTRACE_SCOPE_FILE="/proc/sys/kernel/yama/ptrace_scope"
21-
VAL=0
22-
if [ -f $PTRACE_SCOPE_FILE ]; then
23-
PTRACE_SCOPE_VAL=$(cat $PTRACE_SCOPE_FILE)
24-
if [ $PTRACE_SCOPE_VAL -ne $VAL ]; then
25-
echo "SKIP: ptrace_scope is not set to 0 (classic ptrace permissions) - skipping the test"
26-
exit 125 # skip code defined in CMakeLists.txt
27-
fi
28-
fi
29-
3015
UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"
3116

3217
echo "Starting ipc_os_prov_anon_fd CONSUMER on port $PORT ..."

test/providers/ipc_level_zero_prov.sh

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (C) 2024 Intel Corporation
2+
# Copyright (C) 2024-2025 Intel Corporation
33
#
44
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
55
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -12,21 +12,6 @@ set -e
1212
# port should be a number from the range <1024, 65535>
1313
PORT=$(( 1024 + ( $$ % ( 65535 - 1024 ))))
1414

15-
# The ipc_level_zero_prov test requires using pidfd_getfd(2)
16-
# to obtain a duplicate of another process's file descriptor.
17-
# Permission to duplicate another process's file descriptor
18-
# is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
19-
# that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
20-
PTRACE_SCOPE_FILE="/proc/sys/kernel/yama/ptrace_scope"
21-
VAL=0
22-
if [ -f $PTRACE_SCOPE_FILE ]; then
23-
PTRACE_SCOPE_VAL=$(cat $PTRACE_SCOPE_FILE)
24-
if [ $PTRACE_SCOPE_VAL -ne $VAL ]; then
25-
echo "SKIP: ptrace_scope is not set to 0 (classic ptrace permissions) - skipping the test"
26-
exit 125 # skip code defined in CMakeLists.txt
27-
fi
28-
fi
29-
3015
UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"
3116

3217
echo "Starting ipc_level_zero_prov CONSUMER on port $PORT ..."

0 commit comments

Comments
 (0)