Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [patch] Disable child VMA randomizations
@ 2008-06-07 19:54 Jan Kratochvil
  2008-06-07 20:41 ` Andreas Schwab
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Jan Kratochvil @ 2008-06-07 19:54 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 288 bytes --]

Hi,

the processes map their addresses randomly by default.  It can make the
debugging inconvenient as varous addresses are different on each run.

This feature was suggested by Jakub Jelinek.  One can also already wrap whole
GDB by a script calling: setarch `uname -m` -R


Regards,
Jan

[-- Attachment #2: gdb-derandomize.patch --]
[-- Type: text/plain, Size: 12957 bytes --]

2008-06-07  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* configure.ac: Add check for HAVE_PERSONALITY.
	* configure, config.in: Regenerate.
	* fork-child.c: New include <errno.h>.
	[HAVE_PERSONALITY]: New include <sys/personality.h>.
	[HAVE_PERSONALITY] (set_disable_randomization): New function.
	(disable_randomization, show_disable_randomization): New.
	(fork_inferior) [HAVE_PERSONALITY]: Disable randomization upon the
	variable DISABLE_RANDOMIZATION.
	(_initialize_fork_child): Call ADD_SETSHOW_BOOLEAN_CMD for the variable
	DISABLE_RANDOMIZATION.

2008-06-07  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Starting): Document "set disable-randomization".

2008-06-07  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/randomize.exp, gdb.base/randomize.c: New files.

--- gdb/config.in	5 Jun 2008 22:36:56 -0000	1.100
+++ gdb/config.in	7 Jun 2008 18:37:52 -0000
@@ -237,6 +237,9 @@
 /* Define to 1 if you have the <nlist.h> header file. */
 #undef HAVE_NLIST_H
 
+/* Define if you support the personality syscall. */
+#undef HAVE_PERSONALITY
+
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 
--- gdb/configure	5 Jun 2008 22:36:56 -0000	1.249
+++ gdb/configure	7 Jun 2008 18:38:03 -0000
@@ -26702,6 +26702,108 @@ _ACEOF
 fi
 
 
+if test "$cross_compiling" = yes; then
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+#define PERSONALITY_ADDR_NO_RANDOMIZE 0x0040000
+    /* Test the flag could be set and stays set.  */
+    personality (personality (0xffffffff) | PERSONALITY_ADDR_NO_RANDOMIZE);
+    if (!(personality (personality (0xffffffff))
+	  & PERSONALITY_ADDR_NO_RANDOMIZE))
+	return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PERSONALITY 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+#define PERSONALITY_ADDR_NO_RANDOMIZE 0x0040000
+    /* Test the flag could be set and stays set.  */
+    personality (personality (0xffffffff) | PERSONALITY_ADDR_NO_RANDOMIZE);
+    if (!(personality (personality (0xffffffff))
+	  & PERSONALITY_ADDR_NO_RANDOMIZE))
+	return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PERSONALITY 1
+_ACEOF
+
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
 
 # Check whether --with-sysroot or --without-sysroot was given.
 if test "${with_sysroot+set}" = set; then
--- gdb/configure.ac	5 Jun 2008 22:36:56 -0000	1.69
+++ gdb/configure.ac	7 Jun 2008 18:38:04 -0000
@@ -1266,6 +1266,23 @@ if test "x$gdb_cv_sys_syscall_h_has_tkil
   AC_DEFINE(HAVE_TKILL_SYSCALL, 1, [Define if you support the tkill syscall.])
 fi
 
+dnl Check if we can disable the virtual address space randomization.
+dnl The functionality of setarch -R.
+define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include <sys/personality.h>],
+    [#define PERSONALITY_ADDR_NO_RANDOMIZE 0x0040000
+    /* Test the flag could be set and stays set.  */
+    personality (personality (0xffffffff) | PERSONALITY_ADDR_NO_RANDOMIZE);
+    if (!(personality (personality (0xffffffff))
+	  & PERSONALITY_ADDR_NO_RANDOMIZE))
+	return 1])])
+AC_RUN_IFELSE(PERSONALITY_TEST,
+    AC_DEFINE([HAVE_PERSONALITY], 1,
+	      [Define if you support the personality syscall.]),
+    ,
+    AC_LINK_IFELSE(PERSONALITY_TEST,
+	AC_DEFINE([HAVE_PERSONALITY], 1,
+		  [Define if you support the personality syscall.])))
+
 dnl Handle optional features that can be enabled.
 
 AC_ARG_WITH(sysroot,
--- gdb/fork-child.c	15 Mar 2008 14:55:21 -0000	1.41
+++ gdb/fork-child.c	7 Jun 2008 18:38:11 -0000
@@ -35,6 +35,10 @@
 #include "solib.h"
 
 #include <signal.h>
+#include <errno.h>
+#ifdef HAVE_PERSONALITY
+# include <sys/personality.h>
+#endif
 
 /* This just gets used as a default if we can't find SHELL.  */
 #define SHELL_FILE "/bin/sh"
@@ -42,6 +46,34 @@
 extern char **environ;
 
 static char *exec_wrapper;
+static int disable_randomization =
+#ifdef HAVE_PERSONALITY
+				   1;
+#else
+				   0;
+#endif
+
+#ifndef HAVE_PERSONALITY
+static void
+set_disable_randomization (char *args, int from_tty, struct cmd_list_element *c)
+{
+  if (disable_randomization)
+    {
+      disable_randomization = 0;
+      error (_("Unsupported on this platform."));
+    }
+}
+#endif
+
+static void
+show_disable_randomization (struct ui_file *file, int from_tty,
+			    struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+Whether we disable the randomization of the virtual address space of\n\
+a spawned child is %s.\n"),
+		    value);
+}
 
 /* Break up SCRATCH into an argument vector suitable for passing to
    execvp and store it in ARGV.  E.g., on "run a b c d" this routine
@@ -303,6 +335,23 @@ fork_inferior (char *exec_file_arg, char
       if (debug_fork)
 	sleep (debug_fork);
 
+#ifdef HAVE_PERSONALITY
+      if (disable_randomization)
+	{
+# define PERSONALITY_ADDR_NO_RANDOMIZE 0x0040000
+	  int val;
+
+	  errno = 0;
+	  val = personality (0xffffffff);
+	  if (errno == 0)
+	    personality (val | PERSONALITY_ADDR_NO_RANDOMIZE);
+	  if (errno != 0
+	      || !(personality (0xffffffff) & PERSONALITY_ADDR_NO_RANDOMIZE))
+	    warning (_("Currently enabled disable-randomization is unsupported "
+		       "on this platform."));
+	}
+#endif /* HAVE_PERSONALITY */
+
       /* Create a new session for the inferior process, if necessary.
          It will also place the inferior in a separate process group.  */
       if (create_tty_session () <= 0)
@@ -490,4 +539,19 @@ Show the wrapper for running programs.")
   add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command,
            _("Disable use of an execution wrapper."),
            &unsetlist);
+
+  add_setshow_boolean_cmd ("disable-randomization", class_support,
+			   &disable_randomization, _("\
+Set mode for inserting breakpoints."), _("\
+Show mode for inserting breakpoints."), _("\
+When this mode is on (which is the default), the randomization of\n\
+the virtual address space is disabled (turns on ADDR_NO_RANDOMIZE).\n\
+Standalone programs run with the randomization enabled by default."),
+#ifdef HAVE_PERSONALITY
+			   NULL,
+#else
+			   set_disable_randomization,
+#endif
+			   &show_disable_randomization,
+			   &setlist, &showlist);
 }
--- gdb/doc/gdb.texinfo	6 Jun 2008 20:58:08 -0000	1.503
+++ gdb/doc/gdb.texinfo	7 Jun 2008 18:38:48 -0000
@@ -1999,6 +1999,38 @@ environment:
 This command is available when debugging locally on most targets, excluding
 @sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
 
+@kindex set disable-randomization
+@item set disable-randomization
+@itemx set disable-randomization on
+This option (enabled by default in @value{GDBN}) will turn off the native
+randomization of the virtual address space of the started program.  This option
+is useful for multiple debugging sessions to make the execution better
+reproducible and memory addresses reusable across debugging sessions.
+
+This feature is implemented only on @sc{gnu}/Linux.  You can get the same
+behavior using
+
+@smallexample
+(@value{GDBP}) set exec-wrapper setarch `uname -m` -R
+@end smallexample
+
+@item set disable-randomization off
+Leave the behavior of the started executable unchanged.  While the addresses
+get assigned differently on each run some subtle bugs may be reproducible only
+with specially assigned addresses possibly not reachable with the default
+setting of @kbd{set disable-randomization on}.
+
+PIE executables (type @code{ET_DYN}, compiled by @code{gcc -fPIE -pie}) have
+randomized everything - the executable base address, shared libraries base
+address (their prelinking is ignored), mmap areas, stack and heap.  Regular
+executables (type @code{ET_EXEC}) do not have randomized their base address,
+shared libraries base address is ranomized only for non-prelinked libraries,
+mmap, stack and heap are still randomized.
+
+@item show disable-randomization
+Show the current setting of the explicit disable of the native randomization of
+the virtual address space of the started program.
+
 @end table
 
 @node Arguments
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.c	7 Jun 2008 18:38:48 -0000
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008 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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+  void *p;
+
+  p = malloc (1);
+  printf ("address = %p\n", p);
+
+  return 0;
+}
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.exp	7 Jun 2008 18:38:48 -0000
@@ -0,0 +1,63 @@
+# Copyright 2008 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/>.
+
+set testfile randomize
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+proc address_get { testname } {
+    global gdb_prompt
+
+    if {![runto_main]} {
+	return -1
+    }
+    gdb_test_multiple "continue" $testname {
+	-re "address = (0x\[0-9a-f\]*).*Program exited normally..*$gdb_prompt $" {
+	    pass $testname
+	    return $expect_out(1,string)
+	}
+    }
+}
+
+gdb_test "set disable-randomization off"
+set addr1 [address_get "randomized first address"]
+set addr2 [address_get "randomized second address"]
+set test "randomized addresses should not match"
+if {$addr1 eq $addr2} {
+    fail $test
+} else {
+    pass $test
+}
+
+gdb_test "set disable-randomization on"
+set addr1 [address_get "fixed first address"]
+set addr2 [address_get "fixed second address"]
+set test "fixed addresses should match"
+if {$addr1 eq $addr2} {
+    pass $test
+} else {
+    fail $test
+}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-07 19:54 [patch] Disable child VMA randomizations Jan Kratochvil
@ 2008-06-07 20:41 ` Andreas Schwab
  2008-06-08  9:43   ` Jan Kratochvil
  2008-06-07 20:43 ` Eli Zaretskii
  2008-06-08 15:14 ` Mark Kettenis
  2 siblings, 1 reply; 15+ messages in thread
From: Andreas Schwab @ 2008-06-07 20:41 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

Jan Kratochvil <jan.kratochvil@redhat.com> writes:

> +dnl Check if we can disable the virtual address space randomization.
> +dnl The functionality of setarch -R.
> +define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include <sys/personality.h>],
> +    [#define PERSONALITY_ADDR_NO_RANDOMIZE 0x0040000
> +    /* Test the flag could be set and stays set.  */
> +    personality (personality (0xffffffff) | PERSONALITY_ADDR_NO_RANDOMIZE);
> +    if (!(personality (personality (0xffffffff))
> +	  & PERSONALITY_ADDR_NO_RANDOMIZE))
> +	return 1])])
> +AC_RUN_IFELSE(PERSONALITY_TEST,
> +    AC_DEFINE([HAVE_PERSONALITY], 1,
> +	      [Define if you support the personality syscall.]),
> +    ,
> +    AC_LINK_IFELSE(PERSONALITY_TEST,
> +	AC_DEFINE([HAVE_PERSONALITY], 1,
> +		  [Define if you support the personality syscall.])))

This is underquoted.  All arguments containing nested macro invocations
should be quoted.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-07 19:54 [patch] Disable child VMA randomizations Jan Kratochvil
  2008-06-07 20:41 ` Andreas Schwab
