permission denied for ptrace under GDB

6,183

I don't think the permission denied is necessarily talking about the traditional permissions bits (rwx..), rather I'd be suspicious of something like SELinux or AppArmor which might be denying your process access.

I do not have access to a ArchLinux system but there is something similar under Fedora that is discussed here in this Fedora Wiki topic: Features/SELinuxDenyPtrace.

Here they're blocking access to ptrace through SELinux, so you might want to try disabling either SELinux or AppArmor is ArchLinux happens to be using either.

What your attempting worked for me

I tried you code on my Fedora 19 system and other than needing to install some addtional debuginfo RPMs it worked as you'd expect it to.

Example

Compiled your code.

$ gcc -g test.c 

Ran the resulting binary in gdb.

$ gdb a.out 
GNU gdb (GDB) Fedora 7.6.1-46.fc19
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/saml/tst/106912/a.out...done.
(gdb) break main
Breakpoint 1 at 0x40053f: file test.c, line 4.
(gdb) run
Starting program: /home/saml/tst/106912/a.out 

Breakpoint 1, main (argc=1, argv=0x7fffffffd698) at test.c:4
4       printf("1\n");
Missing separate debuginfos, use: debuginfo-install glibc-2.17-20.fc19.x86_64
(gdb) quit
A debugging session is active.

    Inferior 1 [process 13341] will be killed.

Quit anyway? (y or n) y

The debugger complained that I was missing the debuginfos for glibc so I installed them.

$ sudo debuginfo-install glibc-2.17-20.fc19.x86_64

Now when I re-run gdb.

$ gdb a.out 
GNU gdb (GDB) Fedora 7.6.1-46.fc19
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/saml/tst/106912/a.out...done.
(gdb) break main
Breakpoint 1 at 0x40053f: file test.c, line 4.
(gdb) run
Starting program: /home/saml/tst/106912/a.out 

Breakpoint 1, main (argc=1, argv=0x7fffffffd698) at test.c:4
4       printf("1\n");
(gdb) 
Share:
6,183

Related videos on Youtube

Idan Arye
Author by

Idan Arye

Updated on September 18, 2022

Comments

  • Idan Arye
    Idan Arye almost 2 years

    I have set a super simple C program and compiled it with GCC (with the -g flag). I've tried running it with gdb a.out, set a breakpoint on main and run it, but GDB ignored my breakpoint and simply ran the entire program nonstop.

    On my questions in SO they told me to run it with strace and grep for failed calls to ptrace. I did so and got:

    5765 ptrace(PTRACE_TRACEME, 0, 0, 0) = -1 EPERM (Operation not permitted)
    

    When I'm trying to run gdb with sudo it works fine, so it's definitely a permissions problem. I've also tried reinstalling GDB, hoping it'll re-set the permissions, but it didn't help. Here are the groups and permissions for GDB and for the executable I'm trying to debug:

    -rwxr-xr-x 1 idanarye users 7797 Dec 28 04:52 ./a.out
    -rwxr-xr-x 1 root root 5206304 Aug 31 07:10 /usr/bin/gdb
    

    I tried googling for this problem, but all I could find is another problem where GDB fails to attach to running processes due a to a new security rule that prevents ptracing another process unless it's a child process. This is not the problem here, since I let GDB start the process I want to debug. I've tried the suggested solution(changing /proc/sys/kernel/yama/ptrace_scope) anyways and it didn't work.

    What am I missing here? What permissions do I need to give and to what?

    I'm running a 64bit ArchLinux.

    UPDATE

    No idea how or why, but it works now. Probably a system update fixed it...

  • Idan Arye
    Idan Arye over 10 years
    I have neither SELinux nor AppArmor installed. Any other softwares like them?
  • Idan Arye
    Idan Arye over 10 years
    ArchLinux comes with neither preinstalled and offers both in it's repository. My machine doesn't have them. Anyways, here is the strace output: pastebin.com/Bzxbe8qn
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @Idan Arye By searching through the Linux source code, I found 4 LSM (Linux Security Modules) that appear to register any interest in ptrace_traceme. These are AppArmor, SELinux, Smack and "Yama".
  • Idan Arye
    Idan Arye over 10 years
    Well, I don't seem to have any of those installed...
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @slm I personally recommended to OP using strace -f -o syscall.txt gdb ./a.out on the original SO thread.
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @slm As for the strace of fork system calls: At line 192, gdb with PID 5757 forks out PID 5758 and immediately execs iconv, which exits by line 289. Much later, at line 1681, gdb forks out PID 5765. This new PID first calls getpid() = 5765 twice and second setpgid(5765, 5765). Thirdly it runs the failed ptrace call: ptrace(PTRACE_TRACEME, 0, 0, 0) = -1 EPERM (Operation not permitted). It then execs a.out. We know for sure that the "problem" has crystallized before the PTRACE_TRACEME request, which should not have failed.
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @IdanArye What, precisely, is your kernel version? (uname -a) So far I've only looked at the source of kernel 3.12.
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @slm Can you post up your strace log? I'm especially interested in what happens at ptrace(PTRACE_TRACEME, 0, 0, 0).
  • Idan Arye
    Idan Arye over 10 years
    @IwillnotexistIdonotexist Linux idanarye_lg 3.12.2-1-ARCH #1 SMP PREEMPT Fri Nov 29 21:14:15 CET 2013 x86_64 GNU/Linux. Thanks!
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @slm The ptrace(PTRACE_TRACEME, ...) syscall is executed in the child, not in gdb. For that reason the -f flag is needed to have strace follow into the children spawned by gdb. But now I realize that if strace is ptraceing gdb and its children, then the call to ptrace(PTRACE_TRACEME, ...) in the child will fail, because the kernel reports EPERM if the process is already being traced. So we're back to square one.
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @IdanArye Are you sure that you don't have AppArmor, TOMOYO or Yama enabled in the kernel? Because according to this config file, trunk Arch Linux enables those, but it doesn't enable Smack or SELinux.
  • Idan Arye
    Idan Arye over 10 years
    @IwillnotexistIdonotexist Apperantly I do have Yama. The package manager won't display it, nor there is there a Yama package, so it must be built-in, because I have the folder /proc/sys/kernel/yama. @slm I've already tried that solution and it didn't work. I'm not trying to attach to a process - I fail when I let GDB spawn the process.
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @slm The second link occurs on attaching to the process, whereas in this case GDB is the parent process. The third link is the mistake I just realized I did - you can't simultaneously strace and debug GDB's children.
  • Idan Arye
    Idan Arye over 10 years
    @slm pgrep -f strace yields nothing. Also, the problem in that link was encountered when attaching to a running process, which is not the case here.
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @IdanArye How willing would you be to compile your own GDB, with printf()'s in particular locations within its source code? In gdb-7.6.2/gdb/fork-child.c, the function fork_inferior() is the one that forks off and executes the child. Other thing we should try is to produce a SSCCE (short self-contained compilable example) which forks itself, calls setpgid(getpid(), getpid()), then ptrace(PTRACE_TRACEME, 0, 0, 0) and printf() ptrace's return code, then execve's /bin/bash -c exec ./a.out, because that's what GDB does.
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @slm Can you create one of those chat rooms where we can talk about this? We'd inject our comments so far there.
  • slm
    slm over 10 years
  • Iwillnotexist Idonotexist
    Iwillnotexist Idonotexist over 10 years
    @slm I'm done pasting out the comments under here to the chat room. Too bad the chat-room doesn't have a monospace font.
  • slm
    slm over 10 years
    @IwillnotexistIdonotexist - it does, you have to up arrow after you've posted and then the button should show up saying fixed width. Also you can mark the text similar to posts using single ticks, I believe