1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-25 04:06:03 +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__
int top_running;
#endif
static unsigned int top_name_width = 15;
int output_methods;
char times_in_seconds = 0;
static int extra_newline;
@ -2294,9 +2293,7 @@ void generate_text_internal(char *p, int p_max_size,
#ifdef IOSTATS
case OBJ_top_io:
#endif
/* yes, passing top_name_width instead
* of p_max_size is intended here */
print_top(obj, p, top_name_width);
print_top(obj, p, p_max_size);
#endif /* __linux__ */
OBJ(tail) {
print_tailhead("tail", obj, p, p_max_size);
@ -5095,16 +5092,8 @@ char load_config_file(const char *f)
no_buffers = string_to_bool(value);
}
CONF("top_name_width") {
if (value) {
if (sscanf(value, "%u", &top_name_width) != 1) {
CONF_ERR;
}
} else {
if (set_top_name_width(value))
CONF_ERR;
}
if (top_name_width >= max_user_text) {
top_name_width = max_user_text - 1;
}
}
CONF("top_cpu_separate") {
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);
}
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 top_data *td = obj->data.opaque;
struct process **needed = 0;
int width;
if (!td)
return;
@ -963,53 +974,60 @@ void print_top(struct text_object *obj, char *p, int top_name_width)
return;
}
if (needed[td->num]) {
char *timeval;
switch (td->type) {
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);
break;
case TOP_CPU:
snprintf(p, 7, "%6.2f",
width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f",
needed[td->num]->amount);
break;
case TOP_PID:
snprintf(p, 6, "%5i",
width = MIN(p_max_size, 6);
snprintf(p, width, "%5i",
needed[td->num]->pid);
break;
case TOP_MEM:
/* Calculate a percentage of residential mem from total mem available.
* 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);
break;
case TOP_TIME:
width = MIN(p_max_size, 10);
timeval = format_time(
needed[td->num]->total_cpu_time, 9);
snprintf(p, 10, "%9s", timeval);
snprintf(p, width, "%9s", timeval);
free(timeval);
break;
case TOP_MEM_RES:
human_readable(needed[td->num]->rss,
p, 255);
p, p_max_size);
break;
case TOP_MEM_VSIZE:
human_readable(needed[td->num]->vsize,
p, 255);
p, p_max_size);
break;
#ifdef IOSTATS
case TOP_READ_BYTES:
human_readable(needed[td->num]->read_bytes / update_interval,
p, 255);
p, p_max_size);
break;
case TOP_WRITE_BYTES:
human_readable(needed[td->num]->write_bytes / update_interval,
p, 255);
p, p_max_size);
break;
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);
break;
#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 free_top(struct text_object *, int);
/* return zero on success, non-zero otherwise */
int set_top_name_width(const char *);
#endif /* _top_h_ */