Fixed segfault in pidof when the -f (format) flag is used with

crafted format strings.
Avoid printing stack memory when special format string is passed
to -f.
Listed control characters for -f flag in manual page.
This commit is contained in:
Jesse Smith
2019-03-18 18:09:24 -03:00
parent e19b991bb0
commit 4e2ad6a698
3 changed files with 84 additions and 2 deletions

View File

@@ -985,6 +985,66 @@ void nsyslog(int pri, char *fmt, ...)
#define PIDOF_NETFS 0x04
#define PIDOF_QUIET 0x08
/* Replace elements (from) of the original string
with new elements (to).
Returns the new string on success or NULL on failure.
Free the returnedstring after use.
*/
char *Replace_String(char *from, char *to, char *original)
{
int from_length, to_length;
int source_length, destination_length;
int replace_count = 0;
char *replace_position;
char *destination_string;
char *source_position, *destination_position;
if ( (! from) || (! to) || (! original) )
return NULL;
from_length = strlen(from);
to_length = strlen(to);
source_length = strlen(original);
replace_position = strstr(original, from);
/* There is nothing to replace, return original string */
if (! replace_position)
return strdup(original);
/* count number of times we need to perform replacement */
while (replace_position)
{
replace_count++;
replace_position++;
replace_position = strstr(replace_position, from);
}
/* calculate length and allocate the new string */
destination_length = source_length + ( (to_length - from_length) * replace_count);
destination_string = calloc(destination_length, sizeof(char));
if (! destination_string)
return NULL;
/* Copy source string up to the part we need to replace. Then jump over the replaced bit */
source_position = original;
destination_position = destination_string;
replace_position = strstr(original, from);
while (replace_position)
{
for ( ; source_position < replace_position; source_position++)
{
destination_position[0] = source_position[0];
destination_position++;
}
strcat(destination_position, to);
source_position += from_length;
destination_position += to_length;
replace_position = strstr(source_position, from);
}
/* Replaced all the items, now copy the tail end of the original string */
strcat(destination_position, source_position);
return destination_string;
}
/*
* Pidof functionality.
*/
@@ -1119,7 +1179,22 @@ int main_pidof(int argc, char **argv)
if ( ~flags & PIDOF_QUIET ) {
if (format)
printf(format, p->pid);
{
char *show_string, *final_string;
char my_pid[32];
snprintf(my_pid, 32, "%d", p->pid);
show_string = Replace_String("%d", my_pid, format);
final_string = Replace_String("\\n", "\n", show_string);
if (show_string) free(show_string);
if (final_string)
{
printf("%s", final_string);
free(final_string);
}
else
fprintf(stderr, "Cannot handle format provided by -f\n");
/* printf(format, p->pid); */
}
else
{
if (! first)