Bug 2455127 - [Security] Format String Vulnerability in nano's statusline() via errormessage Buffer
Summary: [Security] Format String Vulnerability in nano's statusline() via errormessag...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: nano
Version: 45
Hardware: x86_64
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Lukáš Zaoral
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-04-04 20:34 UTC by Michał Majchrowicz
Modified: 2026-05-13 21:26 UTC (History)
3 users (show)

Fixed In Version: nano-8.7.1-2.fc44 nano-8.5-3.fc43 nano-8.3-4.fc42
Clone Of:
Environment:
Last Closed: 2026-05-03 00:49:04 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Michał Majchrowicz 2026-04-04 20:34:55 UTC
Hello,

We have identified a format string vulnerability in
GNU nano 8.7 that leads to a confirmed memory corruption crash,
verified with AddressSanitizer.

This issue was identified by Michal Majchrowicz and Marcin Wyczechowski,
members of the AFINE Team.

=======================================================================

OVERVIEW

A format string vulnerability exists in the interaction between has_valid_path()
(src/files.c) and statusline() (src/winio.c). When a user opens a non-existent
file whose parent directory name contains printf format specifiers (e.g. %s),
nano stores the directory name verbatim as an ALERT-level error message on the
new buffer. When the user subsequently switches away from that buffer,
redecorate_after_switch() calls:

    statusline(ALERT, openfile->errormessage);

with NO additional arguments. The format string is the attacker-controlled
directory name, causing vsnprintf/vasnprintf to read garbage or poisoned values
off the stack, leading to a segmentation fault.

This was confirmed to produce an ASAN crash (SEGV on AddressSanitizer poison
pattern 0xf5f5f5f5f5f5f5f5) on x86-64 Linux with GCC 15.

CWE: CWE-134 (Use of Externally-Controlled Format String)

=======================================================================

AFFECTED CODE

src/files.c, function has_valid_path(), around lines 413-438:

    /* Directory existence check -- builds the ALERT message from the path */
    statusline(ALERT, _("Directory '%s' does not exist"), dirname);

This string is stored in openfile->errormessage.

src/winio.c, function statusline(), around lines 2331-2333:

    /* Stored when importance==ALERT, fmt==UNSPECIFIED,
       openfile->errormessage is NULL, and multiple buffers exist */
    openfile->errormessage = display_string;

src/files.c, function redecorate_after_switch(), line 581-582:

    if (openfile->errormessage != NULL)
        statusline(ALERT, openfile->errormessage);  /* format string, no args */

The stored message contains the literal dirname string (e.g.
"Directory '/tmp/%s%s%s%s%s%s%s%s%s%s/file' does not exist"), which is then
passed as the format argument with no corresponding arguments.

=======================================================================

REPRODUCTION STEPS

Requirements: Linux, GNU nano 8.7 built with ASAN+UBSAN, tmux.

1. Build nano with ASAN and the -DDEBUG flag (required to prevent nano's own
   SIGSEGV handler from intercepting the crash before ASAN can log it):

     ./configure CC=gcc \
         CFLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer \
                 -g -O1 -U_FORTIFY_SOURCE -DDEBUG"
     make -j$(nproc)

2. Create a wrapper script run_nano.sh:

     #!/bin/sh
     export ASAN_OPTIONS="detect_leaks=0:halt_on_error=1:log_path=/tmp/asan_nano"
     exec ./src/nano "/nonexistent_parent_%s%s%s%s%s%s%s%s%s%s/file.txt"

   chmod +x run_nano.sh

3. Launch nano via tmux (a PTY is required):

     tmux new-session -d -s test -x 120 -y 30 ./run_nano.sh

4. Wait ~1 second for nano to start, then switch to a second buffer and back:

     sleep 1
     tmux send-keys -t test Escape   # opens new buffer prompt
     sleep 0.5
     tmux send-keys -t test .        # dismiss / opens empty buffer

5. After a brief pause nano will crash. The tmux session will exit.

6. Inspect the ASAN log:

     cat /tmp/asan_nano.*

=======================================================================

ASAN CRASH LOG (captured on x86-64 Linux, GCC 15)

