From cd8ba5670e21f8016e14efd247ed2dd6af887aea Mon Sep 17 00:00:00 2001 From: Qualys Security Advisory Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] top: Check graph_cpus, graph_mems, and summ_mscale. Otherwise they lead to out-of-bounds reads and format-string bugs. Since these variables are set/written to in several places (for example, config_file()), check them in the only place where they are read/used. Also, constify the static gtab[]s. --- top/top.c | 71 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/top/top.c b/top/top.c index 3a92544e..b73be426 100644 --- a/top/top.c +++ b/top/top.c @@ -5399,13 +5399,13 @@ static void summary_hlp (CPU_t *cpu, const char *pfx) { /* display some kinda' cpu state percentages (who or what is explained by the passed prefix) */ - if (Curwin->rc.graph_cpus) { - static struct { - const char *user, *syst, *type; - } gtab[] = { - { "%-.*s~7", "%-.*s~8", Graph_bars }, - { "%-.*s~4", "%-.*s~6", Graph_blks } - }; + static const struct { + const char *user, *syst, *type; + } gtab[] = { + { "%-.*s~7", "%-.*s~8", Graph_bars }, + { "%-.*s~4", "%-.*s~6", Graph_blks } + }; + if (Curwin->rc.graph_cpus >= 1 && (size_t)Curwin->rc.graph_cpus <= sizeof(gtab) / sizeof(gtab[0])) { char user[SMLBUFSIZ], syst[SMLBUFSIZ], dual[MEDBUFSIZ]; int ix = Curwin->rc.graph_cpus - 1; float pct_user = (float)(u_frme + n_frme) * scale, @@ -5520,32 +5520,33 @@ numa_nope: } // end: View_STATES // Display Memory and Swap stats - if (isROOM(View_MEMORY, 2)) { + static struct { + float div; + const char *fmts; + const char *label; + } scaletab[] = { + { 1, "%.0f ", NULL }, // kibibytes +#ifdef BOOST_MEMORY + { 1024.0, "%#.3f ", NULL }, // mebibytes + { 1024.0*1024, "%#.3f ", NULL }, // gibibytes + { 1024.0*1024*1024, "%#.3f ", NULL }, // tebibytes + { 1024.0*1024*1024*1024, "%#.3f ", NULL }, // pebibytes + { 1024.0*1024*1024*1024*1024, "%#.3f ", NULL } // exbibytes +#else + { 1024.0, "%#.1f ", NULL }, // mebibytes + { 1024.0*1024, "%#.1f ", NULL }, // gibibytes + { 1024.0*1024*1024, "%#.1f ", NULL }, // tebibytes + { 1024.0*1024*1024*1024, "%#.1f ", NULL }, // pebibytes + { 1024.0*1024*1024*1024*1024, "%#.1f ", NULL } // exbibytes +#endif + }; + if (isROOM(View_MEMORY, 2) && + Rc.summ_mscale >= 0 && (size_t)Rc.summ_mscale < sizeof(scaletab) / sizeof(scaletab[0])) { #define bfT(n) buftab[n].buf #define scT(e) scaletab[Rc.summ_mscale]. e #define mkM(x) (float)kb_main_ ## x / scT(div) #define mkS(x) (float)kb_swap_ ## x / scT(div) #define prT(b,z) { if (9 < snprintf(b, 10, scT(fmts), z)) b[8] = '+'; } - static struct { - float div; - const char *fmts; - const char *label; - } scaletab[] = { - { 1, "%.0f ", NULL }, // kibibytes -#ifdef BOOST_MEMORY - { 1024.0, "%#.3f ", NULL }, // mebibytes - { 1024.0*1024, "%#.3f ", NULL }, // gibibytes - { 1024.0*1024*1024, "%#.3f ", NULL }, // tebibytes - { 1024.0*1024*1024*1024, "%#.3f ", NULL }, // pebibytes - { 1024.0*1024*1024*1024*1024, "%#.3f ", NULL } // exbibytes -#else - { 1024.0, "%#.1f ", NULL }, // mebibytes - { 1024.0*1024, "%#.1f ", NULL }, // gibibytes - { 1024.0*1024*1024, "%#.1f ", NULL }, // tebibytes - { 1024.0*1024*1024*1024, "%#.1f ", NULL }, // pebibytes - { 1024.0*1024*1024*1024*1024, "%#.1f ", NULL } // exbibytes -#endif - }; struct { // 0123456789 // snprintf contents of each buf (after SK_Kb): 'nnnn.nnn 0' // and prT macro might replace space at buf[8] with: ------> + @@ -5561,13 +5562,13 @@ numa_nope: scaletab[5].label = N_txt(AMT_exxabyte_txt); } - if (w->rc.graph_mems) { - static struct { - const char *used, *misc, *swap, *type; - } gtab[] = { - { "%-.*s~7", "%-.*s~8", "%-.*s~8", Graph_bars }, - { "%-.*s~4", "%-.*s~6", "%-.*s~6", Graph_blks } - }; + static const struct { + const char *used, *misc, *swap, *type; + } gtab[] = { + { "%-.*s~7", "%-.*s~8", "%-.*s~8", Graph_bars }, + { "%-.*s~4", "%-.*s~6", "%-.*s~6", Graph_blks } + }; + if (w->rc.graph_mems >= 1 && (size_t)w->rc.graph_mems <= sizeof(gtab) / sizeof(gtab[0])) { char used[SMLBUFSIZ], util[SMLBUFSIZ], dual[MEDBUFSIZ]; float pct_used, pct_misc, pct_swap; int ix, num_used, num_misc;