Bug 33814 (CVE-2025-15281) - wordexp with WRDE_REUSE and WRDE_APPEND may return uninitialized memory
Summary: wordexp with WRDE_REUSE and WRDE_APPEND may return uninitialized memory
Status: RESOLVED FIXED
Alias: CVE-2025-15281
Product: glibc
Classification: Unclassified
Component: glob (show other bugs)
Version: 2.2.5
: P2 normal
Target Milestone: 2.43
Assignee: Adhemerval Zanella
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-01-20 13:15 UTC by Carlos O'Donell
Modified: 2026-01-26 16:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
Project(s) to access:
ssh public key:
carlos: security+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Carlos O'Donell 2026-01-20 13:15:33 UTC
Calling wordexp with WRDE_REUSE in conjunction with WRDE_APPEND in the GNU C Library version 2.0 to version 2.42 may cause the interface to return uninitialized memory in the we_wordv member, which on subsequent calls to wordfree may abort the process.

The implementation of WRDE_REUSE in conjunction with WRDE_APPEND fails to clear the we_wordc member of the structure, and as such, when new words are added internally, a leading we_wordc count number of entries are skipped since they are assumed initialized.  These skipped entries are not initialized, but are the contents of a realloc-expanded array of pointers.  If the caller inspects the we_wordv array, it will dereference invalid pointers and crash. If the caller calls wordfree, the malloc implementation may detect the invalid pointers and abort the process.  Calls to wordexp using WRDE_REUSE and WRDE_APPEND have never worked correctly and thus the existence of applications that make use of this feature is unlikley.

CVE-Id: CVE-2025-15281
Public-Date: 2026-01-19
Vulnerable-Commit: 8f2ece695d8822e9ecc63ecd157e90bf17a6fe65

Reproducer:
#include <string.h>
#include <stdio.h>
#include <wordexp.h>

int main(void) {
    char trigger[] = "\xf3\xf3\xf3";
    wordexp_t p = {0};
    int flags = WRDE_NOCMD | WRDE_APPEND;
    wordexp(trigger, &p, flags);
    wordexp(trigger + 1, &p, flags | WRDE_REUSE);
    wordfree(&p);
    return 0;
}

Build: gcc -O0 -g3 -o test-wordexp test-wordexp.c

$ ./test-wordexp 
free(): invalid pointer
Aborted                    (core dumped) ./test-wordexp

$ valgrind ./test-wordexp
==1500600== Conditional jump or move depends on uninitialised value(s)
==1500600==    at 0x49713C9: wordfree (wordexp.c:2190)
==1500600==    by 0x4004E7: main (test-wordexp.c:11)

Reported-by: Vitaly Simonovich
Comment 1 Carlos O'Donell 2026-01-20 13:16:52 UTC
There is no known application impact for this CVE, and the feature is generally non-functional with the two flags.
Comment 2 Carlos O'Donell 2026-01-20 13:19:28 UTC
(In reply to Carlos O'Donell from comment #0)
> Public-Date: 2026-01-19

This will be adjusted to 2026-01-20 since disclosure was today.
Comment 3 Sourceware Commits 2026-01-20 14:47:35 UTC
The master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=80cc58ea2de214f85b0a1d902a3b668ad2ecb302

commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Comment 4 Adhemerval Zanella 2026-01-20 14:48:23 UTC
Fixed on 2.43.
Comment 5 Sourceware Commits 2026-01-20 15:35:13 UTC
The release/2.42/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=cbf39c26b25801e9bc88499b4fd361ac172d4125

commit cbf39c26b25801e9bc88499b4fd361ac172d4125
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 6 Sourceware Commits 2026-01-20 16:03:54 UTC
The release/2.41/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=fb4db64a04ad6c96cd1fbb7e02eb59323b1f2ac2

commit fb4db64a04ad6c96cd1fbb7e02eb59323b1f2ac2
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 7 Sourceware Commits 2026-01-20 16:39:42 UTC
The release/2.40/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9fe8576664d43b87ca19401fb6a975e217e47623

commit 9fe8576664d43b87ca19401fb6a975e217e47623
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 8 Sourceware Commits 2026-01-20 17:35:07 UTC
The release/2.39/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ce65d944e38a20cb70af2a48a4b8aa5d8fabe1cc

commit ce65d944e38a20cb70af2a48a4b8aa5d8fabe1cc
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 9 Sourceware Commits 2026-01-20 18:46:54 UTC
The release/2.38/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d5409a1be010699794264162c551ba60f05ee6c3

commit d5409a1be010699794264162c551ba60f05ee6c3
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 10 Sourceware Commits 2026-01-20 19:27:21 UTC
The release/2.37/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ff2b172803f6bbd897755d2ce83ec4323a1a15b3

commit ff2b172803f6bbd897755d2ce83ec4323a1a15b3
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 11 Sourceware Commits 2026-01-20 19:57:01 UTC
The release/2.36/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=e97cfe2293ed097eb3d0b4c18274d22855e65130

commit e97cfe2293ed097eb3d0b4c18274d22855e65130
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 12 Sourceware Commits 2026-01-20 20:26:31 UTC
The release/2.35/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=bb59339d02faebac534a87eea50c83c948f35b77

commit bb59339d02faebac534a87eea50c83c948f35b77
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 13 Sourceware Commits 2026-01-20 21:25:32 UTC
The release/2.34/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2b656ff94d72f93c84d8da2e7c76456c1994f02e

commit 2b656ff94d72f93c84d8da2e7c76456c1994f02e
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 14 Sourceware Commits 2026-01-21 13:00:30 UTC
The release/2.33/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=1d8ed2067a8a5d162a07670d0d063429679f17a0

commit 1d8ed2067a8a5d162a07670d0d063429679f17a0
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 15 Sourceware Commits 2026-01-21 14:20:45 UTC
The release/2.32/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=3a56c4ee4ea49b8f2391a2d8d6220013c4160a79

commit 3a56c4ee4ea49b8f2391a2d8d6220013c4160a79
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 16 Sourceware Commits 2026-01-21 16:27:01 UTC
The release/2.31/master branch has been updated by Adhemerval Zanella <azanella@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=28eb5caf895ced5d895cb02757e109004a2d33e5

commit 28eb5caf895ced5d895cb02757e109004a2d33e5
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 15 10:32:19 2026 -0300

    posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
    
    The wordexp fails to properly initialize the input wordexp_t when
    WRDE_REUSE is used. The wordexp_t struct is properly freed, but
    reuses the old wc_wordc value and updates the we_wordv in the
    wrong position.  A later wordfree will then call free with an
    invalid pointer.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302)
Comment 17 Sourceware Commits 2026-01-26 16:12:52 UTC
The master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=bed2db02f3183e93f21d506786c5f884a1dec9e7

commit bed2db02f3183e93f21d506786c5f884a1dec9e7
Author: Florian Weimer <fweimer@redhat.com>
Date:   Mon Jan 26 17:12:37 2026 +0100

    posix: Run tst-wordexp-reuse-mem test
    
    The test was not properly scheduled for execution with a Makefile
    dependency.
    
    Fixes commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302 ("posix: Reset
    wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814").