@ 2008-06-07 20:43 ` Eli Zaretskii
  2008-06-08 15:14 ` Mark Kettenis
  2 siblings, 0 replies; 15+ messages in thread
From: Eli Zaretskii @ 2008-06-07 20:43 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

> Date: Sat, 7 Jun 2008 21:53:43 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> 
> the processes map their addresses randomly by default.  It can make the
> debugging inconvenient as varous addresses are different on each run.
> 
> This feature was suggested by Jakub Jelinek.  One can also already wrap whole
> GDB by a script calling: setarch `uname -m` -R

Thanks.  I have a few comments.

> +static void
> +show_disable_randomization (struct ui_file *file, int from_tty,
> +			    struct cmd_list_element *c, const char *value)
> +{
> +  fprintf_filtered (file, _("\
> +Whether we disable the randomization of the virtual address space of\n\
> +a spawned child is %s.\n"),
> +		    value);

That longish sentence could be made both shorter and more clear.  How
about this one:

  "Disabling randomization of debuggee's virtual address space is %s."

> +  add_setshow_boolean_cmd ("disable-randomization", class_support,
> +			   &disable_randomization, _("\
> +Set mode for inserting breakpoints."), _("\
> +Show mode for inserting breakpoints."), _("\

"breakpoints"?  Copy/paste error, right?

> +When this mode is on (which is the default), the randomization of\n\
> +the virtual address space is disabled (turns on ADDR_NO_RANDOMIZE).\n\
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
What is this supposed to tell Joe Random Hacker who uses GDB to debug
his/her program?  What is ADDR_NO_RANDOMIZE?

> +Standalone programs run with the randomization enabled by default."),

On some platforms, right?

>                                                       While the addresses
> +get assigned differently on each run some subtle bugs may be reproducible only
> +with specially assigned addresses possibly not reachable with the default
> +setting of @kbd{set disable-randomization on}.

Can you explain this sentence?  I'd like to suggest a better wording,
but I can't do that unless I understand what is it that you are trying
to say here.

> +PIE executables (type @code{ET_DYN}, compiled by @code{gcc -fPIE -pie}) have
> +randomized everything - the executable base address, shared libraries base
> +address (their prelinking is ignored), mmap areas, stack and heap.  Regular
> +executables (type @code{ET_EXEC}) do not have randomized their base address,
> +shared libraries base address is ranomized only for non-prelinked libraries,
> +mmap, stack and heap are still randomized.

There's too much unexplained technical details here, so much so that
this paragraph sounds like it was meant only for the initiated.  What
are ET_DYN and ET_EXEC types? why is prelinking relevant? etc.  Again,
please explain what you are trying to say here, and why it might be
useful for readers of the manual, and I will suggest an alternative
wording.

There are also Texinfo problems in the above: the GCC command should
have the @command markup, not @code; use 3 dashes in a row, as in
"---", to produce a dash, rather than a minus sign, in the manual; and
"ranomized" is a typo.

Other than that, the patch for the manual is okay.  Thanks.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-07 20:41 ` Andreas Schwab
@ 2008-06-08  9:43   ` Jan Kratochvil
  2008-06-08 10:39     ` Eli Zaretskii
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2008-06-08  9:43 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, Andreas Schwab

[-- Attachment #1: Type: text/plain, Size: 4794 bytes --]

On Sat, 07 Jun 2008 22:41:09 +0200, Andreas Schwab wrote:
...
> This is underquoted.  All arguments containing nested macro invocations
> should be quoted.

Fixed, thanks.


On Sat, 07 Jun 2008 22:42:42 +0200, Eli Zaretskii wrote:
...
> That longish sentence could be made both shorter and more clear.  How
> about this one:
> 
>   "Disabling randomization of debuggee's virtual address space is %s."

Used your wording.


> "breakpoints"?  Copy/paste error, right?

Fixed.

+Set disabling of debuggee's virtual address space randomization."), _("\
+Show disabling of debuggee's virtual address space randomization."), _("\


> > +When this mode is on (which is the default), the randomization of\n\
> > +the virtual address space is disabled (turns on ADDR_NO_RANDOMIZE).\n\
>                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
> What is this supposed to tell Joe Random Hacker who uses GDB to debug
> his/her program?  What is ADDR_NO_RANDOMIZE?

ctags will find him /usr/include/linux/personality.h:
        ADDR_NO_RANDOMIZE =     0x0040000,      /* disable randomization of VA space */

Removed my whole text in brackets.


> > +Standalone programs run with the randomization enabled by default."),
> 
> On some platforms, right?

Fixed.

Standalone programs run with the\n\
+randomization enabled by default on the GNU/Linux platform."),


> > +get assigned differently on each run some subtle bugs may be reproducible only
> > +with specially assigned addresses possibly not reachable with the default
> > +setting of @kbd{set disable-randomization on}.
> 
> Can you explain this sentence?  I'd like to suggest a better wording,
> but I can't do that unless I understand what is it that you are trying
> to say here.

New text:

As some debuggee's
+bugs may depend on the assigned addresses the default @value{GDBN} behavior of
+disabling the randomization may make some debuggee's bugs unreproducible.  You
+may want to run the debuggee many times with the randomization enabled (and
+thus this option disabled) to catch such kind of bugs.  Correctly written
+programs must run the same way notwithstanding this configuration option.


I do not know about such a bug example off hand but sure there can be such one
created (such as not expecting \x00 in an adress which would never
coincidentally happen when the randomization is disabled - although 0x00 is
more expected with the randomization disabled as the addresses are then lower).


> > +PIE executables (type @code{ET_DYN}, compiled by @code{gcc -fPIE -pie}) have
> > +randomized everything - the executable base address, shared libraries base
> > +address (their prelinking is ignored), mmap areas, stack and heap.  Regular
> > +executables (type @code{ET_EXEC}) do not have randomized their base address,
> > +shared libraries base address is ranomized only for non-prelinked libraries,
> > +mmap, stack and heap are still randomized.
> 
> There's too much unexplained technical details here, so much so that
> this paragraph sounds like it was meant only for the initiated.

It is mostly explained at:
	http://lwn.net/Articles/190139/

I expected the full explanation is inappropriate for the GDB manual but I tried
to include it in this patch:

+The virtual address space randomization is implemented only on @sc{gnu}/Linux.
+It protects the programs against some kinds of security attacks.  In these
+cases the attacker needs to know the exact location of a concrete executable
+code.  Randomizing its location makes it impossible to inject jumps misusing
+a code at its expected addresses.
+
+Prelinking shared libraries provides a startup performance advantage but it
+makes addresses in these libraries predictable for privileged processes by
+having just unprivileged access at the target system.  Reading the shared
+library binary gives enough information for assembling the malicious code
+misusing it.  Still even a prelinked shared library can get loaded a a new
+random address just requiring the regular relocation process during the
+startup.  Shared libraries not already prelinked are always loaded at
+a randomly chosen address.
+
+Position independent executables (PIE) contain position independent code
+similar to the shared libraries and therefore such executables get loaded at
+a randomly chosen address upon startup.  PIE executables always load even
+already prelinked shared libraries at a random address.  You can build such
+executable using @command{gcc -fPIE -pie}.
+
+Heap (malloc storage), stack and custom mmap areas are always placed randomly
+(as long as the randomization is enabled).


> and "ranomized" is a typo.

Fixed, spell-checked this time.


Thanks for the doc review.

(Patch now additionally prefers the system definition of ADDR_NO_RANDOMIZE.)


Regards,
Jan

[-- Attachment #2: gdb-derandomize2.patch --]
[-- Type: text/plain, Size: 16789 bytes --]

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* configure.ac: Add check for HAVE_PERSONALITY and
	HAVE_DECL_ADDR_NO_RANDOMIZE.
	* configure, config.in: Regenerate.
	* fork-child.c: New include <errno.h>.
	[HAVE_PERSONALITY]: New include <sys/personality.h>.
	[HAVE_PERSONALITY] (set_disable_randomization): New function.
	(disable_randomization, show_disable_randomization): New.
	(fork_inferior) [HAVE_PERSONALITY] [!HAVE_DECL_ADDR_NO_RANDOMIZE]: Set
	ADDR_NO_RANDOMIZE.
	(fork_inferior) [HAVE_PERSONALITY]: Disable randomization upon the
	variable DISABLE_RANDOMIZATION.
	(_initialize_fork_child): Call ADD_SETSHOW_BOOLEAN_CMD for the variable
	DISABLE_RANDOMIZATION.

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Starting): Document "set disable-randomization".

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/randomize.exp, gdb.base/randomize.c: New files.

--- gdb/config.in	5 Jun 2008 22:36:56 -0000	1.100
+++ gdb/config.in	8 Jun 2008 09:11:44 -0000
@@ -82,6 +82,10 @@
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
+/* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if
+   you don't. */
+#undef HAVE_DECL_ADDR_NO_RANDOMIZE
+
 /* Define to 1 if you have the declaration of `free', and to 0 if you don't.
    */
 #undef HAVE_DECL_FREE
@@ -237,6 +241,9 @@
 /* Define to 1 if you have the <nlist.h> header file. */
 #undef HAVE_NLIST_H
 
+/* Define if you support the personality syscall. */
+#undef HAVE_PERSONALITY
+
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 
--- gdb/configure	5 Jun 2008 22:36:56 -0000	1.249
+++ gdb/configure	8 Jun 2008 09:11:56 -0000
@@ -26701,6 +26701,188 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking whether ADDR_NO_RANDOMIZE is declared" >&5
+echo $ECHO_N "checking whether ADDR_NO_RANDOMIZE is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_ADDR_NO_RANDOMIZE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+
+int
+main ()
+{
+#ifndef ADDR_NO_RANDOMIZE
+  char *p = (char *) ADDR_NO_RANDOMIZE;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_have_decl_ADDR_NO_RANDOMIZE=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_ADDR_NO_RANDOMIZE=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&5
+echo "${ECHO_T}$ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&6
+if test $ac_cv_have_decl_ADDR_NO_RANDOMIZE = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 1
+_ACEOF
+
+
+else
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 0
+_ACEOF
+
+
+fi
+
+
+
+if test "$cross_compiling" = yes; then
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_personality=false
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_personality=false
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+if $have_personality
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PERSONALITY 1
+_ACEOF
+
+fi
+
 
 
 # Check whether --with-sysroot or --without-sysroot was given.
--- gdb/configure.ac	5 Jun 2008 22:36:56 -0000	1.69
+++ gdb/configure.ac	8 Jun 2008 09:11:57 -0000
@@ -1266,6 +1266,29 @@ if test "x$gdb_cv_sys_syscall_h_has_tkil
   AC_DEFINE(HAVE_TKILL_SYSCALL, 1, [Define if you support the tkill syscall.])
 fi
 
+dnl Check if we can disable the virtual address space randomization.
+dnl The functionality of setarch -R.
+AC_CHECK_DECLS([ADDR_NO_RANDOMIZE],,, [#include <sys/personality.h>])
+define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include <sys/personality.h>], [
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1])])
+AC_RUN_IFELSE([PERSONALITY_TEST],
+	      [have_personality=true],
+	      [have_personality=false],
+	      [AC_LINK_IFELSE([PERSONALITY_TEST],
+			      [have_personality=true],
+			      [have_personality=false])])
+if $have_personality
+then
+    AC_DEFINE([HAVE_PERSONALITY], 1,
+	      [Define if you support the personality syscall.])
+fi
+
 dnl Handle optional features that can be enabled.
 
 AC_ARG_WITH(sysroot,
--- gdb/fork-child.c	15 Mar 2008 14:55:21 -0000	1.41
+++ gdb/fork-child.c	8 Jun 2008 09:12:05 -0000
@@ -35,6 +35,10 @@
 #include "solib.h"
 
 #include <signal.h>
+#include <errno.h>
+#ifdef HAVE_PERSONALITY
+# include <sys/personality.h>
+#endif
 
 /* This just gets used as a default if we can't find SHELL.  */
 #define SHELL_FILE "/bin/sh"
@@ -42,6 +46,33 @@
 extern char **environ;
 
 static char *exec_wrapper;
+static int disable_randomization =
+#ifdef HAVE_PERSONALITY
+				   1;
+#else
+				   0;
+#endif
+
+#ifndef HAVE_PERSONALITY
+static void
+set_disable_randomization (char *args, int from_tty, struct cmd_list_element *c)
+{
+  if (disable_randomization)
+    {
+      disable_randomization = 0;
+      error (_("Unsupported on this platform."));
+    }
+}
+#endif
+
+static void
+show_disable_randomization (struct ui_file *file, int from_tty,
+			    struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+Disabling randomization of debuggee's virtual address space is %s.\n"),
+		    value);
+}
 
 /* Break up SCRATCH into an argument vector suitable for passing to
    execvp and store it in ARGV.  E.g., on "run a b c d" this routine
@@ -303,6 +334,24 @@ fork_inferior (char *exec_file_arg, char
       if (debug_fork)
 	sleep (debug_fork);
 
+#ifdef HAVE_PERSONALITY
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#  define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+      if (disable_randomization)
+	{
+	  int val;
+
+	  errno = 0;
+	  val = personality (0xffffffff);
+	  if (errno == 0)
+	    personality (val | ADDR_NO_RANDOMIZE);
+	  if (errno != 0 || !(personality (0xffffffff) & ADDR_NO_RANDOMIZE))
+	    warning (_("Currently enabled disable-randomization is unsupported "
+		       "on this platform."));
+	}
+#endif /* HAVE_PERSONALITY */
+
       /* Create a new session for the inferior process, if necessary.
          It will also place the inferior in a separate process group.  */
       if (create_tty_session () <= 0)
@@ -490,4 +539,19 @@ Show the wrapper for running programs.")
   add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command,
            _("Disable use of an execution wrapper."),
            &unsetlist);
+
+  add_setshow_boolean_cmd ("disable-randomization", class_support,
+			   &disable_randomization, _("\
+Set disabling of debuggee's virtual address space randomization."), _("\
+Show disabling of debuggee's virtual address space randomization."), _("\
+When this mode is on (which is the default), the randomization of\n\
+the virtual address space is disabled.  Standalone programs run with the\n\
+randomization enabled by default on the GNU/Linux platform."),
+#ifdef HAVE_PERSONALITY
+			   NULL,
+#else
+			   &set_disable_randomization,
+#endif
+			   &show_disable_randomization,
+			   &setlist, &showlist);
 }
--- gdb/doc/gdb.texinfo	6 Jun 2008 20:58:08 -0000	1.503
+++ gdb/doc/gdb.texinfo	8 Jun 2008 09:12:34 -0000
@@ -1999,6 +1999,57 @@ environment:
 This command is available when debugging locally on most targets, excluding
 @sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
 
+@kindex set disable-randomization
+@item set disable-randomization
+@itemx set disable-randomization on
+This option (enabled by default in @value{GDBN}) will turn off the native
+randomization of the virtual address space of the started program.  This option
+is useful for multiple debugging sessions to make the execution better
+reproducible and memory addresses reusable across debugging sessions.
+
+This feature is implemented only on @sc{gnu}/Linux.  You can get the same
+behavior using
+
+@smallexample
+(@value{GDBP}) set exec-wrapper setarch `uname -m` -R
+@end smallexample
+
+@item set disable-randomization off
+Leave the behavior of the started executable unchanged.  As some debuggee's
+bugs may depend on the assigned addresses the default @value{GDBN} behavior of
+disabling the randomization may make some debuggee's bugs unreproducible.  You
+may want to run the debuggee many times with the randomization enabled (and
+thus this option disabled) to catch such kind of bugs.  Correctly written
+programs must run the same way notwithstanding this configuration option.
+
+The virtual address space randomization is implemented only on @sc{gnu}/Linux.
+It protects the programs against some kinds of security attacks.  In these
+cases the attacker needs to know the exact location of a concrete executable
+code.  Randomizing its location makes it impossible to inject jumps misusing
+a code at its expected addresses.
+
+Prelinking shared libraries provides a startup performance advantage but it
+makes addresses in these libraries predictable for privileged processes by
+having just unprivileged access at the target system.  Reading the shared
+library binary gives enough information for assembling the malicious code
+misusing it.  Still even a prelinked shared library can get loaded a a new
+random address just requiring the regular relocation process during the
+startup.  Shared libraries not already prelinked are always loaded at
+a randomly chosen address.
+
+Position independent executables (PIE) contain position independent code
+similar to the shared libraries and therefore such executables get loaded at
+a randomly chosen address upon startup.  PIE executables always load even
+already prelinked shared libraries at a random address.  You can build such
+executable using @command{gcc -fPIE -pie}.
+
+Heap (malloc storage), stack and custom mmap areas are always placed randomly
+(as long as the randomization is enabled).
+
+@item show disable-randomization
+Show the current setting of the explicit disable of the native randomization of
+the virtual address space of the started program.
+
 @end table
 
 @node Arguments
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.c	8 Jun 2008 09:12:35 -0000
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008 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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+  void *p;
+
+  p = malloc (1);
+  printf ("address = %p\n", p);
+
+  return 0;
+}
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.exp	8 Jun 2008 09:12:35 -0000
@@ -0,0 +1,63 @@
+# Copyright 2008 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/>.
+
+set testfile randomize
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+proc address_get { testname } {
+    global gdb_prompt
+
+    if {![runto_main]} {
+	return -1
+    }
+    gdb_test_multiple "continue" $testname {
+	-re "address = (0x\[0-9a-f\]*).*Program exited normally..*$gdb_prompt $" {
+	    pass $testname
+	    return $expect_out(1,string)
+	}
+    }
+}
+
+gdb_test "set disable-randomization off"
+set addr1 [address_get "randomized first address"]
+set addr2 [address_get "randomized second address"]
+set test "randomized addresses should not match"
+if {$addr1 eq $addr2} {
+    fail $test
+} else {
+    pass $test
+}
+
+gdb_test "set disable-randomization on"
+set addr1 [address_get "fixed first address"]
+set addr2 [address_get "fixed second address"]
+set test "fixed addresses should match"
+if {$addr1 eq $addr2} {
+    pass $test
+} else {
+    fail $test
+}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-08  9:43   ` Jan Kratochvil
@ 2008-06-08 10:39     ` Eli Zaretskii
  2008-06-08 11:38       ` Jan Kratochvil
  0 siblings, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2008-06-08 10:39 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

> Date: Sun, 8 Jun 2008 11:42:13 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: gdb-patches@sourceware.org, Andreas Schwab <schwab@suse.de>
> 
> > > +Standalone programs run with the randomization enabled by default."),
> > 
> > On some platforms, right?
> 
> Fixed.
> 
> Standalone programs run with the\n\
> +randomization enabled by default on the GNU/Linux platform."),

I think "on some platforms" is better, as we won't need to update the
list each time another platform adds support for it.  (Btw, doesn't
Windows Vista already do that?)

> > > +get assigned differently on each run some subtle bugs may be reproducible only
> > > +with specially assigned addresses possibly not reachable with the default
> > > +setting of @kbd{set disable-randomization on}.
> > 
> > Can you explain this sentence?  I'd like to suggest a better wording,
> > but I can't do that unless I understand what is it that you are trying
> > to say here.
> 
> New text:
> 
> As some debuggee's
> +bugs may depend on the assigned addresses the default @value{GDBN} behavior of
> +disabling the randomization may make some debuggee's bugs unreproducible.  You
> +may want to run the debuggee many times with the randomization enabled (and
> +thus this option disabled) to catch such kind of bugs.  Correctly written
> +programs must run the same way notwithstanding this configuration option.

I suggest this modified text:

 Some bugs rear their ugly heads only when the program is loaded at
 certain addresses.  If your bug disappears when you run the program
 under @value{GDBN}, that might be because @value{GDBN} by default
 disables the address randomization on platforms, such as
 @sc{gnu}/Linux, which do that for stand-alone programs.  Use
 @kbd{set disable-randomization off} to try to reproduce such elusive
 bugs.

> > > +PIE executables (type @code{ET_DYN}, compiled by @code{gcc -fPIE -pie}) have
> > > +randomized everything - the executable base address, shared libraries base
> > > +address (their prelinking is ignored), mmap areas, stack and heap.  Regular
> > > +executables (type @code{ET_EXEC}) do not have randomized their base address,
> > > +shared libraries base address is ranomized only for non-prelinked libraries,
> > > +mmap, stack and heap are still randomized.
> > 
> > There's too much unexplained technical details here, so much so that
> > this paragraph sounds like it was meant only for the initiated.
> 
> It is mostly explained at:
> 	http://lwn.net/Articles/190139/
> 
> I expected the full explanation is inappropriate for the GDB manual but I tried
> to include it in this patch:

Thanks.  It needs a bit more work, but now that I understand the
issues, I can do it myself.  Go ahead and commit the doco patch, and I
will revisit it when I have time.

> +The virtual address space randomization is implemented only on @sc{gnu}/Linux.

Btw, according to the above URL, this is not true: it says that
OpenBSD and Adamantix (whatever that is) have it as well.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-08 10:39     ` Eli Zaretskii
@ 2008-06-08 11:38       ` Jan Kratochvil
  0 siblings, 0 replies; 15+ messages in thread
From: Jan Kratochvil @ 2008-06-08 11:38 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1549 bytes --]

On Sun, 08 Jun 2008 12:38:48 +0200, Eli Zaretskii wrote:
...
> I think "on some platforms" is better, as we won't need to update the
> list each time another platform adds support for it.

Changed.

> (Btw, doesn't Windows Vista already do that?)

Probably:
http://en.wikipedia.org/wiki/Address_space_layout_randomization
  Microsoft's Windows Vista and Windows Server 2008 have ASLR enabled by
  default, although only for executables which are specifically linked to be
  ASLR enabled.
  OpenBSD also supports ASLR.


> I suggest this modified text:
> 
>  Some bugs rear their ugly heads only when the program is loaded at
>  certain addresses.  If your bug disappears when you run the program
>  under @value{GDBN}, that might be because @value{GDBN} by default
>  disables the address randomization on platforms, such as
>  @sc{gnu}/Linux, which do that for stand-alone programs.  Use
>  @kbd{set disable-randomization off} to try to reproduce such elusive
>  bugs.

Changed.


> Go ahead and commit the doco patch, and I will revisit it when I have time.

Thanks but I still need the code change approval at least as the whole change
is IMO a bit controversial.


> > +The virtual address space randomization is implemented only on @sc{gnu}/Linux.
> 
> Btw, according to the above URL, this is not true: it says that
> OpenBSD and Adamantix (whatever that is) have it as well.

Changed to (found Adamantix was a GNU/Linux distro):
  The virtual address space randomization is implemented at least on
  @sc{gnu}/Linux and OpenBSD.


Thanks,
Jan

[-- Attachment #2: gdb-derandomize3.patch --]
[-- Type: text/plain, Size: 16807 bytes --]

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* configure.ac: Add check for HAVE_PERSONALITY and
	HAVE_DECL_ADDR_NO_RANDOMIZE.
	* configure, config.in: Regenerate.
	* fork-child.c: New include <errno.h>.
	[HAVE_PERSONALITY]: New include <sys/personality.h>.
	[HAVE_PERSONALITY] (set_disable_randomization): New function.
	(disable_randomization, show_disable_randomization): New.
	(fork_inferior) [HAVE_PERSONALITY] [!HAVE_DECL_ADDR_NO_RANDOMIZE]: Set
	ADDR_NO_RANDOMIZE.
	(fork_inferior) [HAVE_PERSONALITY]: Disable randomization upon the
	variable DISABLE_RANDOMIZATION.
	(_initialize_fork_child): Call ADD_SETSHOW_BOOLEAN_CMD for the variable
	DISABLE_RANDOMIZATION.

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Starting): Document "set disable-randomization".

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/randomize.exp, gdb.base/randomize.c: New files.

--- gdb/config.in	5 Jun 2008 22:36:56 -0000	1.100
+++ gdb/config.in	8 Jun 2008 11:27:20 -0000
@@ -82,6 +82,10 @@
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
+/* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if
+   you don't. */
+#undef HAVE_DECL_ADDR_NO_RANDOMIZE
+
 /* Define to 1 if you have the declaration of `free', and to 0 if you don't.
    */
 #undef HAVE_DECL_FREE
