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+

Summary

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.

Vulnerability Details (CVE-2011-3626)

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.

Affected Versions

  • Logsurfer 1.5b and previous versions
  • Logsurfer+ 1.7 and previous versions

Solution

The vulnerability has been fixed in Logsurfer 1.8 (also includes Logsurfer+ branch) that will be released at the following websites

http://www.crypt.gen.nz/logsurfer/

https://sourceforge.net/projects/logsurfer/

Credits

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.

                --- 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);
 }