diff options
author | Vito Caputo <vcaputo@gnugeneration.com> | 2016-12-18 06:04:34 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@gnugeneration.com> | 2016-12-18 06:15:00 -0800 |
commit | c0c491486e6dc6112ffaa2eefacd0a324219b475 (patch) | |
tree | 1ab008af0e019e024076b2696d1e0682d5bf67be /src | |
parent | f92c2b443b380ddd17e5d9c9ac9a55e49cde444f (diff) |
overlay: fix bug with extraordinarily long argvs
This was a known bug, there's a TODO sitting right there noting it.
The items array was sized very large so it never triggered and was
forgotten about.
Running `make tags` in the linux kernel source steps on it though,
because it constructs a massive argv.
This just adds a bounds check so no crash occurs in argv2xtext().
I don't see the point of allocating memory for this as the TODO's
suggested, since any such argv is unlikely to fit in the overlay
anyways.
Also shrunk the max from 1024 to 512, which is still quite large.
Diffstat (limited to 'src')
-rw-r--r-- | src/overlay.c | 13 | ||||
-rw-r--r-- | src/vwm.h | 1 |
2 files changed, 8 insertions, 6 deletions
diff --git a/src/overlay.c b/src/overlay.c index 06d2de2..1ff8443 100644 --- a/src/overlay.c +++ b/src/overlay.c @@ -41,6 +41,7 @@ #define OVERLAY_GRAPH_MIN_HEIGHT (4 * OVERLAY_ROW_HEIGHT) #define OVERLAY_ISTHREAD_ARGV "~" /* use this string to mark threads in the argv field */ #define OVERLAY_NOCOMM_ARGV "#missed it!" /* use this string to substitute the command when missing in argv field */ +#define OVERLAY_MAX_ARGC 512 /* this is a huge amount */ /* libvmon */ @@ -184,7 +185,7 @@ static void shadow_row(vwm_t *vwm, vwm_xwindow_t *xwin, int row) /* simple helper to map the vmon per-proc argv array into an XTextItem array, deals with threads vs. processes and the possibility of the comm field not getting read in before the process exited... */ -static void argv2xtext(vmon_proc_t *proc, XTextItem *items, int *nr_items) /* XXX TODO: reallocate items when too small... */ +static void argv2xtext(vmon_proc_t *proc, XTextItem *items, int max_items, int *nr_items) { int i; int nr = 0; @@ -209,7 +210,7 @@ static void argv2xtext(vmon_proc_t *proc, XTextItem *items, int *nr_items) /* XX items[nr].font = None; nr++; - for (i = 1; i < ((vmon_proc_stat_t *)proc->stores[VMON_STORE_PROC_STAT])->argc; nr++, i++) { + for (i = 1; nr < max_items && i < ((vmon_proc_stat_t *)proc->stores[VMON_STORE_PROC_STAT])->argc; nr++, i++) { items[nr].chars = ((vmon_proc_stat_t *)proc->stores[VMON_STORE_PROC_STAT])->argv[i]; items[nr].nchars = strlen(((vmon_proc_stat_t *)proc->stores[VMON_STORE_PROC_STAT])->argv[i]); /* TODO: libvmon should inform us of the length */ items[nr].delta = 4; @@ -290,7 +291,7 @@ static void draw_heirarchy_row(vwm_t *vwm, vwm_xwindow_t *xwin, vmon_proc_t *pro vmon_proc_t *child; char str[256]; int str_len, str_width; - XTextItem items[1024]; /* XXX TODO: dynamically allocate this and just keep it at the high water mark.. create a struct to encapsulate this, nr_items, and alloc_items... */ + XTextItem items[OVERLAY_MAX_ARGC]; int nr_items; /* process heirarchy text and accompanying per-process details like wchan/pid/state... */ @@ -325,7 +326,7 @@ static void draw_heirarchy_row(vwm_t *vwm, vwm_xwindow_t *xwin, vmon_proc_t *pro str_width = XTextWidth(overlay_font, str, str_len); /* the process' comm label indented according to depth, followed with their respective argv's */ - argv2xtext(proc, items, &nr_items); + argv2xtext(proc, items, NELEMS(items), &nr_items); XDrawText(vwm->display, xwin->overlay.text_pixmap, text_gc, depth * (OVERLAY_ROW_HEIGHT / 2), (row + 1) * OVERLAY_ROW_HEIGHT - 3, /* dst x, y */ items, nr_items); @@ -444,7 +445,7 @@ static void draw_overlay_rest(vwm_t *vwm, vwm_xwindow_t *xwin, vmon_proc_t *proc double utime_delta, stime_delta; /* text variables */ - XTextItem items[1024]; /* XXX TODO: dynamically allocate this and just keep it at the high water mark.. create a struct to encapsulate this, nr_items, and alloc_items... */ + XTextItem items[OVERLAY_MAX_ARGC]; int nr_items; /* Some parts of this we must do on every sample to maintain coherence in the graphs, since they're incrementally kept @@ -506,7 +507,7 @@ static void draw_overlay_rest(vwm_t *vwm, vwm_xwindow_t *xwin, vmon_proc_t *proc xwin->overlay.snowflakes_cnt++; /* stamp the name (and whatever else we include) into overlay.text_picture */ - argv2xtext(proc, items, &nr_items); + argv2xtext(proc, items, NELEMS(items), &nr_items); XDrawText(vwm->display, xwin->overlay.text_pixmap, text_gc, 5, (xwin->overlay.heirarchy_end + 1) * OVERLAY_ROW_HEIGHT - 3,/* dst x, y */ items, nr_items); @@ -39,6 +39,7 @@ #define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) #define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) +#define NELEMS(_a) (sizeof(_a) / sizeof(_a[0])) typedef struct _vwm_window_t vwm_window_t; typedef struct _vwm_desktop_t vwm_desktop_t; |