Skip to content

Commit 56132aa

Browse files
committed
smsc/cma: Add a check for CAP_SYS_PTRACE between processes
* If you run in an environment (e.g., container) where the `CAP_SYS_PTRACE` capability is not provided then the two processes will not be able to use `process_vm_readv`/`process_vm_writev` even if all of the other checks currently in the code pass. The result is errors when trying to call one of these two functions which is difficult for the called (i.e., `btl/sm`) to recover from. * Use the `kcmp` system call as a proxy for the `process_vm_readv`/`process_vm_writev` functions. `kcmp` is a lightweight check in the kernel and is sufficient to detect if the two processes have the necessary capabilities. * Refs * Capabilities : https://man7.org/linux/man-pages/man7/capabilities.7.html * `kcmp` : https://man7.org/linux/man-pages/man2/kcmp.2.html Signed-off-by: Joshua Hursey <[email protected]>
1 parent 31d719d commit 56132aa

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

config/opal_check_cma.m4

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# of Tennessee Research Foundation. All rights
55
# reserved.
66
# Copyright (c) 2009-2016 Cisco Systems, Inc. All rights reserved.
7-
# Copyright (c) 2010-2012 IBM Corporation. All rights reserved.
7+
# Copyright (c) 2010-2022 IBM Corporation. All rights reserved.
88
# Copyright (c) 2013-2016 Los Alamos National Security, LLC. All rights
99
# reserved.
1010
# Copyright (c) 2022 Amazon.com, Inc. or its affiliates. All Rights reserved.
@@ -130,6 +130,25 @@ static void do_check (pid_t pid, int *in, int *out)
130130

131131
OPAL_VAR_SCOPE_POP
132132

133+
# Testing CAP_SYS_PTRACE between two processes with kcmp
134+
AC_CHECK_HEADERS([linux/kcmp.h])
135+
AC_CHECK_HEADERS([sys/syscall.h])
136+
AC_MSG_CHECKING([if kcmp works])
137+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
138+
#include <linux/kcmp.h>
139+
#include <sys/syscall.h>
140+
#include <unistd.h>
141+
]], [[
142+
syscall(SYS_kcmp, 123, 456, KCMP_VM, 0, 0);
143+
]])],
144+
[AC_MSG_RESULT([yes])
145+
opal_check_cma_kcmp_happy=1],
146+
[AC_MSG_RESULT([no])
147+
opal_check_cma_kcmp_happy=0])
148+
AC_DEFINE_UNQUOTED([OPAL_CMA_KCMP_AVAIL],
149+
[$opal_check_cma_kcmp_happy],
150+
[If kcmp is available])
151+
133152
AS_IF([test $opal_check_cma_happy -eq 1],
134153
[opal_check_cma_msg=yes],
135154
[opal_check_cma_msg=no])

opal/mca/smsc/cma/smsc_cma_module.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* of Tennessee Research Foundation. All rights
99
* reserved.
1010
* Copyright (c) 2021 Google, Inc. All rights reserved.
11+
* Copyright (c) 2022 IBM Corporation. All rights reserved.
1112
* $COPYRIGHT$
1213
*
1314
* Additional copyrights may follow
@@ -20,6 +21,13 @@
2021
#include "opal/mca/smsc/base/base.h"
2122
#include "opal/mca/smsc/cma/smsc_cma_internal.h"
2223

24+
#if HAVE_LINUX_KCMP_H
25+
# include <linux/kcmp.h> /* kcmp: Definition of KCMP_* constants */
26+
#endif /* HAVE_LINUX_KCMP_H */
27+
#if HAVE_SYS_SYSCALL_H
28+
# include <sys/syscall.h> /* kcmp: Definition of SYS_* constants */
29+
#endif /* HAVE_SYS_SYSCALL_H */
30+
2331
#if OPAL_CMA_NEED_SYSCALL_DEFS
2432
# include "opal/sys/cma.h"
2533
#else
@@ -58,6 +66,26 @@ mca_smsc_endpoint_t *mca_smsc_cma_get_endpoint(opal_proc_t *peer_proc)
5866
return NULL;
5967
}
6068

69+
#if OPAL_CMA_KCMP_AVAIL
70+
/* Check if CAP_SYS_PTRACE capability is allowed between these two processes
71+
* Calling process_vm_readv/writev requires CAP_SYS_PTRACE. We can use kcmp
72+
* to check if these two processes share a kernel resource. Since kcmp
73+
* also requires CAP_SYS_PTRACE it is a good proxy for process_vm_readv/writev.
74+
*/
75+
rc = syscall(SYS_kcmp, getpid(), modex->pid, KCMP_VM, 0, 0);
76+
if(rc < 0) {
77+
opal_output_verbose(MCA_BASE_VERBOSE_ERROR, opal_smsc_base_framework.framework_output,
78+
"mca_smsc_cma_module_get_endpoint: can not proceed. processes do not have "
79+
"the necessary permissions (i.e., CAP_SYS_PTRACE). "
80+
"PID %d <-> %d (rc = %d) (errno: %d: %s)",
81+
getpid(), modex->pid, rc, errno, strerror(errno));
82+
/* can't use CMA with this peer */
83+
OBJ_RELEASE(endpoint);
84+
free(modex);
85+
return NULL;
86+
}
87+
#endif /* OPAL_CMA_KCMP_AVAIL */
88+
6189
endpoint->pid = modex->pid;
6290
return &endpoint->super;
6391
}

0 commit comments

Comments
 (0)