==<PID>==ERROR: AddressSanitizer: SEGV on unknown address 0xf5f5f5f5f5f5f5f5
(pc 0x... bp 0x... sp 0x... T0)
==<PID>==The signal is caused by a READ memory access.
    #0 0x... in vasnprintf
    #1 0x... in vsnzprintf src/definitions.h:...
    #2 0x... in rpl_vsnprintf
    #3 0x... in statusline src/winio.c:2320
    #4 0x... in redecorate_after_switch src/files.c:581
    #5 0x... in switch_to_next_buffer src/files.c:...
    #6 0x... in do_next_buffer src/files.c:...
    #7 0x... in do_input src/nano.c:...

0xf5f5f5f5f5f5f5f5 is ASAN's freed-heap poison pattern, confirming that
the format string read pointer values from the stack that pointed into
previously-freed (and now poisoned) heap memory.

=======================================================================

SUGGESTED FIX

In src/files.c, function redecorate_after_switch(), change line 582 from:

    statusline(ALERT, openfile->errormessage);

to:

    statusline(ALERT, "%s", openfile->errormessage);

This makes the format string a literal "%s" and passes the message as a
safe argument, eliminating the format string injection.

Additionally, a broader audit of all call sites where a stored string is
passed as the first argument to statusline() / statusbar() is recommended.

=======================================================================

DISCLOSURE POLICY

We follow a 90-day coordinated disclosure policy. We intend to publish our
findings 90 days from the date of this report,
or earlier if a fix is released and announced publicly. We are happy to
coordinate the timing with you and to review any proposed patches.

Please acknowledge receipt of this report at your earliest convenience.

Regards,
Michał Majchrowicz.

Reproducible: Always

Comment 1 Benno Schulenberg 2026-04-05 07:48:09 UTC
Already fixed in git, by commit 0b7328bce4 from four days ago (as a result of this report: https://lists.gnu.org/archive/html/nano-devel/2026-03/msg00027.html).  The fix will be released in version 9.0 next week.

Comment 2 Fedora Update System 2026-04-30 09:21:24 UTC
FEDORA-2026-fbeaecb457 (nano-8.3-4.fc42) has been submitted as an update to Fedora 42.
https://bodhi.fedoraproject.org/updates/FEDORA-2026-fbeaecb457

Comment 3 Fedora Update System 2026-04-30 09:21:29 UTC
FEDORA-2026-3111ffa11a (nano-8.7.1-2.fc44) has been submitted as an update to Fedora 44.
https://bodhi.fedoraproject.org/updates/FEDORA-2026-3111ffa11a

Comment 4 Fedora Update System 2026-04-30 09:21:31 UTC
FEDORA-2026-d0a0f1c3d2 (nano-8.5-3.fc43) has been submitted as an update to Fedora 43.
https://bodhi.fedoraproject.org/updates/FEDORA-2026-d0a0f1c3d2

Comment 5 Fedora Update System 2026-05-01 03:15:43 UTC
FEDORA-2026-3111ffa11a has been pushed to the Fedora 44 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2026-3111ffa11a`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2026-3111ffa11a

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 6 Fedora Update System 2026-05-01 03:45:38 UTC
FEDORA-2026-fbeaecb457 has been pushed to the Fedora 42 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2026-fbeaecb457`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2026-fbeaecb457

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 7 Fedora Update System 2026-05-01 04:02:47 UTC
FEDORA-2026-d0a0f1c3d2 has been pushed to the Fedora 43 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2026-d0a0f1c3d2`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2026-d0a0f1c3d2

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 8 Fedora Update System 2026-05-03 00:49:04 UTC
FEDORA-2026-3111ffa11a (nano-8.7.1-2.fc44) has been pushed to the Fedora 44 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 9 Fedora Update System 2026-05-07 01:08:58 UTC
FEDORA-2026-d0a0f1c3d2 (nano-8.5-3.fc43) has been pushed to the Fedora 43 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 10 Fedora Update System 2026-05-13 21:26:42 UTC
FEDORA-2026-fbeaecb457 (nano-8.3-4.fc42) has been pushed to the Fedora 42 stable repository.
If problem still persists, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.