1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-26 04:17:33 +00:00

fix potential buffer overflow when printing top values

This commit is contained in:
Phil Sutter 2009-11-16 22:43:59 +01:00
parent 9efa384bbc
commit 6f9bfe970a
3 changed files with 35 additions and 24 deletions

View File

@ -166,7 +166,6 @@ int top_io;
#ifdef __linux__ #ifdef __linux__
int top_running; int top_running;
#endif #endif
static unsigned int top_name_width = 15;
int output_methods; int output_methods;
char times_in_seconds = 0; char times_in_seconds = 0;
static int extra_newline; static int extra_newline;
@ -2294,9 +2293,7 @@ void generate_text_internal(char *p, int p_max_size,
#ifdef IOSTATS #ifdef IOSTATS
case OBJ_top_io: case OBJ_top_io:
#endif #endif
/* yes, passing top_name_width instead print_top(obj, p, p_max_size);
* of p_max_size is intended here */
print_top(obj, p, top_name_width);
#endif /* __linux__ */ #endif /* __linux__ */
OBJ(tail) { OBJ(tail) {
print_tailhead("tail", obj, p, p_max_size); print_tailhead("tail", obj, p, p_max_size);
@ -5095,17 +5092,9 @@ char load_config_file(const char *f)
no_buffers = string_to_bool(value); no_buffers = string_to_bool(value);
} }
CONF("top_name_width") { CONF("top_name_width") {
if (value) { if (set_top_name_width(value))
if (sscanf(value, "%u", &top_name_width) != 1) {
CONF_ERR; CONF_ERR;
} }
} else {
CONF_ERR;
}
if (top_name_width >= max_user_text) {
top_name_width = max_user_text - 1;
}
}
CONF("top_cpu_separate") { CONF("top_cpu_separate") {
cpu_separate = string_to_bool(value); cpu_separate = string_to_bool(value);
} }

View File

@ -935,11 +935,22 @@ static char *format_time(unsigned long timeval, const int width)
return strndup("<inf>", text_buffer_size); return strndup("<inf>", text_buffer_size);
} }
void print_top(struct text_object *obj, char *p, int top_name_width) static unsigned int top_name_width = 15;
/* return zero on success, non-zero otherwise */
int set_top_name_width(const char *s)
{
if (!s)
return 0;
return !(sscanf(s, "%u", &top_name_width) == 1);
}
void print_top(struct text_object *obj, char *p, int p_max_size)
{ {
struct information *cur = &info; struct information *cur = &info;
struct top_data *td = obj->data.opaque; struct top_data *td = obj->data.opaque;
struct process **needed = 0; struct process **needed = 0;
int width;
if (!td) if (!td)
return; return;
@ -963,53 +974,60 @@ void print_top(struct text_object *obj, char *p, int top_name_width)
return; return;
} }
if (needed[td->num]) { if (needed[td->num]) {
char *timeval; char *timeval;
switch (td->type) { switch (td->type) {
case TOP_NAME: case TOP_NAME:
snprintf(p, top_name_width + 1, "%-*s", top_name_width, width = MIN(p_max_size, (int)top_name_width + 1);
snprintf(p, width + 1, "%-*s", width,
needed[td->num]->name); needed[td->num]->name);
break; break;
case TOP_CPU: case TOP_CPU:
snprintf(p, 7, "%6.2f", width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f",
needed[td->num]->amount); needed[td->num]->amount);
break; break;
case TOP_PID: case TOP_PID:
snprintf(p, 6, "%5i", width = MIN(p_max_size, 6);
snprintf(p, width, "%5i",
needed[td->num]->pid); needed[td->num]->pid);
break; break;
case TOP_MEM: case TOP_MEM:
/* Calculate a percentage of residential mem from total mem available. /* Calculate a percentage of residential mem from total mem available.
* Since rss is bytes and memmax kilobytes, dividing by 10 suffices here. */ * Since rss is bytes and memmax kilobytes, dividing by 10 suffices here. */
snprintf(p, 7, "%6.2f", width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f",
(float) ((float)needed[td->num]->rss / cur->memmax) / 10); (float) ((float)needed[td->num]->rss / cur->memmax) / 10);
break; break;
case TOP_TIME: case TOP_TIME:
width = MIN(p_max_size, 10);
timeval = format_time( timeval = format_time(
needed[td->num]->total_cpu_time, 9); needed[td->num]->total_cpu_time, 9);
snprintf(p, 10, "%9s", timeval); snprintf(p, width, "%9s", timeval);
free(timeval); free(timeval);
break; break;
case TOP_MEM_RES: case TOP_MEM_RES:
human_readable(needed[td->num]->rss, human_readable(needed[td->num]->rss,
p, 255); p, p_max_size);
break; break;
case TOP_MEM_VSIZE: case TOP_MEM_VSIZE:
human_readable(needed[td->num]->vsize, human_readable(needed[td->num]->vsize,
p, 255); p, p_max_size);
break; break;
#ifdef IOSTATS #ifdef IOSTATS
case TOP_READ_BYTES: case TOP_READ_BYTES:
human_readable(needed[td->num]->read_bytes / update_interval, human_readable(needed[td->num]->read_bytes / update_interval,
p, 255); p, p_max_size);
break; break;
case TOP_WRITE_BYTES: case TOP_WRITE_BYTES:
human_readable(needed[td->num]->write_bytes / update_interval, human_readable(needed[td->num]->write_bytes / update_interval,
p, 255); p, p_max_size);
break; break;
case TOP_IO_PERC: case TOP_IO_PERC:
snprintf(p, 7, "%6.2f", width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f",
needed[td->num]->io_perc); needed[td->num]->io_perc);
break; break;
#endif #endif

View File

@ -145,4 +145,8 @@ int parse_top_args(const char *s, const char *arg, struct text_object *obj);
void print_top(struct text_object *, char *, int); void print_top(struct text_object *, char *, int);
void free_top(struct text_object *, int); void free_top(struct text_object *, int);
/* return zero on success, non-zero otherwise */
int set_top_name_width(const char *);
#endif /* _top_h_ */ #endif /* _top_h_ */