@@ -237,6 +241,9 @@
 /* Define to 1 if you have the <nlist.h> header file. */
 #undef HAVE_NLIST_H
 
+/* Define if you support the personality syscall. */
+#undef HAVE_PERSONALITY
+
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 
--- gdb/configure	5 Jun 2008 22:36:56 -0000	1.249
+++ gdb/configure	8 Jun 2008 11:27:41 -0000
@@ -26701,6 +26701,188 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking whether ADDR_NO_RANDOMIZE is declared" >&5
+echo $ECHO_N "checking whether ADDR_NO_RANDOMIZE is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_ADDR_NO_RANDOMIZE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+
+int
+main ()
+{
+#ifndef ADDR_NO_RANDOMIZE
+  char *p = (char *) ADDR_NO_RANDOMIZE;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_have_decl_ADDR_NO_RANDOMIZE=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_ADDR_NO_RANDOMIZE=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&5
+echo "${ECHO_T}$ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&6
+if test $ac_cv_have_decl_ADDR_NO_RANDOMIZE = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 1
+_ACEOF
+
+
+else
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 0
+_ACEOF
+
+
+fi
+
+
+
+if test "$cross_compiling" = yes; then
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_personality=false
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_personality=false
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+if $have_personality
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PERSONALITY 1
+_ACEOF
+
+fi
+
 
 
 # Check whether --with-sysroot or --without-sysroot was given.
--- gdb/configure.ac	5 Jun 2008 22:36:56 -0000	1.69
+++ gdb/configure.ac	8 Jun 2008 11:27:44 -0000
@@ -1266,6 +1266,29 @@ if test "x$gdb_cv_sys_syscall_h_has_tkil
   AC_DEFINE(HAVE_TKILL_SYSCALL, 1, [Define if you support the tkill syscall.])
 fi
 
+dnl Check if we can disable the virtual address space randomization.
+dnl The functionality of setarch -R.
+AC_CHECK_DECLS([ADDR_NO_RANDOMIZE],,, [#include <sys/personality.h>])
+define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include <sys/personality.h>], [
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1])])
+AC_RUN_IFELSE([PERSONALITY_TEST],
+	      [have_personality=true],
+	      [have_personality=false],
+	      [AC_LINK_IFELSE([PERSONALITY_TEST],
+			      [have_personality=true],
+			      [have_personality=false])])
+if $have_personality
+then
+    AC_DEFINE([HAVE_PERSONALITY], 1,
+	      [Define if you support the personality syscall.])
+fi
+
 dnl Handle optional features that can be enabled.
 
 AC_ARG_WITH(sysroot,
--- gdb/fork-child.c	15 Mar 2008 14:55:21 -0000	1.41
+++ gdb/fork-child.c	8 Jun 2008 11:27:55 -0000
@@ -35,6 +35,10 @@
 #include "solib.h"
 
 #include <signal.h>
+#include <errno.h>
+#ifdef HAVE_PERSONALITY
+# include <sys/personality.h>
+#endif
 
 /* This just gets used as a default if we can't find SHELL.  */
 #define SHELL_FILE "/bin/sh"
@@ -42,6 +46,33 @@
 extern char **environ;
 
 static char *exec_wrapper;
+static int disable_randomization =
+#ifdef HAVE_PERSONALITY
+				   1;
+#else
+				   0;
+#endif
+
+#ifndef HAVE_PERSONALITY
+static void
+set_disable_randomization (char *args, int from_tty, struct cmd_list_element *c)
+{
+  if (disable_randomization)
+    {
+      disable_randomization = 0;
+      error (_("Unsupported on this platform."));
+    }
+}
+#endif
+
+static void
+show_disable_randomization (struct ui_file *file, int from_tty,
+			    struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+Disabling randomization of debuggee's virtual address space is %s.\n"),
+		    value);
+}
 
 /* Break up SCRATCH into an argument vector suitable for passing to
    execvp and store it in ARGV.  E.g., on "run a b c d" this routine
@@ -303,6 +334,24 @@ fork_inferior (char *exec_file_arg, char
       if (debug_fork)
 	sleep (debug_fork);
 
+#ifdef HAVE_PERSONALITY
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#  define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+      if (disable_randomization)
+	{
+	  int val;
+
+	  errno = 0;
+	  val = personality (0xffffffff);
+	  if (errno == 0)
+	    personality (val | ADDR_NO_RANDOMIZE);
+	  if (errno != 0 || !(personality (0xffffffff) & ADDR_NO_RANDOMIZE))
+	    warning (_("Currently enabled disable-randomization is unsupported "
+		       "on this platform."));
+	}
+#endif /* HAVE_PERSONALITY */
+
       /* Create a new session for the inferior process, if necessary.
          It will also place the inferior in a separate process group.  */
       if (create_tty_session () <= 0)
@@ -490,4 +539,19 @@ Show the wrapper for running programs.")
   add_cmd ("exec-wrapper", class_run, unset_exec_wrapper_command,
            _("Disable use of an execution wrapper."),
            &unsetlist);
