mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-12-26 20:31:17 +00:00
fix potential buffer overflow when printing top values
This commit is contained in:
parent
9efa384bbc
commit
6f9bfe970a
15
src/conky.c
15
src/conky.c
@ -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);
|
||||||
}
|
}
|
||||||
|
40
src/top.c
40
src/top.c
@ -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
|
||||||
|
@ -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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user