* [RFA] Add $pdir as entry for libthread-db-search-path.
@ 2011-04-29 3:59 Doug Evans
2011-04-29 12:36 ` Jan Kratochvil
0 siblings, 1 reply; 9+ messages in thread
From: Doug Evans @ 2011-04-29 3:59 UTC (permalink / raw)
To: gdb-patches
Hi.
(1) gdb currently searches for libthread_db in libthread-db-search-path,
the system libthread_db, and finally tries the libthread_db in the
directory of libpthread.
[For completeness sake,
system libthread_db is a bit of a misnomer. What this really is
is the libthread_db that the ld.so specified in the gdb/gdbserver
binary would find.]
A better default is to look in the directory of libpthread first - that is
the best default.
(2) If the user overrides libthread-db-search-path we want to obey the
user's choice. Thus, for example, we don't want to hardcode looking
in the directory of libpthread first.
Combining (1) and (2) yields the following patch.
gdbserver has an existing bug where it won't look in the directory
of libpthread, differing in behaviour from gdb. Blech.
Fixing this requires having gdbserver know where libpthread lives
but that's a bit much for the scope of this patch.
So this patch ignores $pdir in gdbserver.
Tested on amd64-linux with a non-trivial default libthread-db-search-path
and three different libthread_dbs, and cvs head.
Ok to check in?
2011-04-28 Doug Evans <dje@google.com>
Support $pdir in libthread-db-search-path.
* gdb_thread_db.h (LIBTHREAD_DB_SEARCH_PATH): Add $pdir.
* linux-thread-db.c (try_thread_db_load_from_pdir): New function.
(thread_db_load_search): Handle $pdir.
(has_libpthread): New function.
(thread_db_load): Remove search for libthread_db in directory of
libpthread - that is now done via $pdir.
gdbserver/
* thread-db.c (thread_db_load_search): Ignore $pdir.
doc/
* gdb.texinfo (Threads): Document $pdir.
(Server): Ditto.
Index: gdb_thread_db.h
===================================================================
RCS file: /cvs/src/src/gdb/gdb_thread_db.h,v
retrieving revision 1.16
diff -u -p -r1.16 gdb_thread_db.h
--- gdb_thread_db.h 7 Jan 2011 19:36:17 -0000 1.16
+++ gdb_thread_db.h 29 Apr 2011 03:30:11 -0000
@@ -6,7 +6,7 @@
#endif
#ifndef LIBTHREAD_DB_SEARCH_PATH
-#define LIBTHREAD_DB_SEARCH_PATH ""
+#define LIBTHREAD_DB_SEARCH_PATH "$pdir"
#endif
#else
Index: linux-thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.82
diff -u -p -r1.82 linux-thread-db.c
--- linux-thread-db.c 17 Apr 2011 19:11:07 -0000 1.82
+++ linux-thread-db.c 29 Apr 2011 03:30:11 -0000
@@ -639,7 +639,7 @@ dladdr_to_soname (const void *addr)
return NULL;
}
-/* Attempt to initialize dlopen()ed libthread_db, described by HANDLE.
+/* Attempt to initialize dlopen()ed libthread_db, described by INFO.
Return 1 on success.
Failure could happen if libthread_db does not have symbols we expect,
or when it refuses to work with the current inferior (e.g. due to
@@ -802,6 +802,44 @@ try_thread_db_load (const char *library)
return 0;
}
+/* Handle $pdir in libthread-db-search-path.
+ Look for libthread_db in the directory of libpthread. */
+
+static int
+try_thread_db_load_from_pdir (void)
+{
+ struct objfile *obj;
+
+ ALL_OBJFILES (obj)
+ if (libpthread_name_p (obj->name))
+ {
+ char path[PATH_MAX], *cp;
+
+ gdb_assert (strlen (obj->name) < sizeof (path));
+ strcpy (path, obj->name);
+ cp = strrchr (path, '/');
+
+ if (cp == NULL)
+ {
+ warning (_("Expected absolute pathname for libpthread in the"
+ " inferior, but got %s."), path);
+ }
+ else if (cp + 1 + strlen (LIBTHREAD_DB_SO) + 1 > path + sizeof (path))
+ {
+ warning (_("Unexpected: path to libpthread in the inferior is"
+ " too long: %s"), path);
+ }
+ else
+ {
+ strcpy (cp + 1, LIBTHREAD_DB_SO);
+ if (try_thread_db_load (path))
+ return 1;
+ }
+ return 0;
+ }
+
+ return 0;
+}
/* Search libthread_db_search_path for libthread_db which "agrees"
to work on current inferior. */
@@ -850,12 +888,24 @@ thread_db_load_search (void)
memcpy (path, search_path, len + 1);
search_path += len;
}
- strcat (path, "/");
- strcat (path, LIBTHREAD_DB_SO);
- if (try_thread_db_load (path))
+
+ if (strcmp (path, "$pdir") == 0)
{
- rc = 1;
- break;
+ if (try_thread_db_load_from_pdir ())
+ {
+ rc = 1;
+ break;
+ }
+ }
+ else
+ {
+ strcat (path, "/");
+ strcat (path, LIBTHREAD_DB_SO);
+ if (try_thread_db_load (path))
+ {
+ rc = 1;
+ break;
+ }
}
}
if (rc == 0)
@@ -863,13 +913,26 @@ thread_db_load_search (void)
return rc;
}
+/* Return non-zero if the inferior has a libpthread. */
+
+static int
+has_libpthread (void)
+{
+ struct objfile *obj;
+
+ ALL_OBJFILES (obj)
+ if (libpthread_name_p (obj->name))
+ return 1;
+
+ return 0;
+}
+
/* Attempt to load and initialize libthread_db.
Return 1 on success. */
static int
thread_db_load (void)
{
- struct objfile *obj;
struct thread_db_info *info;
info = get_thread_db_info (GET_PID (inferior_ptid));
@@ -889,39 +952,15 @@ thread_db_load (void)
if (thread_db_load_search ())
return 1;
- /* None of the libthread_db's on our search path, not the system default
- ones worked. If the executable is dynamically linked against
- libpthread, try loading libthread_db from the same directory. */
-
- ALL_OBJFILES (obj)
- if (libpthread_name_p (obj->name))
- {
- char path[PATH_MAX], *cp;
-
- gdb_assert (strlen (obj->name) < sizeof (path));
- strcpy (path, obj->name);
- cp = strrchr (path, '/');
-
- if (cp == NULL)
- {
- warning (_("Expected absolute pathname for libpthread in the"
- " inferior, but got %s."), path);
- }
- else if (cp + 1 + strlen (LIBTHREAD_DB_SO) + 1 > path + sizeof (path))
- {
- warning (_("Unexpected: path to libpthread in the inferior is"
- " too long: %s"), path);
- }
- else
- {
- strcpy (cp + 1, LIBTHREAD_DB_SO);
- if (try_thread_db_load (path))
- return 1;
- }
- warning (_("Unable to find libthread_db matching inferior's thread"
- " library, thread debugging will not be available."));
- return 0;
+ /* We couldn't find a libthread_db.
+ If the inferior has a libpthread warn the user. */
+ if (has_libpthread ())
+ {
+ warning (_("Unable to find libthread_db matching inferior's thread"
+ " library, thread debugging will not be available."));
+ return 0;
}
+
/* Either this executable isn't using libpthread at all, or it is
statically linked. Since we can't easily distinguish these two cases,
no warning is issued. */
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.827
diff -u -p -r1.827 gdb.texinfo
--- doc/gdb.texinfo 27 Apr 2011 20:03:04 -0000 1.827
+++ doc/gdb.texinfo 29 Apr 2011 03:30:12 -0000
@@ -2864,8 +2864,12 @@ On @sc{gnu}/Linux and Solaris systems, @
@code{libthread_db} library to obtain information about threads in the
inferior process. @value{GDBN} will use @samp{libthread-db-search-path}
to find @code{libthread_db}. If that fails, @value{GDBN} will continue
-with default system shared library directories, and finally the directory
-from which @code{libpthread} was loaded in the inferior process.
+with default system shared library directories.
+
+A special entry @samp{$pdir} for @samp{libthread-db-search-path} is
+supported, and refers to the directory from which @code{libpthread}
+was loaded in the inferior process. It is normally the first entry
+in the search path.
For any @code{libthread_db} library @value{GDBN} finds in above directories,
@value{GDBN} attempts to initialize it with the current inferior process.
@@ -16357,6 +16361,9 @@ directories to search for @code{libthrea
libthread-db-search-path}). If you omit @var{path},
@samp{libthread-db-search-path} will be reset to an empty list.
+The special entry @samp{$pdir} for @samp{libthread-db-search-path} is
+not supported in @code{gdbserver}.
+
@item monitor exit
Tell gdbserver to exit immediately. This command should be followed by
@code{disconnect} to close the debugging session. @code{gdbserver} will
Index: gdbserver/thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/thread-db.c,v
retrieving revision 1.39
diff -u -p -r1.39 thread-db.c
--- gdbserver/thread-db.c 6 Jan 2011 00:14:09 -0000 1.39
+++ gdbserver/thread-db.c 29 Apr 2011 03:30:12 -0000
@@ -743,14 +743,24 @@ thread_db_load_search (void)
memcpy (path, search_path, len + 1);
search_path += len;
}
- strcat (path, "/");
- strcat (path, LIBTHREAD_DB_SO);
- if (debug_threads)
- fprintf (stderr, "thread_db_load_search trying %s\n", path);
- if (try_thread_db_load (path))
+
+ if (strcmp (path, "$pdir") == 0)
+ {
+ /* We don't maintain a list of loaded libraries so we don't know
+ where libpthread lives. We *could* fetch the info, but we don't
+ do that yet. Ignore it. */
+ }
+ else
{
- rc = 1;
- break;
+ strcat (path, "/");
+ strcat (path, LIBTHREAD_DB_SO);
+ if (debug_threads)
+ fprintf (stderr, "thread_db_load_search trying %s\n", path);
+ if (try_thread_db_load (path))
+ {
+ rc = 1;
+ break;
+ }
}
}
if (rc == 0)
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [RFA] Add $pdir as entry for libthread-db-search-path.
2011-04-29 3:59 [RFA] Add $pdir as entry for libthread-db-search-path Doug Evans
@ 2011-04-29 12:36 ` Jan Kratochvil
2011-04-29 16:49 ` Doug Evans
0 siblings, 1 reply; 9+ messages in thread
From: Jan Kratochvil @ 2011-04-29 12:36 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
On Fri, 29 Apr 2011 05:58:37 +0200, Doug Evans wrote:
> A better default is to look in the directory of libpthread first - that is
> the best default.
This is insecure default. It is something like the FSF GDB insecure .gdbinit
behavior which many distros (at least Fedora but even others) have to patch.
While it is always insecure to run a foreign binary it should be secure to for
example load a foreign binary and its core file.
> (2) If the user overrides libthread-db-search-path we want to obey the
> user's choice.
I agree if the user explicitly wishes so it should be followed.
Thanks,
Jan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Add $pdir as entry for libthread-db-search-path.
2011-04-29 12:36 ` Jan Kratochvil
@ 2011-04-29 16:49 ` Doug Evans
2011-04-29 17:08 ` Jan Kratochvil
0 siblings, 1 reply; 9+ messages in thread
From: Doug Evans @ 2011-04-29 16:49 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches
On Fri, Apr 29, 2011 at 5:36 AM, Jan Kratochvil
<jan.kratochvil@redhat.com> wrote:
> On Fri, 29 Apr 2011 05:58:37 +0200, Doug Evans wrote:
>> A better default is to look in the directory of libpthread first - that is
>> the best default.
>
> This is insecure default. It is something like the FSF GDB insecure .gdbinit
> behavior which many distros (at least Fedora but even others) have to patch.
Does Fedora turn off the autoloading of python?
How do your pretty printers Just Work?
[Or maybe you only autoload if the directory is in $prefix/lib/debug
or some such?]
Plus I wonder how easy it would be to build a program that used an
accompanying libpthread that didn't match the system libthread_db -
gdb would then pick the accompanying libthread_db. Or does Fedora not
ever look in the directory of libpthread for its libthread_db?
> While it is always insecure to run a foreign binary it should be secure to for
> example load a foreign binary and its core file.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFA] Add $pdir as entry for libthread-db-search-path.
2011-04-29 16:49 ` Doug Evans
@ 2011-04-29 17:08 ` Jan Kratochvil
[not found] ` <BANLkTinagVcXZqvOg80eoFMnyaw9T0OYUw@mail.gmail.com>
0 siblings, 1 reply; 9+ messages in thread
From: Jan Kratochvil @ 2011-04-29 17:08 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches, Tom Tromey
On Fri, 29 Apr 2011 18:49:09 +0200, Doug Evans wrote:
> On Fri, Apr 29, 2011 at 5:36 AM, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
> > This is insecure default. Â It is something like the FSF GDB insecure .gdbinit
> > behavior which many distros (at least Fedora but even others) have to patch.
>
> Does Fedora turn off the autoloading of python?
No.
> How do your pretty printers Just Work?
> [Or maybe you only autoload if the directory is in $prefix/lib/debug
> or some such?]
You are right it is a security hole, I have not tracked to Python autoloading
much. It should get CVE and security errata assigned as it is the same
category of a security breach as was:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=2006-4146
> Plus I wonder how easy it would be to build a program that used an
> accompanying libpthread that didn't match the system libthread_db -
> gdb would then pick the accompanying libthread_db. Or does Fedora not
> ever look in the directory of libpthread for its libthread_db?
This may be also a security exploit I did not catch.
Thanks,
Jan
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-05-09 22:30 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-29 3:59 [RFA] Add $pdir as entry for libthread-db-search-path Doug Evans
2011-04-29 12:36 ` Jan Kratochvil
2011-04-29 16:49 ` Doug Evans
2011-04-29 17:08 ` Jan Kratochvil
[not found] ` <BANLkTinagVcXZqvOg80eoFMnyaw9T0OYUw@mail.gmail.com>
2011-05-01 18:34 ` Doug Evans
2011-05-02 19:15 ` Jan Kratochvil
2011-05-02 19:51 ` Doug Evans
2011-05-06 18:40 ` Tom Tromey
2011-05-09 22:30 ` Doug Evans
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox