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-----