Bug 10246 - glob() with GLOB_NOCHECK is returning a modified pattern sometimes
Summary: glob() with GLOB_NOCHECK is returning a modified pattern sometimes
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: glob (show other bugs)
Version: 2.8
: P2 normal
Target Milestone: ---
Assignee: Adhemerval Zanella
Depends on:
Reported: 2009-06-06 05:55 UTC by Paul Smith
Modified: 2017-08-01 20:47 UTC (History)
2 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Last reconfirmed:
fweimer: security-

Test program for glob(). (231 bytes, text/plain)
2009-06-06 05:57 UTC, Paul Smith

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Smith 2009-06-06 05:55:45 UTC
Actually I see this with glibc 2.7-13 but there's no 2.7 in the version list?

According to POSIX, glob() with GLOB_NOCHECK should:

> If pattern does not match any pathname, then glob() shall return a list
> consisting of only pattern, and the number of matched pathnames is 1.

However, if I invoke glob() with a pattern of "//<word>" where <word> is any
non-slash-containing string that I've tried, then the resulting string is
"/<word>" with the initial slash removed.

If there are more than two initial slashes, it works fine.  Likewise if there
are extra directory levels in the pattern.

I will attach a test program I wrote:

$ gcc -o /tmp/gtest /tmp/gtest.c

$ /tmp/gtest /%
0: /bin

$ /tmp/gtest //%
0: /bin     <--incorrect!

$ /tmp/gtest ///%
0: ///%     <--OK

$/tmp/gtest //a/b
0: //a/b    <--OK
Comment 1 Paul Smith 2009-06-06 05:57:21 UTC
Created attachment 3984 [details]
Test program for glob().
Comment 2 cvs-commit@gcc.gnu.org 2017-07-26 20:17:39 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, azanella/glob-fixes has been created
        at  80aed7ed5a919358c0bce9bfee97c4d8ac533d5e (commit)

- Log -----------------------------------------------------------------

