Як вирішити “операцію ptrace не дозволено” при спробі приєднати GDB до процесу?


80

Я намагаюся підключити програму за допомогою gdb, але вона повертає:

Приєднання до процесу 29139
Не вдалося долучити до процесу. Якщо ваш uid відповідає uid цільового процесу, перевірте налаштування / proc / sys / kernel / yama / ptrace_scope або спробуйте ще раз як кореневий користувач. Детальніше див. У
/etc/sysctl.d/10-ptrace.conf ptrace: Операція не дозволена.

gdb-debugger повертає "Не вдалося підключити до процесу, перевірте привілеї та повторіть спробу."

strace повертає "attach: ptrace (PTRACE_ATTACH, ...): Операція не дозволена"

Я змінив "kernel.yama.ptrace_scope" 1 на 0 і /proc/sys/kernel/yama/ptrace_scope1 на 0 і спробував set environment LD_PRELOAD=./ptrace.soз цим:

Але це все одно повертає ту саму помилку. Як я можу приєднати його до налагоджувачів?

Відповіді:


178

Якщо ви використовуєте Docker, вам, ймовірно, знадобляться такі параметри:


53
Навіть якщо питання не стосувалося Докера, я потрапив сюди через це. Це вирішено для мене і дякую, що вийшли за межі питання.
Perennialista

Це працювало для мене під управлінням GCC 8.2 та GDB 8.1 у Docker
ThetaSinner

1
як я можу це зробити, коли будую докер, а не запускаю? здається, не приймає цих аргументів? (у мене є дивна помилка, яка трапляється лише при використанні файлу Docker)
fersarr

3
У docker-compose.yml мені просто довелося додати cap_add: - SYS_PTRACE(з новим рядком після двокрапки) у моїй специфікації контейнера.
Рафал Г.

1
У новішій версії Docker 18+ --security-opt seccomp=unconfinedбільше не потрібен.
BZ

63

Це пов'язано із затвердінням ядра в Linux; Ви можете вимкнути цю поведінку echo 0 > /proc/sys/kernel/yama/ptrace_scope, змінивши її в/etc/sysctl.d/10-ptrace.conf

Див. Також цю статтю про це у Fedora 22 (із посиланнями на документацію) та цю тему коментарів щодо Ubuntu та.


3
echo ...Чи працювати тільки в моєму випадку , якщо я відкрив кореневої консоль спочатку sudo -i( sudo echo ...не зробив роботу з - за символу перенаправлення)
¨R Yoda

Деякі конструкції оболонки досить складно використовувати в аргументах для таких команд, як sudo.
jesup

17
Під час використання sudo та перенаправлення ви можете використовуватиecho 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
Daniel Serodio

13

Я хотів би додати, що мені потрібні --security-opt apparmor=unconfinedбули параметри, про які згадав @wisbucky. Це було в Ubuntu 18.04 (як клієнт Docker, так і хост). Отже, повний виклик для увімкнення налагодження gdb всередині контейнера:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined


Це не дає відповіді на запитання. Отримавши достатню репутацію, ви зможете коментувати будь-яку публікацію ; натомість надайте відповіді, які не вимагають роз’яснень від запитувача . - З огляду
Рафаель

2
@Rafael відповідь оновлена ​​за допомогою повного командного рядка. Зараз він дає повністю самодостатню відповідь на запитання.
Juraj Oršulić,

11

Я не дуже звертався до вищезазначеного випадку використання, але у мене була така проблема:

Проблема : Бувало, що я запускав свою програму sudo, тому при запуску gdb це дало мені ptrace: Operation not permitted.

Рішення :sudo gdb ...


1
Але зверніть увагу, що sudo gdbце також не буде працювати, якщо echo 3 | sudo tee /proc/sys/kernel/yama/ptrace_scope( kernel.org/doc/Documentation/security/Yama.txt ), і ваші .gdbinitсценарії не відображатимуться .
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3

Відповідь Джесупа правильна; це пов'язано із затвердінням ядра Linux. У моєму випадку я використовую Docker Community для Mac, і для того, щоб змінити прапор, я повинен увійти до оболонки LinuxKit, використовуючи nsenter Джастіна Кормака (посилання: https://www.bretfisher.com/docker-for-mac-commands -для потрапляння в-local-docker-vm / ).

docker run -it --rm --privileged --pid=host justincormack/nsenter1

/ # cat / etc / issue

Ласкаво просимо до LinuxKit

/ # cat / proc / sys / kernel / yama / ptrace_scope

1

/ # echo 0> / proc / sys / kernel / yama / ptrace_scope

/ # вихід


2

Можливо, хтось приєднав цей процес до gdb.

  • ps -ef | grep gdb

не вдається gdb приєднати один і той же процес двічі.


2

Я запускав свій код із вищими привілеями для роботи з Ethernet Raw Sockets, встановивши команду set capability у розподілі Debian. Я спробував наведене вище рішення: echo 0 > /proc/sys/kernel/yama/ptrace_scope або змінивши його, /etc/sysctl.d/10-ptrace.confале це не допомогло мені.

Крім того, я також спробував з набір можливостей команди для GDB у встановленій директорії (USR / бен / GDB) , і вона працює: /sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb. Обов’язково виконайте цю команду з правами root.


2

Просто хочу наголосити на відповідній відповіді . Скажімо, ви кореневі і зробили:

і отримати:

Перевірка:

Якщо ви бачите щось на зразок TracerPid: 12, тобто не нульове значення, це PID програми, яка вже використовує системний виклик ptrace . Як gdbі straceвикористовувати його, і може бути тільки один активний на один раз.


1

Якщо дозволи є проблемою, ви, мабуть, захочете використовувати gdbserver. (Я майже завжди використовую gdbserver, коли використовую gdb, docker чи ні, з багатьох причин.) Вам знадобиться gdbserver (Deb) або gdb-gdbserver (RH), встановлений в образі докера. Запустіть програму в docker з

(виберіть номер порту, 1025-65535). Потім у gdb на хості скажіть

де 172.17.0.4IP-адреса образу докера, як повідомляється /sbin/ip addr listзапуском у образі докера. Це кріпиться в точці перед mainзапуском. Ви можете tb mainі cзупинитися на mainабо де завгодно. Запустіть gdb під cgdb, emacs, vim, або навіть в якійсь IDE, або просто. Ви можете запустити gdb у своєму джерелі або побудувати дерево, щоб воно знало, де все знаходиться. (Якщо він не може знайти ваші джерела, скористайтеся dirкомандою.) Зазвичай це набагато краще, ніж запустити його в образі докера.

gdbserver покладається ptrace, тому вам також потрібно буде виконати інші дії, запропоновані вище. --privileged --pid=hostмені вистачало.

Якщо ви розгортаєтеся в інших ОС або вбудованих цілях, ви можете запустити там gdbserver або gdb-заглушку і запускати gdb таким же чином, підключаючись через реальну мережу або навіть через послідовний порт ( /dev/ttyS0).


1

Я збирався відповісти на це старе запитання, оскільки воно не приймається, і будь-які інші відповіді не зрозумілі. Справжня відповідь може бути вже написана, /etc/sysctl.d/10-ptrace.confяк це є в моєму випадку під Ubuntu. Цей файл говорить:

Для програм, що запускають обробники збоїв, які потребують PTRACE, налагоджувач може зареєструвати винятки, вказавши в обробнику segfault конкретно, який процес буде використовувати PTRACE на налагоджувачеві: prctl (PR_SET_PTRACER, debugger_pid, 0, 0, 0);

Тож просто виконайте те саме, що і вище: збережіть /proc/sys/kernel/yama/ptrace_scopeяк 1 і додайте prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);в налагоджувач. Тоді налагоджувач дозволить налагоджувачу його налагоджувати. Це працює sudoбез перезавантаження та без.

Зазвичай налагоджувачеві також потрібно зателефонувати, waitpidщоб уникнути виходу після аварії, щоб налагоджувач міг знайти pid відладчика.


0

Я не знаю, що ви робите з LD_PRELOAD або функцією ptrace.

Чому б вам не спробувати приєднати gdb до дуже простої програми? Створіть програму, яка просто неодноразово друкує Hello або щось інше, і використовуйте gdb --pid [привіт програма PID], щоб приєднати до неї.

Якщо це не спрацює, тоді у вас дійсно є проблема.

Інша проблема - це ідентифікатор користувача. Чи програма, яку ви відстежуєте, встановлює себе на інший UID? Якщо це так, то ви не зможете простежити його, якщо не використовуєте той самий ідентифікатор користувача або не є root.


він додає прості програми, але я намагаюся вкласти файл crackme. він має захист від налагодження , як це .
user2850750

@ user2850750: Я додав ще один біт до відповіді.
Zan Lynx

я пробую це як корінь
user2850750

@ user2850750: Добре. Тоді, чи можливо, що gdb якось викликає функцію ptrace у вашому спільному об’єкті? Якщо ви запускаєте gdb у програмі hello world із вашим об'єктом попереднього завантаження, він також не вдається?
Zan Lynx

0

Я зіткнувся з тією ж проблемою і спробую багато рішень, але, нарешті, я знайшов рішення, але насправді я не знаю, в чому була проблема. Спочатку я змінив значення ptrace_conf та увійшов до Ubuntu як корінь, але проблема все ще з'являється. Але найдивніше, що трапилось, - це те, що gdb показав мені повідомлення, яке говорить:

Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user.
For more details, see /etc/sysctl.d/10-ptrace.conf warning: process 3767 is already traced by process 3755 ptrace: Operation not permitted.

За допомогою командного терміналу ps процес 3755 не був перелічений.

Я знайшов процес 3755 у / proc / $ pid, але я не розумію, що це було !!

Нарешті, я видалив цільовий файл (foo.c), який намагаюся приєднати до програми vid gdb і tracer c, використовуючи системний виклик PTRACE_ATTACH, а в іншій папці створив іншу програму c та скомпілював її.

проблема вирішена, і мені було дозволено підключатись до іншого процесу за допомогою gdb або ptrace_attach syscall.

(gdb) attach 4416

Attaching to process 4416

і я відправляю багато сигналів на обробку 4416. Я перевірив це як з gdb, так і з ptrace, обидва вони працюють правильно.

дійсно я не знаю проблему, що було, але я думаю, що це не помилка в Ubuntu, оскільки на неї посилаються багато сайтів, наприклад /ubuntu/143561/why-wont-strace- gdb-attach-to-a-process-even-хотя-im-root


0

Додаткова інформація

Якщо ви хочете внести зміни в інтерфейси, наприклад, додати мост ovs, ви повинні використовувати --privilegedзамість --cap-add NET_ADMIN.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.