[1/2] Add contrib/sudo-allow-ptrace.sh
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
fail
|
Testing failed
|
Commit Message
Some linux systems have the setting kernel.yama.ptrace_scope set to 1 or 2.
This limits the ability to attach to processes, for security reasons.
However, this can get in the way of for instance:
- debugging an application, and
- running certain test-cases in the gdb testsuite.
This can be worked around by setting kernel.yama.ptrace_scope to 0, either:
- temporarily (until the next reboot), using:
- "echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope", or
- "sudo sysctl -w kernel.yama.ptrace_scope=0",
- or permanently, by editing /etc/sysctl.conf or adding a file to
/etc/sysctl.d.
However, it may be the case that setting kernel.yama.ptrace_scope to 0 is not
desirable, for instance when trying to debug an application on a production
system.
Another way of working around this is by running as root, but this may be
undesirable as well.
Here ( https://wiki.archlinux.org/title/Capabilities ) it's demonstrated how
to run gdb while temporarily adding the CAP_SYS_PTRACE capability using capsh.
I tried out this approach on the test-suite, and found that while capsh uses
"--user $USER", some things are different from being $USER:
- $HOME is /root, not /home/$USER
- USER and LOGNAME are root
- ulimit -c is 0, even though I set it to unlimited in /home/$USER/.bashrc.
Add a convenience script gdb/contrib/sudo-allow-ptrace.sh that takes care of
these differences.
With the script, I'm able to run the test-suite as usual on a
kernel.yama.ptrace_scope=1/2 system.
There's only one regression compared to kernel.yama.ptrace_scope=0, in
gdb.base/attach-deleted-exec.exp, which is filed as PR gdb/31528. A following
patch deals with this.
Tested and shell-checked on x86_64-linux.
PR external/31520
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31520
---
gdb/contrib/sudo-allow-ptrace.sh | 110 +++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
create mode 100755 gdb/contrib/sudo-allow-ptrace.sh
base-commit: 61ced226a4fc2e6df7836cd9c0f7e1ad47af2440
new file mode 100755
@@ -0,0 +1,110 @@
+#!/bin/sh
+
+# Copyright (C) 2024 Free Software Foundation, Inc.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This script intends to facilitate using gdb to attach to processes
+# on a kernel.yama.ptrace_scope=1 system, without changing the setting and
+# without becoming root.
+#
+# Example usage (running the gdb testsuite):
+# $ cd build/gdb/testsuite
+# $ sudo-allow-ptrace.sh make check
+#
+# Example usage (using gdb to attach to process):
+# $ sudo-allow-ptrace.sh gdb -p <pid>
+#
+# The script is based on this [1] recipe.
+#
+# [1] https://wiki.archlinux.org/title/Capabilities.
+
+set -e
+
+case " $1 " in
+ " --stage2 ")
+ stage=2
+ shift
+ ;;
+
+ " --stage3 ")
+ stage=3
+ shift
+ ;;
+
+ *)
+ stage=1
+ ;;
+esac
+
+if [ $stage = 1 ]; then
+ # STAGE 1, as user $USER.
+
+ # shellcheck disable=SC3045
+ ulimit_core_hard=$(ulimit -Hc)
+ # shellcheck disable=SC3045
+ ulimit_core_soft=$(ulimit -Sc)
+
+ exec \
+ sudo -E \
+ "$0" \
+ --stage2 \
+ "$USER" \
+ "$HOME" \
+ "$ulimit_core_hard" \
+ "$ulimit_core_soft" \
+ "$@"
+elif [ $stage = 2 ]; then
+ # STAGE 2, as user root.
+
+ export user="$1"
+ shift
+
+ export home="$1"
+ shift
+
+ ulimit_core_hard="$1"
+ shift
+
+ ulimit_core_soft="$1"
+ shift
+
+ # shellcheck disable=SC3045
+ ulimit -Hc "$ulimit_core_hard"
+ # shellcheck disable=SC3045
+ ulimit -Sc "$ulimit_core_soft"
+
+ exec \
+ capsh \
+ --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_sys_ptrace+eip" \
+ --keep=1 \
+ --user="$user" \
+ --addamb="cap_sys_ptrace" \
+ --shell="$0" \
+ -- \
+ --stage3 \
+ "$user" \
+ "$home" \
+ "$@"
+elif [ $stage = 3 ]; then
+ # STAGE 3, as user root with "assumed identity" $USER.
+
+ export USER="$1"
+ export LOGNAME="$1"
+ shift
+
+ export HOME="$1"
+ shift
+
+ exec "$@"
+fi