Double-free Vulnerability in Logsurfer
- Advisory: DSB-2011-02
- Version: 1.0
- Released on: 2011-10-21
- Updated on: 2011-10-21
- Product: Logsurfer 1.5b and 1.7+
Logsurfer is affected by a double-free vulnerability in the function prepare_exec(). Exploitation allows to crash the program or even to execute arbitrary code with the privileges of logsurfer.
The program Logsurfer is designed to monitor any text-based logfile on systems in realtime. Gregor Kopf of Recurity Labs GmbH found a double-free vulnerability in Logsurfer affecting the function prepare_exec(). The vulnerability is caused by an insufficient treatment of an error condition that is returned by the function get_word() when it is unable to correctly parse its input. As a result, a heap buffer is double freed. An attacker is able to exploit this vulnerability by injecting specially crafted strings into a log-file that is processed by logsurfer. Exploitation allows to crash the program or even to execute arbitrary code with the privileges of logsurfer.
The vulnerability has been fixed in Logsurfer 1.8 (also includes Logsurfer+ branch) that will be released at the following websites
The vulnerability was found by Gregor Kopf of Recurity Labs GmbH. We thank Wolfgang Ley and Kerry Thompson for their comments and providing us with a software patch.
Workaround: Patch for logsurfer 1.5b (exec.c)
--- exec.c.1.5b 1999-08-03 12:10:29.000000000 +0200
+++ exec.c 2011-10-21 11:55:53.000000000 +0200
@@ -79,18 +79,22 @@ prepare_exec(cmdstring)
}
new_argc=0;
- src=cmdstring;
- /* suppress expanding of $var in the command line (already done) */
- old_matchnum=regex_submatches_num;
- while ( (new_argc < 255) && ((new_argv[new_argc++]=get_word(&src)) != NULL) )
- ;
- regex_submatches_num=old_matchnum;
- if ( (new_argc == 255) || (*(skip_spaces(src)) != '\0') )
- return(0);
- if ( (new_argv[new_argc]=(char *)malloc(sizeof(char))) == NULL )
- return(0);
- *new_argv[new_argc]='\0';
- return(1);
+ src=cmdstring;
+ /* suppress expanding of $var in the command line (already done) */
+ old_matchnum=regex_submatches_num;
+ while ( (new_argc < 255) && ((new_argv[new_argc++]=get_word(&src)) != NULL) )
+ ;
+ regex_submatches_num=old_matchnum;
+ if ( (new_argc == 255) || (*(skip_spaces(src)) != '\0') ) {
+ new_argc--;
+ return(0);
+ }
+ if ( (new_argv[new_argc]=(char *)malloc(sizeof(char))) == NULL ) {
+ new_argc--;
+ return(0);
+ }
+ *new_argv[new_argc]='\0';
+ return(1);
}