Re: [SECURITY] Format String Vulnerability in GNU nano Buffer Error Message Display

Benno Schulenberg <[email protected]> Wed, 1 Apr 2026 12:29:48 +0200
Newsgroups gmane.editors.nano.devel
Message-ID <[email protected]>
Op 31-03-2026 om 21:26 schreef Jonathan Echavarria:
> *_Overview:_*
> A format string vulnerability exists in GNU nano's multi-buffer error message 
> handling. When a user opens multiple files at startup and one triggers an ALERT- 
> level error (such as permission denied), the pre-formatted error message is 
> stored and later passed directly as the format string argument to statusline() 
> when the user switches buffers.
> 
> If the filename contains printf format specifiers (for example: %s, %p, %n), 
> they are re interpreted by vsnprintf() on the second call, leading to stack 
> information disclosure, denial of service (crash), or /potentially/ arbitrary 
> memory writes on platforms where %n is not disabled.

Thanks for the report, the detailed recipes, and the suggested fix.

> *_Additional POC that results in a crash:_*
> ```sh
> touch '/tmp/evil_%s_%s_%s_%s.txt'
> chmod 000 '/tmp/evil_%s_%s_%s_%s.txt'
> nano /tmp/normal.txt '/tmp/evil_%s_%s_%s_%s.txt'
> # Press ALT+. to switch to the next buffer and trigger the crash
> ```

For me, nano crashes only when compiled with -fsanitize=address.  Without it,
nano just prints a little garbage.  For example:

   [ Error reading /tmp/evil_P�^G��Z_H=_(NULL)_(NULL).txt: Permission denied ]

> *_Suggested fix:_*
> ```diff
> --- a/src/files.c
> +++ b/src/files.c
> @@ -579,7 +579,7 @@ void redecorate_after_switch(void)
>    /* If the switched-to buffer gave an error during opening, show the message
>    * once; otherwise, indicate on the status bar which file we switched to. */
>    if (openfile->errormessage) {
> - statusline(ALERT, openfile->errormessage);
> + statusline(ALERT, "%s", openfile->errormessage);
>    free(openfile->errormessage);
>    openfile->errormessage = NULL;
>    } else
> ```

The above change has been pushed to master:

   https://cgit.git.savannah.gnu.org/cgit/nano.git/commit/?id=0b7328bc


> Considering hardening these additional call sites:
> - statusline(ALERT, strerror(errornumber));
> + statusline(ALERT, "%s", strerror(errornumber));

Are there any standard error messages that contain things like %s?
As I don't think there are, this kind of hardening looks unneeded.


Benno
OpenPGP_signature.asc (application/pgp-signature, 840 B)
-----BEGIN PGP SIGNATURE-----

wsF5BAABCAAjFiEEFo5vQpe/16ea/USWUUu+Lrjhlh8FAmnM85wFAwAAAAAACgkQUUu+Lrjhlh+/
DA//Q/57LNEmj31xWjVIs7zBdf5/YUTZlfeIdPZswpPQue6v1e5NlvJP6lm+5vZrqehNSquv1uj7
wjomKbP9e5+EGYGVeW/n0W4OFNT+YwuGxB3nVbZ9mqiWIc43lnO22Wo1AEqffeJjEYQnpZbEkjb3
tI/CQQlbTyn8dkOqUYqO5O8jYQnkgUAocnXJQvoEeNAweZTzlNX13pVBpWQp4peWK9veNQEtlHr8
RPhF2GefP+b2Y+nVoYzNCrfJJDu3a2O48FGNUEddYjTr8xCqtChHeTouNwHgc9N8gPU5HVX50O8D
/Kja7r94AhEyW2vOlgL8VqvlDA38hEWHJDFDOQZtvn03Hdf2mgmtN+QWtVMGVACZRYyyBlFnQ0Ik
gCUQ03O2TIadpNuYI9zS8EtU7N71DtPGOZ3RTJ1/MceS76l6fb8t9wn1p649y74j4gwdyq/s9Hsr
xxEou7ERjVx2EIH9DnYFm0KRt/CD/xTjfP6OVuuciQt9w+ZMMQ3hI9cqvLKkrtkbBizqvGrh5Fe2
Yq5DZfkaNCPNskssUE/b00XiOMS1x6erx9A94kLtMhSBYgr6FZz++SBHN51/zlFDkDJoUHp/sxsx
C1MHBlX3grneovE8+Ke9SxsXKvOYKtjkLPngLqF2ULJrcKJzardDWlsRcZ+BmTWE19PDYy8wFYFK
kqA=
=5IzC
-----END PGP SIGNATURE-----