From 059ae8b512151c6390ec8430533555979cf2f183 Mon Sep 17 00:00:00 2001 From: Qualys Security Advisory Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] top: Prevent out-of-bounds writes in PUFF(). This patch prevents three problems: 1/ Because snprintf() returns "the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available", _eol may point past the end of _str and write out-of-bounds (in Batch mode). 2/ _eol is never checked against _str, so "while (*(--_eol) == ' ');" may point _eol below _str and write out-of-bounds (in Batch mode). 3/ Sanity-check Pseudo_row to protect the strcpy(). --- top/top.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/top/top.h b/top/top.h index 02e38749..046fc879 100644 --- a/top/top.h +++ b/top/top.h @@ -547,10 +547,11 @@ typedef struct WIN_t { . subject to optimization, thus MAY be discarded */ #define PUFF(fmt,arg...) do { \ char _str[ROWMAXSIZ], *_eol; \ - _eol = _str + snprintf(_str, sizeof(_str), fmt, ## arg); \ + const int _len = snprintf(_str, sizeof(_str), fmt, ## arg); \ + _eol = _str + (_len < 0 ? 0 : (size_t)_len >= sizeof(_str) ? sizeof(_str)-1 : (size_t)_len); \ if (Batch) { \ - while (*(--_eol) == ' '); *(++_eol) = '\0'; putp(_str); } \ - else { \ + while (_eol > _str && _eol[-1] == ' ') _eol--; *_eol = '\0'; putp(_str); } \ + else if (Pseudo_row >= 0 && Pseudo_row < Screen_rows) { \ char *_ptr = &Pseudo_screen[Pseudo_row * ROWMAXSIZ]; \ if (Pseudo_row + 1 < Screen_rows) ++Pseudo_row; \ if (!strcmp(_ptr, _str)) putp("\n"); \