commit 80aed7ed5a919358c0bce9bfee97c4d8ac533d5e
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Jul 26 16:09:26 2017 -0300

    posix: Fix glob with GLOB_NOCHECK returning modified patterns (BZ#10246)
    Acconding to POSIX glob with GLOB_NOCHECK should return a list consisting
    of only of the input pattern in case of no match.  However GLIBC does not
    honor in case of '//<something'.  This is due internally this is handled
    and special case and prefix_array (responsable to prepend the directory
    name) does not know if the input already contains a slash or not since
    either '/<something>' or '//<something>' will be handle in same way.
    This patch fix it by using a empty directory name for the latter (since
    prefix_array already adds a slash as default for each entry).
    Checked on x86_64-linux-gnu.
    	[BZ #10246]
    	* posix/glob.c (glob): Handle pattern that do not match and
    	start with '/' correctly.
    	* posix/globtest.sh: New tests for NOCHECK.


commit c50dfe79df1b3a3fe3ba3bc1eba3c354a5d122a6
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Jul 26 11:39:49 2017 -0300

    posix: Use enum for __glob_pattern_type result
    This patch replaces the internal integer constant from
    __glob_pattern_type return with a proper enum.
    Checked on x86_64-linux-gnu.
    	* posix/glob_internal.h (__glob_pat_types): New enumeration.
    	(__glob_pattern_type): Use __glob_pat_types.
    	* posix/glob_pattern_p.c (__glob_pattern_p): Likewise.
    	* posix/glob.c (glob): Likewise.
    	(glob_in_dir): Likewise.


commit 6e05025f557147feec2772f2e65a2f95baae0eee
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Jun 7 09:33:19 2017 -0300

    posix: More check for overflow allocation in glob
    This patch adds and replace the allocation overflow based using
    malloc internal functions check_add_wrapv_size_t and __libc_reallocarray.
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (glob_malloc_incr): New function.
    	(glob_malloc_incr2): Likewise.
    	(glob_realloc_incr): Likewise.
    	(glob): Use glob_{realloc,malloc}_incr{2}.


commit 89e7c2b0d336e51968484d187aa67b250bfbc7a2
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Jun 6 11:38:29 2017 -0300

    posix: Add common function to get home directory
    This patch adds a common function to get the full home directory
    from a user.  No functional changes expected.
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (get_home_directory): New function.
    	(glob): Use get_home_directory.


commit 5f9db2076c77c55d6b81cf38ea2621e7f71f59c1
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Jun 6 10:57:33 2017 -0300

    posix: Use char_array for home_dir in glob
    This patch uses char_array for home directory discovery.  It simplifies
    the buffer management.
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (glob): Use char_array for home directory.


commit 44684cd21876bde13fc3bed741f887ebff173d69
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jun 5 19:55:48 2017 -0300

    posix: Remove all alloca usage in glob
    With alloca usage removal from glob this patch wraps it up by removing
    all the alloca defines and macros usage.
    Checked on x86_64-linux-gnu.
    	posix/glob.c (glob_in_dir): Remove alloca_used argument.
    	(glob): Remove alloca_used.


commit 3a5cee0bfadd7f3b6b1a273570c25daecba731c9
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jun 5 19:41:58 2017 -0300

    posix: Use dynarray for globname in glob
    This patch uses dynarray at glob internal glob_in_dir function to manage
    the various matched patterns.  It simplify and removes all the boilerplate
    buffer managements required.  It also removes the glob_use_alloca, since
    it is not used anymore.
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (glob_use_alloca): Remove.
    	(glob_in_dir): Use dynarray for globnames.


commit 923c67dea223b7d2f02cbd8ccf7c588aaf439ba6
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jun 5 17:20:01 2017 -0300

    posix: Remove alloca usage on glob dirname
    This patch replaces the alloca/malloc usage for dirname creation
    by the char_array struct.
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (glob_in_dir): Remove alloca usage for fullname.
    	* malloc/char_array-skeleton.c (char_array_init_str): Remove unused
    	(char_array_append_str): Likewise.


commit 34f6a6e813fbb9d15895008157a4c3fe9f6a19d8
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jun 5 15:19:22 2017 -0300

    posix: Remove alloca usage for GLOB_BRACE on glob
    GNU GLOB_BRACE internal implementation constructs a new expression and
    calls glob recursively.  It then requires a possible large temporary
    buffer place the new pattern.
    This patch removes the alloca/malloc usage and replaces it with
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (glob): Remove alloca usage for onealt.


commit 5389d55d0488f71d7dbcda40c24b78d33fd960ec
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jun 5 12:31:21 2017 -0300

    posix: User LOGIN_NAME_MAX for all user name in glob
    This patch limits all user name obtained for GLOB_TILDE to max of
    LOGIN_NAME_MAX (256 on glibc) and remove all stack/malloc buffer
    handling boilerplate.
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (glob): Remove alloca usage on user_name for


commit 08530e743120416c3efd23e61920afc16e3dc5d7
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jun 5 12:12:38 2017 -0300

    posix: Remove glob GET_LOGIN_NAME_MAX usage
    Current glob implementation allows non limited user name for home
    directory construction on GLOB_TILDE case.  To accomplish it glob
    either construct a name on stack if size are small enough (based
    on current alloca_used) value in heap otherwise.
    There is no actual login to resize the buffer in case of the resizing
    the buffer in case of ERANGE, so a static buffer using glibc default
    LOGIN_NAME_MAX is suffice.
    Checked on x86_64-linux-gnu.
    	* posix/glob.c (LOGIN_NAME_MAX): Define if not defined.
    	(glob): Use static buffer for user_name on getlogin_r.


commit a192083bb599321a0d16ca31978d6be3f8f857ff
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Sun Jun 4 16:53:20 2017 -0300

    posix: Use char_array for internal glob dirname
    This is the first patch of the set to remove alloca usage on glob
    implementation.  Internal path to search for file might expand to a
    non static directory derived from pattern for some difference cases
    (GLOB_NOESCAPE, GNU GLOB_TILDE) and to allow a non-static dirname
    path glob uses a lot of boilerplate code to manage the buffer (which
    is either allocated using alloca or malloc depending both to size
    requested and the total alloca_used).
    The patch changes to use the char_array struct with the default size
    (256 bytes).  It simplifies all the allocation code by using char_array
    one and every internal buffer access is done using char_array provided
    functions.  No functional changes are expected.
    Checked on x86_64-linux-gnu.
    	* posix/globc.c (glob): Use char_array for dirname.


commit 7f028010854a13cecdbea14954ea97a94428bad7
Author: Florian Weimer <fweimer@redhat.com>
Date:   Sat Jun 3 20:22:24 2017 -0300

    posix: Rewrite to use struct scratch_buffer instead of extend_alloca
    This patch removes a lot of boilerplate code to manager buffers for
    Checked on x86_64-linux-gnu.
    	[BZ #18023]
    	* posix/glob.c (glob): Use struct scratch_buffer instead of


commit 782c40918fa3d3a161e4fe3014ea23c2bd170872
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Fri Jun 2 15:38:04 2017 -0300

    posix: Consolidate glob implementation
    This patch consolidates the glob implementation.  The main changes are:
      * Remove specific defines required for multiple compilation in same
        unit (GLOB_ONLY_P, NO_GLOB_PATTERN_P and GLOB_COMPAT_BUILD).  To allow
        using the same code to build compat version on Linux, extra units are
        used instead (oldglob.c).
      * Both globfree and GNU extension glob_pattern_p are now on their files.
        This simplifies the creation of compat symbol when required.
      * Also similar to glob/glob64, a new globfree64 is file is added with an
        empty implementatio as default.
      * On Linux all implementation now uses a default one with the exception
        of alpha (which requires a specific versioning) and s390-32 (which
        different than other 32 bits with support for v2.1 symbol does not
        add a compat symbol).
      * Move i386 olddirent.h header to Linux default directory, since it is
        the only header with this name and it is shared among different
        architectures (and used on compat glob symbol).
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    	* posix/Makefile (routines): Add globfree, globfree64, and
    	* posix/glob.c: Remove GLOB_ONLY_P, GLOB_COMPAT_BUILD, and
    	NO_GLOB_PATTERN_P define usage.
    	(globfree): Move to its own file.
    	(__glob_pattern_type): Likewise.
    	(__glob_pattern_p): Likewise.
    	* posix/glob_internal.h: New file.
    	* posix/glob_pattern_p.c: Likewise.
    	* posix/globfree.c: Likewise.
    	* posix/globfree64.c: Likewise.
    	* sysdeps/gnu/glob64.c: Remove file.
    	* sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add oldglob.
    	* sysdeps/unix/sysv/linux/alpha/Makefile [$(subdir) = posix]
    	(sysdep_routines): Remove rule.
    	* sysdeps/unix/sysv/linux/alpha/glob.c: Remove file.
    	* sysdeps/unix/sysv/linux/arm/glob64.c: Likewise.
    	* sysdeps/wordsize-64/glob.c: Likewise.
    	* sysdeps/unix/sysv/linux/m68k/glob64.c: Likewise.
    	* sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c: Likewise.
    	* sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c: Likewise.
    	* sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c: Likewise.
    	* sysdeps/unix/sysv/linux/wordsize-64/glob64.c: Likewise.
    	* sysdeps/unix/sysv/linux/x86_64/x32/glob.c: Likewise.
    	* sysdeps/wordsize-64/glob64.c: Likewise.
    	* sysdeps/unix/sysv/linux/alpha/glob64.c: New file.
    	* sysdeps/unix/sysv/linux/alpha/globfree.c: Likewise.
    	* sysdeps/unix/sysv/linux/glob.c: Likewise.
    	* sysdeps/unix/sysv/linux/glob64.c: Likewise.
    	* sysdeps/unix/sysv/linux/globfree.c: Likewise.
    	* sysdeps/unix/sysv/linux/globfree64.c: Likewise.
    	* sysdeps/unix/sysv/linux/i386/alphasort64.c: include olddirent.h
    	using relative path instead of absolute one.
    	* sysdeps/unix/sysv/linux/i386/getdents64.c: Likewise.
    	* sysdeps/unix/sysv/linux/i386/readdir64.c: Likewise.
    	* sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
    	* sysdeps/unix/sysv/linux/i386/versionsort64.c: Likewise.
    	* sysdeps/unix/sysv/linux/i386/olddirent.h: Move to ...
    	* sysdeps/unix/sysv/linux/olddirent.h: ... here.
    	* sysdeps/unix/sysv/linux/i386/glob64.c: Move to ...
    	* sysdeps/unix/sysv/linux/oldglob.c: ... here.
    	* sysdeps/unix/sysv/linux/i386/glob64.c: Remove file.
    	* sysdeps/unix/sysv/linux/oldglob.c: New file.
    	* sysdeps/unix/sysv/linux/s390/s390-32/glob64.c: New file.
    	* sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c: Likewise.


commit e0906fb5e1e3dd4ce487b8dc76e72035c21b9768
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed May 24 09:41:15 2017 -0300

    posix: Adjust glob tests to libsupport
    This patch adjust glob tests to use libsupport.  It also refactor some
    tests to move to a more meaningful file name and to gather similar tests
    in a common file:
      * move bug-glob3.c tests to tst-glob_basic.c.
      * move bug-glob2.c tests to tst-glob_memory.c
      * move common definitions to tst-glob_common.c.
    Checked on x86_64-linux-gnu.
    	* posix/Makefile (tests): Remove bug-glob2 and bug-glob3.  Add
    	tst-glob_basic and tst-glob_memory.
    	* posix/bug-glob3.c: Move to ...
    	* posix/tst-glob_basic.c: ... here.
    	* posix/bug-glob2.c: Move to ...
    	* posix/tst-glob_memory.c: ... here.
    	* posix/globtest.c: Use libsupport.
    	* posix/tst-gnuglob.c: Likewise.
    	* posix/tst-glob_common.c: New file.


commit c1ba9d146a5fd7522fa45f4309922f693e7470f5
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Fri May 19 12:39:47 2017 -0300

    posix: Allow glob to match dangling symlinks [BZ #866]
    This patch makes glob match dangling symlinks.  Compared to other glob
    implementation (*BSD, bash, musl, and other shells as well), GLIBC seems
    the be the only one that does not match dangling symlinks.  As for
    comment #5 in BZ #866, POSIX does not have any strict specification for
    dangling symlinks match and it is reasonable that trying to glob everything
    in a path should return all types of files (such as for a 'rm *').  Also,
    comment #7 shows even more example where GLIBC current behavior is
    I avoided adding another GNU specific flag to set this behavior and
    instead make it the default.  Although this change the semanthic from
    previous implementation, I think adding another compat symbol to be
    really unecessary as from aforementioned reasons (current behavior not
    defined in any standard, general idea of different implementation is
    to list dangling symbols).
    Checked on x86_64-linux-gnu.
    	* posix/Makefile (tests): Add tst-glob_symlinks and remove tst-glob3.
    	* posix/bug-glob1.c: Remove file.
    	* posix/glob.c (glob): Match dangling symlinks.
    	(link_exists2_p): Remove function.
    	(link_exists_p): Likewise.
    	* posix/tst-glob_symlinks.c: New file.
    	* sysdeps/gnu/glob64.c (__stat): Redefine to __lstat.
    	* sysdeps/unix/sysv/linux/i386/glob64.c (__stat): Likewise.


commit b80fb4bbc472522aeeafa148061a5a480300fb50
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed May 17 17:01:05 2017 -0300

    posix: Sync glob with gnulib [BZ #1062]
    This patch syncs posix/glob.c implementation with gnulib version
    1540f34.  The main differences to gnulib code:
      1. Commit 44c637c (Properly initialize glob structure with
         GLOB_BRACE|GLOB_DOOFFS) which fixes BZ# 20707.
      2. No inclusion of flexmember.h header and its usage on glob.
         The code is meant to be rewritten and header is unrequired in
         next patch in this set.
      3. An additional define (GLOB_COMPAT_BUILD) to avoid building
         size_and_wrapv and gblo_use_alloca twice on some configurations
         (i368 compat code) due multiple inclusion.
    The main changes are:
      - Header organization mostly due gnulib requirements.  It leads
        to some simplification and less conditional includes.
      - Use of glob_use_alloca with wraps up __libc_use_alloca with
        saturated math for the total size calculation.
      - Simplify some size allocation overflow calculation.
      - Some fixed on non supported glibc systems.
      - Some comments adjustments.
    The changes does not alter current glob internal semantic.  I also
    added a missing globfree on posix/globtest.c (it helps silence
    some valgrind or other memory profilers).
    	[BZ #1062]
    	* posix/glob.c: Sync with gnulib.
    	* posix/globtest.c (main): Add final globfree.
    	* sysdeps/unix/sysv/linux/i386/glob64.c (GLOB_COMPAT_BUILD):


commit 526d45c58ecbd329603c317bc5b80bfcfd6b08a1
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Jun 20 10:31:28 2017 -0300

    gconv: Replace norm_add_slashes with __gconv_norm_add_slashes
    2017-06-19  Florian Weimer  <fweimer@redhat.com>
    	    Adhemerval Zanella  <adhemerval.zanella@linaro.org>
    	* iconv/Makefile (routine): Add norm_add_slashes.
    	* iconv/norm_add_slashes.c: New file, extracted from
    	* iconv/gconv_int.h (norm_add_slashes): Remove.
    	(__gconv_norm_add_slashes): Declare.
    	* wcsmbs/wcsmbsload.c (__wcsmbs_load_conv): Use
    	* intl/dcigettext.c (_nl_find_msg): Likewise.  Simplify !_LIBC


commit e7ffd8ee94da45cb3433c29d36f4fd96bbd6b42a
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Mon Jun 5 21:21:46 2017 -0300

    malloc: Add specialized dynarray for C strings
    This patch adds an specialized dynarray to manage C strings using the
    dynarray internal implementation.  It uses some private fields from
    dynarray and thus it provided specific files to access and manage
    the internal string buffer.
       For instance:
       struct char_array str;
       // str == "testing"
       char_array_init_str (&str, "testing");
       // c == 's'
       char c = char_array_pos (&str, 2);
       // str = "testing2"
       char_array_set_str (&str, "testing2");
       // str = "testi"
       char_array_erase (&str, 5);
       // str = "123testi"
       char_array_prepend_str (&str, "123");
       // len = 8
       size_t len = char_array_length (&str);
       // str = "123testi456"
       char_array_append_str (&str, "456");
       // str = "123testi789"
       char_array_replace_str_pos (&str, 7, "789", 3);
    The provided function are not extensive and meant mainly to be use in
    subsequent glob implementation cleanup.  For internal object consistency
    only the function provided by char_array.c should be used, including
    internal object manipulation.
    To check for possible overflows in internal size manipulation a new
    function, check_add_wrapv_size_t, is added on malloc-internal.  It basically
    return whether the addition of two size_t overflows.
    Checked on x86_64-linux-gnu.
    	* malloc/Makefile (test-internal): Add tst-char_array.
    	(routines): Add dynarray_overflow_failure and char_array-impl.
    	* malloc/Versions [GLIBC_PRIVATE] (libc): Add
    	__libc_dynarray_overflow_failure, __char_array_set_str_size,
    	__char_array_erase, __char_array_prepend_str_size, and
    	* malloc/char_array-impl.c: New file.
    	* malloc/char_array-skeleton.c: Likewise.
    	* malloc/char_array.h: Likewise.
    	* malloc/tst-char-array.c: Likewise.
    	* malloc/dynarray_overflow_failure.c: Likewise.
    	* malloc/malloc-internal.h (check_add_overflow_size_t): New function.