Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 341889 - sys-devel/gdb-7.2 ignores hardware breakpoints and provides no symbolic bt on amd64 hardened
Summary: sys-devel/gdb-7.2 ignores hardware breakpoints and provides no symbolic bt on...
Status: CONFIRMED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Hardened (show other bugs)
Hardware: AMD64 Linux
: High normal (vote)
Assignee: The Gentoo Linux Hardened Team
URL: http://sourceware.org/bugzilla/show_b...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-20 11:53 UTC by Hugo Mildenberger
Modified: 2010-10-26 12:25 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hugo Mildenberger 2010-10-20 11:53:20 UTC
Blueness opted to close BUG #265693 although the very same problems persist in gdb-7.2:

1.) gdb does not use Hardware-breakpoints before the target is run, although gdb is actually able to do so if the target program was stopped due to a signal. 

2.) With PaX RANDMAP enabled, a symbolic backtrace in unavaiable.

http://sourceware.org/bugzilla/show_bug.cgi?id=11440, although addressing a valgrind problem with PIE binaries gives a clue to problem number two:
gdb reads /proc/<pid>/auxv to determine base addresses. But on hardened, this file is empty if running a binary with RANDMAP enabled. Content re-appears when using paxctl -r. As a final proof of concept, I commented the following section from proc_pid_auxv() in linux-2.6.35-hardened-r2/fs/base.c:

 313 #if 0
 314 #ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
 315   if (PAX_RAND_FLAGS(mm)) {
 316    mmput(mm);
 317    return res;
 318   }
 319 #endif
 320 #endif

Recompiling the kernel then "solved" problem number two.  

CONFIG_GRKERNSEC_PROC_MEMMAP is probably enabled on most hardened installations,
because the help text for "[*] Remove addresses from /proc/<pid>/[smaps|maps|stat]" says:

CONFIG_GRKERNSEC_PROC_MEMMAP:                                                                                            │ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will                                                │ give no information about the addresses of its mappings if                                                              
│ PaX features that rely on random addresses are enabled on the task.                                                    │   
│ If you use PaX it is greatly recommended that you say Y here as it                                                       
│ closes up a hole that makes the full ASLR useless for suid                                                             │ binaries.

Clearly, this is a conflict of objectives, and I've currently no idea how to solve the antagonism while using gdb to analyse a running program. 

Problem number one is still present, as it is associated with some confusion in gdb's internal target "Local exec file". I already demonstrated that within comment 13 to bug #265693.  
  
Fixing these two problems would not only spare the need of running paxctl -mr on any target, but also make gdb again usable for just-in-time debugging.
Comment 1 Hugo Mildenberger 2010-10-20 17:03:38 UTC
Good news regarding the /proc/<pid>/auxv problem. Spender said on http://forums.grsecurity.net/viewtopic.php?f=1&t=2467 :

  I'll update the restriction for this so that it's readable 
  only if the task is currently being ptraced and only by 
  the task doing the ptracing.
Comment 2 Anthony Basile gentoo-dev 2010-10-25 19:24:39 UTC
Using the test code from bug #265693#c13, one obtains the exact same results on amd64 nnone hardened gentoo, on unbuntu 10.04 (which uses gdb-7.1) and ubuntu10.10 (which uses gdb-7.2).   The reuslts for the later are below.  Basically you cannot set hardware breakpoints until after the process is started:

basile@carlson-desktop:~/265693$ gdb ./gtest 
GNU gdb (GDB) 7.2-ubuntu
Copyright (C) 2010 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-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/basile/265693/gtest...done.
(gdb) hbreak function_1
No hardware breakpoint support in the target.
(gdb) run 
Starting program: /home/basile/265693/gtest 

Program received signal SIGINT, Interrupt.
0x00007ffff7a8cba5 in raise () from /lib/libc.so.6
(gdb) hbreak function_1
Hardware assisted breakpoint 1 at 0x400548: file gtest.c, line 4.
(gdb) cont
Continuing.

Breakpoint 1, function_1 () at gtest.c:4
4	        printf("entering %s\n",__PRETTY_FUNCTION__);
(gdb) 
Comment 3 Francisco Blas Izquierdo Riera gentoo-dev 2010-10-25 19:35:36 UTC
Hi,

I'll try to explain what's involved behind hardware breakpoints and why they aren't working right now before executing a program. I'll also point a few limitations which are good to know.

On x86 (and amd64) Hardware breakpoints basically work by modifying the Dr registers, this means that we can have as much 4 breakpoints, amongst other restrictions, and only can turn them on once the program has started running.

Ok, now is when you say, then why don't modify them betwen the fork and exec calls. Because the exec call may reset those registers son the breakpoints would disappear.

Now comes the part on how to use them. Basically what's needed is storing the hardware breakpoint in the same way as software breakpoints work. IIRC correctly, what is done is put a pending signal before the exec on the child so all of them can be properly set on load and just after the exec call ends. So all we need is add a hook to read the stored breakpoints and set the registers as we do when the program is already running.
Comment 4 Hugo Mildenberger 2010-10-26 12:25:08 UTC
(In reply to comment #3)
> Hi,
> 
> I'll try to explain what's involved behind hardware breakpoints and why they
> aren't working right now before executing a program. I'll also point a few
> limitations which are good to know.
> 
> On x86 (and amd64) Hardware breakpoints basically work by modifying the Dr
> registers, this means that we can have as much 4 breakpoints, amongst other
> restrictions, and only can turn them on once the program has started running.
> 
> Ok, now is when you say, then why don't modify them betwen the fork and exec
> calls. Because the exec call may reset those registers son the breakpoints
> would disappear.
> 
> Now comes the part on how to use them. Basically what's needed is storing the
> hardware breakpoint in the same way as software breakpoints work. IIRC
> correctly, what is done is put a pending signal before the exec on the child so
> all of them can be properly set on load and just after the exec call ends. So
> all we need is add a hook to read the stored breakpoints and set the registers
> as we do when the program is already running.
> 

Some remarks: when applying that ugly hack I described in comment 13 to BUG  #265693, gdb is fully able to use hw breakpoints right from start if the "hbreak" command is used. The "break" command still tries to modify code and therefore fails. From what I've seen in gdb's sources, this behaviour differs from remote targets, where gdb tries to use hardware breakpoints first.  

There is another interesting inconsistency: gdb's "watch" command silently uses the hardware debug registers, while complaining about no hardware support when trying to use "hbreak".

--- 

The PaX induced problem regarding randmap had been fixed with grsecurity-2.2.0-2.6.35.7-201010201740.patch; thus paxctl -r is not needed any more and gdb-based just-in-time debuggers like drkonqi are finally working on also on hardened platforms.