+
+  add_setshow_boolean_cmd ("disable-randomization", class_support,
+			   &disable_randomization, _("\
+Set disabling of debuggee's virtual address space randomization."), _("\
+Show disabling of debuggee's virtual address space randomization."), _("\
+When this mode is on (which is the default), the randomization of\n\
+the virtual address space is disabled.  Standalone programs run with the\n\
+randomization enabled by default on some platforms."),
+#ifdef HAVE_PERSONALITY
+			   NULL,
+#else
+			   &set_disable_randomization,
+#endif
+			   &show_disable_randomization,
+			   &setlist, &showlist);
 }
--- gdb/doc/gdb.texinfo	6 Jun 2008 20:58:08 -0000	1.503
+++ gdb/doc/gdb.texinfo	8 Jun 2008 11:28:51 -0000
@@ -1999,6 +1999,57 @@ environment:
 This command is available when debugging locally on most targets, excluding
 @sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
 
+@kindex set disable-randomization
+@item set disable-randomization
+@itemx set disable-randomization on
+This option (enabled by default in @value{GDBN}) will turn off the native
+randomization of the virtual address space of the started program.  This option
+is useful for multiple debugging sessions to make the execution better
+reproducible and memory addresses reusable across debugging sessions.
+
+This feature is implemented at least on @sc{gnu}/Linux and OpenBSD.  You can
+get the same behavior using
+
+@smallexample
+(@value{GDBP}) set exec-wrapper setarch `uname -m` -R
+@end smallexample
+
+@item set disable-randomization off
+Leave the behavior of the started executable unchanged.  Some bugs rear their
+ugly heads only when the program is loaded at certain addresses.  If your bug
+disappears when you run the program under @value{GDBN}, that might be because
+@value{GDBN} by default disables the address randomization on platforms, such
+as @sc{gnu}/Linux, which do that for stand-alone programs.  Use @kbd{set
+disable-randomization off} to try to reproduce such elusive bugs.
+
+The virtual address space randomization is implemented at least on
+@sc{gnu}/Linux and OpenBSD.  It protects the programs against some kinds of
+security attacks.  In these cases the attacker needs to know the exact location
+of a concrete executable code.  Randomizing its location makes it impossible to
+inject jumps misusing a code at its expected addresses.
+
+Prelinking shared libraries provides a startup performance advantage but it
+makes addresses in these libraries predictable for privileged processes by
+having just unprivileged access at the target system.  Reading the shared
+library binary gives enough information for assembling the malicious code
+misusing it.  Still even a prelinked shared library can get loaded a a new
+random address just requiring the regular relocation process during the
+startup.  Shared libraries not already prelinked are always loaded at
+a randomly chosen address.
+
+Position independent executables (PIE) contain position independent code
+similar to the shared libraries and therefore such executables get loaded at
+a randomly chosen address upon startup.  PIE executables always load even
+already prelinked shared libraries at a random address.  You can build such
+executable using @command{gcc -fPIE -pie}.
+
+Heap (malloc storage), stack and custom mmap areas are always placed randomly
+(as long as the randomization is enabled).
+
+@item show disable-randomization
+Show the current setting of the explicit disable of the native randomization of
+the virtual address space of the started program.
+
 @end table
 
 @node Arguments
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.c	8 Jun 2008 11:28:53 -0000
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008 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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+  void *p;
+
+  p = malloc (1);
+  printf ("address = %p\n", p);
+
+  return 0;
+}
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.exp	8 Jun 2008 11:28:53 -0000
@@ -0,0 +1,63 @@
+# Copyright 2008 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/>.
+
+set testfile randomize
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+proc address_get { testname } {
+    global gdb_prompt
+
+    if {![runto_main]} {
+	return -1
+    }
+    gdb_test_multiple "continue" $testname {
+	-re "address = (0x\[0-9a-f\]*).*Program exited normally..*$gdb_prompt $" {
+	    pass $testname
+	    return $expect_out(1,string)
+	}
+    }
+}
+
+gdb_test "set disable-randomization off"
+set addr1 [address_get "randomized first address"]
+set addr2 [address_get "randomized second address"]
+set test "randomized addresses should not match"
+if {$addr1 eq $addr2} {
+    fail $test
+} else {
+    pass $test
+}
+
+gdb_test "set disable-randomization on"
+set addr1 [address_get "fixed first address"]
+set addr2 [address_get "fixed second address"]
+set test "fixed addresses should match"
+if {$addr1 eq $addr2} {
+    pass $test
+} else {
+    fail $test
+}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-07 19:54 [patch] Disable child VMA randomizations Jan Kratochvil
  2008-06-07 20:41 ` Andreas Schwab
  2008-06-07 20:43 ` Eli Zaretskii
@ 2008-06-08 15:14 ` Mark Kettenis
  2008-06-08 16:44   ` Jan Kratochvil
  2 siblings, 1 reply; 15+ messages in thread
From: Mark Kettenis @ 2008-06-08 15:14 UTC (permalink / raw)
  To: jan.kratochvil; +Cc: gdb-patches

> Date: Sat, 7 Jun 2008 21:53:43 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> 
> Hi,
> 
> the processes map their addresses randomly by default.  It can make the
> debugging inconvenient as varous addresses are different on each run.
> 
> This feature was suggested by Jakub Jelinek.  One can also already wrap whole
> GDB by a script calling: setarch `uname -m` -R

This really should be moved to a linux-nat.c.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-08 15:14 ` Mark Kettenis
@ 2008-06-08 16:44   ` Jan Kratochvil
  2008-06-26 15:52     ` Daniel Jacobowitz
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2008-06-08 16:44 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 281 bytes --]

On Sun, 08 Jun 2008 17:13:58 +0200, Mark Kettenis wrote:
> > the processes map their addresses randomly by default.  It can make the
> > debugging inconvenient as varous addresses are different on each run.
> 
> This really should be moved to a linux-nat.c.

Moved.


Regards,
Jan

[-- Attachment #2: gdb-derandomize4.patch --]
[-- Type: text/plain, Size: 17029 bytes --]

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* configure.ac: Add check for HAVE_PERSONALITY and
	HAVE_DECL_ADDR_NO_RANDOMIZE.
	* configure, config.in: Regenerate.
	* linux-nat.c [HAVE_PERSONALITY]: New include <sys/personality.h>.
	[HAVE_PERSONALITY] [!HAVE_DECL_ADDR_NO_RANDOMIZE]: Set
	ADDR_NO_RANDOMIZE.
	(disable_randomization, show_disable_randomization): New.
	(linux_nat_create_inferior) [HAVE_PERSONALITY]: New variables
	PERSONALITY_ORIG and PERSONALITY_SET.  Disable randomization upon the
	variable DISABLE_RANDOMIZATION.
	(_initialize_linux_nat): Call ADD_SETSHOW_BOOLEAN_CMD for the variable
	DISABLE_RANDOMIZATION.

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Starting): Document "set disable-randomization".

2008-06-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/randomize.exp, gdb.base/randomize.c: New files.

--- gdb/config.in	5 Jun 2008 22:36:56 -0000	1.100
+++ gdb/config.in	8 Jun 2008 16:22:02 -0000
@@ -82,6 +82,10 @@
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
+/* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if
+   you don't. */
+#undef HAVE_DECL_ADDR_NO_RANDOMIZE
+
 /* Define to 1 if you have the declaration of `free', and to 0 if you don't.
    */
 #undef HAVE_DECL_FREE
@@ -237,6 +241,9 @@
 /* Define to 1 if you have the <nlist.h> header file. */
 #undef HAVE_NLIST_H
 
+/* Define if you support the personality syscall. */
+#undef HAVE_PERSONALITY
+
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 
--- gdb/configure	5 Jun 2008 22:36:56 -0000	1.249
+++ gdb/configure	8 Jun 2008 16:22:20 -0000
@@ -26701,6 +26701,188 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking whether ADDR_NO_RANDOMIZE is declared" >&5
+echo $ECHO_N "checking whether ADDR_NO_RANDOMIZE is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_ADDR_NO_RANDOMIZE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+
+int
+main ()
+{
+#ifndef ADDR_NO_RANDOMIZE
+  char *p = (char *) ADDR_NO_RANDOMIZE;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_have_decl_ADDR_NO_RANDOMIZE=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_ADDR_NO_RANDOMIZE=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&5
+echo "${ECHO_T}$ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&6
+if test $ac_cv_have_decl_ADDR_NO_RANDOMIZE = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 1
+_ACEOF
+
+
+else
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 0
+_ACEOF
+
+
+fi
+
+
+
+if test "$cross_compiling" = yes; then
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_personality=false
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_personality=false
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+if $have_personality
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PERSONALITY 1
+_ACEOF
+
+fi
+
 
 
 # Check whether --with-sysroot or --without-sysroot was given.
--- gdb/configure.ac	5 Jun 2008 22:36:56 -0000	1.69
+++ gdb/configure.ac	8 Jun 2008 16:22:21 -0000
@@ -1266,6 +1266,29 @@ if test "x$gdb_cv_sys_syscall_h_has_tkil
   AC_DEFINE(HAVE_TKILL_SYSCALL, 1, [Define if you support the tkill syscall.])
 fi
 
+dnl Check if we can disable the virtual address space randomization.
+dnl The functionality of setarch -R.
+AC_CHECK_DECLS([ADDR_NO_RANDOMIZE],,, [#include <sys/personality.h>])
+define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include <sys/personality.h>], [
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1])])
+AC_RUN_IFELSE([PERSONALITY_TEST],
+	      [have_personality=true],
+	      [have_personality=false],
+	      [AC_LINK_IFELSE([PERSONALITY_TEST],
+			      [have_personality=true],
+			      [have_personality=false])])
+if $have_personality
+then
+    AC_DEFINE([HAVE_PERSONALITY], 1,
+	      [Define if you support the personality syscall.])
+fi
+
 dnl Handle optional features that can be enabled.
 
 AC_ARG_WITH(sysroot,
--- gdb/linux-nat.c	24 May 2008 16:32:01 -0000	1.86
+++ gdb/linux-nat.c	8 Jun 2008 16:22:37 -0000
@@ -50,6 +50,13 @@
 #include "event-loop.h"
 #include "event-top.h"
 
+#ifdef HAVE_PERSONALITY
+# include <sys/personality.h>
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#  define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+#endif /* HAVE_PERSONALITY */
+
 /* Note on this file's use of signals:
 
    We stop threads by sending a SIGSTOP.  The use of SIGSTOP instead
@@ -149,6 +156,19 @@ show_debug_linux_nat_async (struct ui_fi
 		    value);
 }
 
+#ifdef HAVE_PERSONALITY
+static int disable_randomization = 1;
+
+static void
+show_disable_randomization (struct ui_file *file, int from_tty,
+			    struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+Disabling randomization of debuggee's virtual address space is %s.\n"),
+		    value);
+}
+#endif /* HAVE_PERSONALITY */
+
 static int linux_parent_pid;
 
 struct simple_pid_list
@@ -1217,6 +1237,9 @@ linux_nat_create_inferior (char *exec_fi
 			   int from_tty)
 {
   int saved_async = 0;
+#ifdef HAVE_PERSONALITY
+  int personality_orig = 0, personality_set = 0;
+#endif /* HAVE_PERSONALITY */
 
   /* The fork_child mechanism is synchronous and calls target_wait, so
      we have to mask the async mode.  */
@@ -1232,8 +1255,36 @@ linux_nat_create_inferior (char *exec_fi
       sigdelset (&suspend_mask, SIGCHLD);
     }
 
+#ifdef HAVE_PERSONALITY
+  if (disable_randomization)
+    {
+      errno = 0;
+      personality_orig = personality (0xffffffff);
+      if (errno == 0 && !(personality_orig & ADDR_NO_RANDOMIZE))
+	{
+	  personality_set = 1;
+	  personality (personality_orig | ADDR_NO_RANDOMIZE);
+	}
+      if (errno != 0 || (personality_set
+			 && !(personality (0xffffffff) & ADDR_NO_RANDOMIZE)))
+	warning (_("Error setting the enabled disable-randomization: %s"),
+		 safe_strerror (errno));
+    }
+#endif /* HAVE_PERSONALITY */
+
   linux_ops->to_create_inferior (exec_file, allargs, env, from_tty);
 
+#ifdef HAVE_PERSONALITY
+  if (personality_set)
+    {
+      errno = 0;
+      personality (personality_orig);
+      if (errno != 0)
+	warning (_("Problem restoring the disable-randomization state: %s"),
+		 safe_strerror (errno));
+    }
+#endif /* HAVE_PERSONALITY */
+
   if (saved_async)
     linux_nat_async_mask (saved_async);
 }
@@ -4277,6 +4328,19 @@ Tells gdb whether to control the GNU/Lin
 
   /* Install the default mode.  */
   linux_nat_set_async_mode (linux_async_permitted);
+
+#ifdef HAVE_PERSONALITY
+  add_setshow_boolean_cmd ("disable-randomization", class_support,
+			   &disable_randomization, _("\
+Set disabling of debuggee's virtual address space randomization."), _("\
+Show disabling of debuggee's virtual address space randomization."), _("\
+When this mode is on (which is the default), the randomization of\n\
+the virtual address space is disabled.  Standalone programs run with the\n\
+randomization enabled by default on some platforms."),
+			   NULL,
+			   &show_disable_randomization,
+			   &setlist, &showlist);
+#endif /* HAVE_PERSONALITY */
 }
 \f
 
