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:
parent
e19b991bb0
commit
4e2ad6a698
@ -4,6 +4,11 @@ sysvinit (2.95) unreleased; urgency=low
|
||||
|
||||
* Fixed various typos and control codes in manual pages.
|
||||
Patch provided by Bjarni Ingi Gislason.
|
||||
* Patched pidof so that the -f flag does not print memory information
|
||||
from the stack when passed a specially crafted format string.
|
||||
Also prevent segfault when "%s" is used in a format string.
|
||||
Special characters for the format string can be found in the man
|
||||
page for pidof.
|
||||
|
||||
|
||||
sysvinit (2.94) released; urgency=low
|
||||
|
@ -69,8 +69,10 @@ Tells \fIpidof\fP to omit processes with that process id. The special
|
||||
pid \fB%PPID\fP can be used to name the parent process of the \fIpidof\fP
|
||||
program, in other words the calling shell or shell script.
|
||||
.IP "-f \fIformat\fP"
|
||||
Tells \fIpidof\fP to format the process ids in the given \fIprintf\fP style.
|
||||
Tells \fIpidof\fP to format the process IDs in the given \fIprintf\fP style string.
|
||||
For example \fB" -p%d"\fP is useful for \fIstrace\fP.
|
||||
The "%d" symbol is used as a place holder for the PID to be printed. A "\\n" can
|
||||
be used to cause a newline to be printed. For example \fB" %d\\n"\fP.
|
||||
.SH "EXIT STATUS"
|
||||
.TP
|
||||
.B 0
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user