Bug 23613 - gdb segfaults when in an unreachable directory
Summary: gdb segfaults when in an unreachable directory
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 25178 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-09-06 17:59 UTC by Joseph C. Sible
Modified: 2019-12-14 16:24 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph C. Sible 2018-09-06 17:59:22 UTC
When gdb is ran in a directory that's unreachable (specifically, when the getcwd system call gives a string beginning with "(unreachable)"), it will segfault. Reproduction steps:

sudo mount -t tmpfs none /mnt
cd /mnt
sudo umount --lazy /mnt
gdb /bin/true
run

I've tested this with multiple versions of gdb:

On 8.2.50.20180906-git (commit d82b386, which is HEAD as of this writing) on RHEL 7.5, it crashes before I even get to the prompt to type "run". On 8.1-0ubuntu3 on Ubuntu 18.04, it gets to the prompt, then crashes after I type "run". On 7.6.1-110.el7 on RHEL 7.5, the crash doesn't seem to happen at all.

(The actual case I hit this in involved directories from foreign mount namespaces accessed via the /proc/*/fd/ symlinks rather than lazy unmounts, but this test case is simpler and exposes the exact same problem.)
Comment 1 Sergio Durigan Junior 2019-11-10 01:18:58 UTC
*** Bug 25178 has been marked as a duplicate of this bug. ***
Comment 2 Sourceware Commits 2019-12-14 04:51:06 UTC
The master branch has been updated by Sergio Durigan Junior <sergiodj@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ff8577f64987a898e1dc5eb6afb66a404fb7bb16

commit ff8577f64987a898e1dc5eb6afb66a404fb7bb16
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Wed Jul 10 16:18:27 2019 -0400

    Guard against 'current_directory == NULL' on gdb_abspath (PR gdb/23613)
    
    Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1728147
    Ref.: https://sourceware.org/bugzilla/show_bug.cgi?id=23613
    
    Hi,
    
    This bug has been reported against Fedora GDB, but there's also an
    upstream bug.  The problem reported is that GDB segfaults when the
    working directory is deleted.  It's pretty use to reproduce it:
    
      mkdir bla
      cd bla
      rmdir ../bla
      gdb echo
    
    Debugging the problem is a bit tricky, because, since the current
    directory doesn't exist anymore, a corefile cannot be saved there.
    After a few attempts, I came up with the following:
    
      gdb -ex 'shell mkdir bla' -ex 'cd bla' -ex 'shell rmdir ../bla' -ex 'r echo' ./gdb/gdb
    
    This assumes that you're inside a build directory which contains
    ./gdb/gdb, of course.
    
    After investigating it, I found that the problem happens at
    gdb_abspath, where we're dereferencing 'current_directory' without
    checking if it's NULL:
    
        ...
        (concat (current_directory,
    	     IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
    	     ? "" : SLASH_STRING,
        ...
    
    So I fixed the problem with the patch below.  The idea is that, if
    'current_directory' is NULL, then the final string returned should be
    just the "path".
    
    After fixing the bug, I found a similar one reported against our
    bugzilla: PR gdb/23613.  The problem is the same, but the reproducer
    is a bit different.
    
    I really tried writing a testcase for this, but unfortunately it's
    apparently not possible to start GDB inside a non-existent directory
    with DejaGNU.
    
    I regression tested this patch on the BuildBot, and no regressions
    were found.
    
    gdb/ChangeLog:
    2019-12-14  Sergio Durigan Junior  <sergiodj@redhat.com>
    
    	https://bugzilla.redhat.com/show_bug.cgi?id=1728147
    	PR gdb/23613
    	* bsd-kvm.c (bsd_kvm_target_open): Use 'gdb_abspath'.
    	* corelow.c: Include 'gdbsupport/pathstuff.h'.
    	(core_target_open): Use 'gdb_abspath'.
    	* gdbsupport/pathstuff.c (gdb_abspath): Guard against
    	'current_directory == NULL' case.
    	* gdbsupport/pathstuff.h (gdb_abspath): Expand comment and
    	explain what happens when 'current_directory' is NULL.
    	* go32-nat.c (go32_nat_target::wait): Check if
    	'current_directory' is NULL before call to 'chdir'.
    	* source.c (add_path): Use 'gdb_abspath'.
    	* top.c: Include 'gdbsupport/pathstuff.h'.
    	(init_history): Use 'gdb_abspath'.
    	(set_history_filename): Likewise.
    	* tracefile-tfile.c: Include 'gdbsupport/pathstuff.h'.
    	(tfile_target_open): Use 'gdb_abspath'.
    
    Change-Id: Ibb0932fa25bc5c2d3ae4a7f64bd7f32885ca403b
Comment 3 Sergio Durigan Junior 2019-12-14 16:24:16 UTC
Fixed.