--- gdb/doc/gdb.texinfo	6 Jun 2008 20:58:08 -0000	1.503
+++ gdb/doc/gdb.texinfo	8 Jun 2008 16:23:15 -0000
@@ -1999,6 +1999,57 @@ environment:
 This command is available when debugging locally on most targets, excluding
 @sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
 
+@kindex set disable-randomization
+@item set disable-randomization
+@itemx set disable-randomization on
+This option (enabled by default in @value{GDBN}) will turn off the native
+randomization of the virtual address space of the started program.  This option
+is useful for multiple debugging sessions to make the execution better
+reproducible and memory addresses reusable across debugging sessions.
+
+This feature is implemented only on @sc{gnu}/Linux.  You can get the same
+behavior using
+
+@smallexample
+(@value{GDBP}) set exec-wrapper setarch `uname -m` -R
+@end smallexample
+
+@item set disable-randomization off
+Leave the behavior of the started executable unchanged.  Some bugs rear their
+ugly heads only when the program is loaded at certain addresses.  If your bug
+disappears when you run the program under @value{GDBN}, that might be because
+@value{GDBN} by default disables the address randomization on platforms, such
+as @sc{gnu}/Linux, which do that for stand-alone programs.  Use @kbd{set
+disable-randomization off} to try to reproduce such elusive bugs.
+
+The virtual address space randomization is implemented only on @sc{gnu}/Linux.
+It protects the programs against some kinds of security attacks.  In these
+cases the attacker needs to know the exact location of a concrete executable
+code.  Randomizing its location makes it impossible to inject jumps misusing
+a code at its expected addresses.
+
+Prelinking shared libraries provides a startup performance advantage but it
+makes addresses in these libraries predictable for privileged processes by
+having just unprivileged access at the target system.  Reading the shared
+library binary gives enough information for assembling the malicious code
+misusing it.  Still even a prelinked shared library can get loaded a a new
+random address just requiring the regular relocation process during the
+startup.  Shared libraries not already prelinked are always loaded at
+a randomly chosen address.
+
+Position independent executables (PIE) contain position independent code
+similar to the shared libraries and therefore such executables get loaded at
+a randomly chosen address upon startup.  PIE executables always load even
+already prelinked shared libraries at a random address.  You can build such
+executable using @command{gcc -fPIE -pie}.
+
+Heap (malloc storage), stack and custom mmap areas are always placed randomly
+(as long as the randomization is enabled).
+
+@item show disable-randomization
+Show the current setting of the explicit disable of the native randomization of
+the virtual address space of the started program.
+
 @end table
 
 @node Arguments
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.c	8 Jun 2008 16:23:15 -0000
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008 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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+  void *p;
+
+  p = malloc (1);
+  printf ("address = %p\n", p);
+
+  return 0;
+}
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.exp	8 Jun 2008 16:23:15 -0000
@@ -0,0 +1,63 @@
+# Copyright 2008 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/>.
+
+set testfile randomize
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+proc address_get { testname } {
+    global gdb_prompt
+
+    if {![runto_main]} {
+	return -1
+    }
+    gdb_test_multiple "continue" $testname {
+	-re "address = (0x\[0-9a-f\]*).*Program exited normally..*$gdb_prompt $" {
+	    pass $testname
+	    return $expect_out(1,string)
+	}
+    }
+}
+
+gdb_test "set disable-randomization off"
+set addr1 [address_get "randomized first address"]
+set addr2 [address_get "randomized second address"]
+set test "randomized addresses should not match"
+if {$addr1 eq $addr2} {
+    fail $test
+} else {
+    pass $test
+}
+
+gdb_test "set disable-randomization on"
+set addr1 [address_get "fixed first address"]
+set addr2 [address_get "fixed second address"]
+set test "fixed addresses should match"
+if {$addr1 eq $addr2} {
+    pass $test
+} else {
+    fail $test
+}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-08 16:44   ` Jan Kratochvil
@ 2008-06-26 15:52     ` Daniel Jacobowitz
  2008-06-27 23:19       ` Jan Kratochvil
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel Jacobowitz @ 2008-06-26 15:52 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Mark Kettenis, gdb-patches

Please also add the new commands to NEWS.

On Sun, Jun 08, 2008 at 06:43:31PM +0200, Jan Kratochvil wrote:
> @@ -149,6 +156,19 @@ show_debug_linux_nat_async (struct ui_fi
>  		    value);
>  }
>  
> +#ifdef HAVE_PERSONALITY
> +static int disable_randomization = 1;
> +
> +static void
> +show_disable_randomization (struct ui_file *file, int from_tty,
> +			    struct cmd_list_element *c, const char *value)
> +{
> +  fprintf_filtered (file, _("\
> +Disabling randomization of debuggee's virtual address space is %s.\n"),
> +		    value);
> +}
> +#endif /* HAVE_PERSONALITY */
> +
>  static int linux_parent_pid;
>  
>  struct simple_pid_list

I think it would be better to register the command unconditionally,
but only call personality if it is available.  I'd like to keep
conditionally compiled code to a minimum.

> +	warning (_("Error setting the enabled disable-randomization: %s"),

Error disabling address space randomization:

> +		 safe_strerror (errno));
> +    }
> +#endif /* HAVE_PERSONALITY */
> +
>    linux_ops->to_create_inferior (exec_file, allargs, env, from_tty);
>  
> +#ifdef HAVE_PERSONALITY
> +  if (personality_set)
> +    {
> +      errno = 0;
> +      personality (personality_orig);
> +      if (errno != 0)
> +	warning (_("Problem restoring the disable-randomization state: %s"),

Error restoring address space randomization:

> +When this mode is on (which is the default), the randomization of\n\
> +the virtual address space is disabled.  Standalone programs run with the\n\
> +randomization enabled by default on some platforms."),

You don't need "the" before randomization in this case (two places).

> +misusing it.  Still even a prelinked shared library can get loaded a a new

at a

> +    gdb_test_multiple "continue" $testname {
> +	-re "address = (0x\[0-9a-f\]*).*Program exited normally..*$gdb_prompt $" {
> +	    pass $testname
> +	    return $expect_out(1,string)
> +	}

Please set a breakpoint and use GDB to print out the variable, instead
of relying on printf; some test configurations don't work with stdio.
They probably won't work with this test anyway, but no reason to
complicate things.

> +gdb_test "set disable-randomization off"
> +set addr1 [address_get "randomized first address"]
> +set addr2 [address_get "randomized second address"]
> +set test "randomized addresses should not match"
> +if {$addr1 eq $addr2} {
> +    fail $test
> +} else {
> +    pass $test
> +}

This test will only pass if the system supports address randomization
and has it enabled.  I don't know about you, but the first thing I do
on a new developer system is turn it off...

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-26 15:52     ` Daniel Jacobowitz
@ 2008-06-27 23:19       ` Jan Kratochvil
  2008-07-09 21:15         ` Daniel Jacobowitz
  2008-07-12 21:16         ` Ulrich Weigand
  0 siblings, 2 replies; 15+ messages in thread
From: Jan Kratochvil @ 2008-06-27 23:19 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 613 bytes --]

Hi,

addressed all your objections.


On Thu, 26 Jun 2008 16:41:50 +0200, Daniel Jacobowitz wrote:
> I think it would be better to register the command unconditionally,
> but only call personality if it is available.  I'd like to keep
> conditionally compiled code to a minimum.

It still has some #ifdef-s for complaints when the feature is not available.


> This test will only pass if the system supports address randomization
> and has it enabled.

There are now two detections:
+       untested "No randomization supported by this GDB"
+    untested "No randomization detected on this system"


Thanks,
Jan

[-- Attachment #2: gdb-derandomize5.patch --]
[-- Type: text/plain, Size: 18789 bytes --]

2008-06-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* NEWS (New commands): Mention "set disable-randomization".
	* configure.ac: Add check for HAVE_PERSONALITY and
	HAVE_DECL_ADDR_NO_RANDOMIZE.
	* configure, config.in: Regenerate.
	* linux-nat.c [HAVE_PERSONALITY]: New include <sys/personality.h>.
	[HAVE_PERSONALITY] [!HAVE_DECL_ADDR_NO_RANDOMIZE]: Set
	ADDR_NO_RANDOMIZE.
	(disable_randomization, show_disable_randomization)
	(set_disable_randomization): New.
	(linux_nat_create_inferior) [HAVE_PERSONALITY]: New variables
	PERSONALITY_ORIG and PERSONALITY_SET.  Disable randomization upon the
	variable DISABLE_RANDOMIZATION.
	(_initialize_linux_nat): Call ADD_SETSHOW_BOOLEAN_CMD for the variable
	DISABLE_RANDOMIZATION.

2008-06-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.texinfo (Starting): Document "set disable-randomization".

2008-06-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/randomize.exp, gdb.base/randomize.c: New files.

--- gdb/NEWS	11 Jun 2008 12:56:36 -0000	1.277
+++ gdb/NEWS	27 Jun 2008 20:35:54 -0000
@@ -95,6 +95,12 @@ show arm force-mode
   the current CPSR value for instructions without symbols; previous
   versions of GDB behaved as if "set arm fallback-mode arm".
 
+set disable-randomization
+show disable-randomization
+  Standalone programs run with the virtual address space randomization enabled
+  by default on some platforms.  This option keeps the addresses stable across
+  multiple debugging sessions.
+
 * New targets
 
 x86 DICOS			i[34567]86-*-dicos*
--- gdb/config.in	26 Jun 2008 15:51:27 -0000	1.101
+++ gdb/config.in	27 Jun 2008 20:35:56 -0000
@@ -82,6 +82,10 @@
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
+/* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if
+   you don't. */
+#undef HAVE_DECL_ADDR_NO_RANDOMIZE
+
 /* Define to 1 if you have the declaration of `free', and to 0 if you don't.
    */
 #undef HAVE_DECL_FREE
@@ -237,6 +241,9 @@
 /* Define to 1 if you have the <nlist.h> header file. */
 #undef HAVE_NLIST_H
 
+/* Define if you support the personality syscall. */
+#undef HAVE_PERSONALITY
+
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 
--- gdb/configure	26 Jun 2008 19:20:42 -0000	1.252
+++ gdb/configure	27 Jun 2008 20:36:06 -0000
@@ -23669,6 +23669,188 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking whether ADDR_NO_RANDOMIZE is declared" >&5
+echo $ECHO_N "checking whether ADDR_NO_RANDOMIZE is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_ADDR_NO_RANDOMIZE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+
+int
+main ()
+{
+#ifndef ADDR_NO_RANDOMIZE
+  char *p = (char *) ADDR_NO_RANDOMIZE;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_have_decl_ADDR_NO_RANDOMIZE=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_ADDR_NO_RANDOMIZE=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&5
+echo "${ECHO_T}$ac_cv_have_decl_ADDR_NO_RANDOMIZE" >&6
+if test $ac_cv_have_decl_ADDR_NO_RANDOMIZE = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 1
+_ACEOF
+
+
+else
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE 0
+_ACEOF
+
+
+fi
+
+
+
+if test "$cross_compiling" = yes; then
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_personality=false
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/personality.h>
+int
+main ()
+{
+
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_personality=true
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_personality=false
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+if $have_personality
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PERSONALITY 1
+_ACEOF
+
+fi
+
 
 
 # Check whether --with-sysroot or --without-sysroot was given.
--- gdb/configure.ac	26 Jun 2008 19:20:42 -0000	1.72
+++ gdb/configure.ac	27 Jun 2008 20:36:07 -0000
@@ -1268,6 +1268,29 @@ if test "x$gdb_cv_sys_syscall_h_has_tkil
   AC_DEFINE(HAVE_TKILL_SYSCALL, 1, [Define if you support the tkill syscall.])
 fi
 
+dnl Check if we can disable the virtual address space randomization.
+dnl The functionality of setarch -R.
+AC_CHECK_DECLS([ADDR_NO_RANDOMIZE],,, [#include <sys/personality.h>])
+define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include <sys/personality.h>], [
+#      if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#       define ADDR_NO_RANDOMIZE 0x0040000
+#      endif
+       /* Test the flag could be set and stays set.  */
+       personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+       if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+	   return 1])])
+AC_RUN_IFELSE([PERSONALITY_TEST],
+	      [have_personality=true],
+	      [have_personality=false],
+	      [AC_LINK_IFELSE([PERSONALITY_TEST],
+			      [have_personality=true],
+			      [have_personality=false])])
+if $have_personality
+then
+    AC_DEFINE([HAVE_PERSONALITY], 1,
+	      [Define if you support the personality syscall.])
+fi
+
 dnl Handle optional features that can be enabled.
 
 AC_ARG_WITH(sysroot,
--- gdb/linux-nat.c	26 Jun 2008 17:40:23 -0000	1.87
+++ gdb/linux-nat.c	27 Jun 2008 20:36:12 -0000
@@ -50,6 +50,13 @@
 #include "event-loop.h"
 #include "event-top.h"
 
+#ifdef HAVE_PERSONALITY
+# include <sys/personality.h>
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#  define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+#endif /* HAVE_PERSONALITY */
+
 /* This comment documents high-level logic of this file. 
 
 Waiting for events in sync mode
@@ -220,6 +227,33 @@ show_debug_linux_nat_async (struct ui_fi
 		    value);
 }
 
+static int disable_randomization = 1;
+
+static void
+show_disable_randomization (struct ui_file *file, int from_tty,
+			    struct cmd_list_element *c, const char *value)
+{
+#ifdef HAVE_PERSONALITY
+  fprintf_filtered (file, _("\
+Disabling randomization of debuggee's virtual address space is %s.\n"),
+		    value);
+#else /* !HAVE_PERSONALITY */
+  fputs_filtered (_("\
+Disabling randomization of debuggee's virtual address space is unsupported on\n\
+this platform.\n"), file);
+#endif /* !HAVE_PERSONALITY */
+}
+
+static void
+set_disable_randomization (char *args, int from_tty, struct cmd_list_element *c)
+{
+#ifndef HAVE_PERSONALITY
+  error (_("\
+Disabling randomization of debuggee's virtual address space is unsupported on\n\
+this platform."));
+#endif /* !HAVE_PERSONALITY */
+}
+
 static int linux_parent_pid;
 
 struct simple_pid_list
@@ -1266,6 +1300,9 @@ linux_nat_create_inferior (char *exec_fi
 			   int from_tty)
 {
   int saved_async = 0;
+#ifdef HAVE_PERSONALITY
+  int personality_orig = 0, personality_set = 0;
+#endif /* HAVE_PERSONALITY */
 
   /* The fork_child mechanism is synchronous and calls target_wait, so
      we have to mask the async mode.  */
@@ -1281,8 +1318,36 @@ linux_nat_create_inferior (char *exec_fi
       sigdelset (&suspend_mask, SIGCHLD);
     }
 
+#ifdef HAVE_PERSONALITY
+  if (disable_randomization)
+    {
+      errno = 0;
+      personality_orig = personality (0xffffffff);
+      if (errno == 0 && !(personality_orig & ADDR_NO_RANDOMIZE))
+	{
+	  personality_set = 1;
+	  personality (personality_orig | ADDR_NO_RANDOMIZE);
+	}
+      if (errno != 0 || (personality_set
+			 && !(personality (0xffffffff) & ADDR_NO_RANDOMIZE)))
+	warning (_("Error disabling address space randomization: %s"),
+		 safe_strerror (errno));
+    }
+#endif /* HAVE_PERSONALITY */
+
   linux_ops->to_create_inferior (exec_file, allargs, env, from_tty);
 
+#ifdef HAVE_PERSONALITY
+  if (personality_set)
+    {
+      errno = 0;
+      personality (personality_orig);
+      if (errno != 0)
+	warning (_("Error restoring address space randomization: %s"),
+		 safe_strerror (errno));
+    }
+#endif /* HAVE_PERSONALITY */
+
   if (saved_async)
     linux_nat_async_mask (saved_async);
 }
@@ -4326,6 +4391,17 @@ Tells gdb whether to control the GNU/Lin
 
   /* Install the default mode.  */
   linux_nat_set_async_mode (linux_async_permitted);
+
+  add_setshow_boolean_cmd ("disable-randomization", class_support,
+			   &disable_randomization, _("\
+Set disabling of debuggee's virtual address space randomization."), _("\
+Show disabling of debuggee's virtual address space randomization."), _("\
+When this mode is on (which is the default), randomization of the virtual\n\
+address space is disabled.  Standalone programs run with the randomization\n\
+enabled by default on some platforms."),
+			   &set_disable_randomization,
+			   &show_disable_randomization,
+			   &setlist, &showlist);
 }
 \f
 
--- gdb/doc/gdb.texinfo	10 Jun 2008 10:23:53 -0000	1.504
+++ gdb/doc/gdb.texinfo	27 Jun 2008 20:37:27 -0000
@@ -1999,6 +1999,57 @@ environment:
 This command is available when debugging locally on most targets, excluding
 @sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
 
+@kindex set disable-randomization
+@item set disable-randomization
+@itemx set disable-randomization on
+This option (enabled by default in @value{GDBN}) will turn off the native
+randomization of the virtual address space of the started program.  This option
+is useful for multiple debugging sessions to make the execution better
+reproducible and memory addresses reusable across debugging sessions.
+
+This feature is implemented only on @sc{gnu}/Linux.  You can get the same
+behavior using
+
+@smallexample
+(@value{GDBP}) set exec-wrapper setarch `uname -m` -R
+@end smallexample
+
+@item set disable-randomization off
+Leave the behavior of the started executable unchanged.  Some bugs rear their
+ugly heads only when the program is loaded at certain addresses.  If your bug
+disappears when you run the program under @value{GDBN}, that might be because
+@value{GDBN} by default disables the address randomization on platforms, such
+as @sc{gnu}/Linux, which do that for stand-alone programs.  Use @kbd{set
+disable-randomization off} to try to reproduce such elusive bugs.
+
+The virtual address space randomization is implemented only on @sc{gnu}/Linux.
+It protects the programs against some kinds of security attacks.  In these
+cases the attacker needs to know the exact location of a concrete executable
+code.  Randomizing its location makes it impossible to inject jumps misusing
+a code at its expected addresses.
+
+Prelinking shared libraries provides a startup performance advantage but it
+makes addresses in these libraries predictable for privileged processes by
+having just unprivileged access at the target system.  Reading the shared
+library binary gives enough information for assembling the malicious code
+misusing it.  Still even a prelinked shared library can get loaded at a new
+random address just requiring the regular relocation process during the
+startup.  Shared libraries not already prelinked are always loaded at
+a randomly chosen address.
+
+Position independent executables (PIE) contain position independent code
+similar to the shared libraries and therefore such executables get loaded at
+a randomly chosen address upon startup.  PIE executables always load even
+already prelinked shared libraries at a random address.  You can build such
+executable using @command{gcc -fPIE -pie}.
+
+Heap (malloc storage), stack and custom mmap areas are always placed randomly
+(as long as the randomization is enabled).
+
+@item show disable-randomization
+Show the current setting of the explicit disable of the native randomization of
+the virtual address space of the started program.
+
 @end table
 
 @node Arguments
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.c	27 Jun 2008 20:37:28 -0000
@@ -0,0 +1,31 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008 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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+  void *p;
+
+  p = malloc (1);
+
+  return 0; /* print p */
+}
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/randomize.exp	27 Jun 2008 20:37:28 -0000
@@ -0,0 +1,87 @@
+# Copyright 2008 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/>.
+
+set testfile randomize
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+proc address_get { testname } {
+    global gdb_prompt
+
+    if {![runto_main]} {
+	return -1
+    }
+
+    # Do not rely on printf; some test configurations don't work with stdio.
+
+    gdb_breakpoint [gdb_get_line_number "print p"]
+    gdb_continue_to_breakpoint "$testname - address set"
+
+    gdb_test_multiple "print/x p" $testname {
+	-re "\\$\[0-9\]+ = (0x\[0-9a-f\]*)\r?\n$gdb_prompt $" {
+	    pass $testname
+	    return $expect_out(1,string)
+	}
+    }
+}
+
+set test "set disable-randomization off"
+gdb_test_multiple "${test}" "${test}" {
+    -re "Disabling randomization .* unsupported .*$gdb_prompt $" {
+	untested "No randomization supported by this GDB"
+	return -1
+    }
+    -re "$gdb_prompt $" {
+	pass $test
+    }
+}
+gdb_test "show disable-randomization"	      \
+         "Disabling randomization .* is off." \
+         "show disable-randomization off"
+
+set addr1 [address_get "randomized first address"]
+set addr2 [address_get "randomized second address"]
+set test "randomized addresses should not match"
+if {$addr1 eq $addr2} {
+    untested "No randomization detected on this system"
+    return -1
+} else {
+    pass $test
+}
+
+gdb_test "set disable-randomization on"
+gdb_test "show disable-randomization"	      \
+         "Disabling randomization .* is on." \
+         "show disable-randomization on"
+
+set addr1 [address_get "fixed first address"]
+set addr2 [address_get "fixed second address"]
+set test "fixed addresses should match"
+if {$addr1 eq $addr2} {
+    pass $test
+} else {
+    fail $test
+}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-27 23:19       ` Jan Kratochvil
@ 2008-07-09 21:15         ` Daniel Jacobowitz
  2008-07-10  9:34           ` Jan Kratochvil
  2008-07-12 21:16         ` Ulrich Weigand
  1 sibling, 1 reply; 15+ messages in thread
From: Daniel Jacobowitz @ 2008-07-09 21:15 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Mark Kettenis, gdb-patches

On Fri, Jun 27, 2008 at 10:46:42PM +0200, Jan Kratochvil wrote:
> 2008-06-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
> 
> 	* NEWS (New commands): Mention "set disable-randomization".
> 	* configure.ac: Add check for HAVE_PERSONALITY and
> 	HAVE_DECL_ADDR_NO_RANDOMIZE.
> 	* configure, config.in: Regenerate.
> 	* linux-nat.c [HAVE_PERSONALITY]: New include <sys/personality.h>.
> 	[HAVE_PERSONALITY] [!HAVE_DECL_ADDR_NO_RANDOMIZE]: Set
> 	ADDR_NO_RANDOMIZE.
> 	(disable_randomization, show_disable_randomization)
> 	(set_disable_randomization): New.
> 	(linux_nat_create_inferior) [HAVE_PERSONALITY]: New variables
> 	PERSONALITY_ORIG and PERSONALITY_SET.  Disable randomization upon the
> 	variable DISABLE_RANDOMIZATION.
> 	(_initialize_linux_nat): Call ADD_SETSHOW_BOOLEAN_CMD for the variable
> 	DISABLE_RANDOMIZATION.
> 
> 2008-06-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
> 
> 	* gdb.texinfo (Starting): Document "set disable-randomization".
> 
> 2008-06-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
> 
> 	* gdb.base/randomize.exp, gdb.base/randomize.c: New files.

Thanks, this is OK.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-07-09 21:15         ` Daniel Jacobowitz
@ 2008-07-10  9:34           ` Jan Kratochvil
  0 siblings, 0 replies; 15+ messages in thread
From: Jan Kratochvil @ 2008-07-10  9:34 UTC (permalink / raw)
  To: gdb-patches, Eli Zaretskii; +Cc: Daniel Jacobowitz

On Wed, 09 Jul 2008 23:14:40 +0200, Daniel Jacobowitz wrote:
> Thanks, this is OK.

Committed.

[ http://sourceware.org/ml/gdb-patches/2008-06/msg00133.html ]
On Sun, 08 Jun 2008 12:38:48 +0200, Eli Zaretskii wrote:
> Thanks.  It needs a bit more work, but now that I understand the
> issues, I can do it myself.  Go ahead and commit the doco patch, and I
> will revisit it when I have time.

Just a notice the patch has been committed.


Thanks,
Jan


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-06-27 23:19       ` Jan Kratochvil
  2008-07-09 21:15         ` Daniel Jacobowitz
@ 2008-07-12 21:16         ` Ulrich Weigand
  2008-07-13  6:55           ` Jan Kratochvil
  1 sibling, 1 reply; 15+ messages in thread
From: Ulrich Weigand @ 2008-07-12 21:16 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Daniel Jacobowitz, Mark Kettenis, gdb-patches

Jan Kratochvil wrote:

> 	* gdb.base/randomize.exp, gdb.base/randomize.c: New files.

This test case still fails on non-Linux targets.

This test:

> +set test "set disable-randomization off"
> +gdb_test_multiple "${test}" "${test}" {
> +    -re "Disabling randomization .* unsupported .*$gdb_prompt $" {
> +	untested "No randomization supported by this GDB"
> +	return -1
> +    }
> +    -re "$gdb_prompt $" {
> +	pass $test
> +    }
> +}

does not trigger as the command is not even registered:

(gdb) set disable-randomization off^M
No symbol "disable" in current context.^M
(gdb) PASS: gdb.base/randomize.exp: set disable-randomization off

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-07-12 21:16         ` Ulrich Weigand
@ 2008-07-13  6:55           ` Jan Kratochvil
  2008-07-15 18:41             ` Ulrich Weigand
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2008-07-13  6:55 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Daniel Jacobowitz, Mark Kettenis, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 329 bytes --]

On Sat, 12 Jul 2008 23:16:23 +0200, Ulrich Weigand wrote:
> does not trigger as the command is not even registered:
> 
> (gdb) set disable-randomization off^M
> No symbol "disable" in current context.^M
> (gdb) PASS: gdb.base/randomize.exp: set disable-randomization off

I see, sorry, going to commit this patch.


Regards,
Jan

[-- Attachment #2: gdb-derandomize-nonlinux-test.patch --]
[-- Type: text/plain, Size: 792 bytes --]

2008-07-13  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/randomize.exp: Catch non-Linux targets as untested.

--- ./gdb/testsuite/gdb.base/randomize.exp	10 Jul 2008 20:16:27 -0000	1.2
+++ ./gdb/testsuite/gdb.base/randomize.exp	13 Jul 2008 06:52:48 -0000
@@ -51,7 +51,11 @@ proc address_get { testname } {
 set test "set disable-randomization off"
 gdb_test_multiple "${test}" "${test}" {
     -re "Disabling randomization .* unsupported .*$gdb_prompt $" {
-	untested "No randomization supported by this GDB"
+	untested "Disabling randomization is not supported on this Linux GDB"
+	return -1
+    }
+    -re "No symbol .* in current context.*$gdb_prompt $" {
+	untested "Disabling randomization is not supported on this GDB platform"
 	return -1
     }
     -re "$gdb_prompt $" {

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [patch] Disable child VMA randomizations
  2008-07-13  6:55           ` Jan Kratochvil
@ 2008-07-15 18:41             ` Ulrich Weigand
  0 siblings, 0 replies; 15+ messages in thread
From: Ulrich Weigand @ 2008-07-15 18:41 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Daniel Jacobowitz, Mark Kettenis, gdb-patches

Jan Kratochvil wrote:

> On Sat, 12 Jul 2008 23:16:23 +0200, Ulrich Weigand wrote:
> > does not trigger as the command is not even registered:
> > 
> > (gdb) set disable-randomization off^M
> > No symbol "disable" in current context.^M
> > (gdb) PASS: gdb.base/randomize.exp: set disable-randomization off
> 
> I see, sorry, going to commit this patch.

Thanks, that fixes the problem for me.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2008-07-15 18:41 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-07 19:54 [patch] Disable child VMA randomizations Jan Kratochvil
2008-06-07 20:41 ` Andreas Schwab
2008-06-08  9:43   ` Jan Kratochvil
2008-06-08 10:39     ` Eli Zaretskii
2008-06-08 11:38       ` Jan Kratochvil
2008-06-07 20:43 ` Eli Zaretskii
2008-06-08 15:14 ` Mark Kettenis
2008-06-08 16:44   ` Jan Kratochvil
2008-06-26 15:52     ` Daniel Jacobowitz
2008-06-27 23:19       ` Jan Kratochvil
2008-07-09 21:15         ` Daniel Jacobowitz
2008-07-10  9:34           ` Jan Kratochvil
2008-07-12 21:16         ` Ulrich Weigand
2008-07-13  6:55           ` Jan Kratochvil
2008-07-15 18:41             ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox