Your message dated Tue, 15 Jul 2008 18:47:02 +0000
with message-id <[EMAIL PROTECTED]>
and subject line Bug#490921: fixed in afuse 0.2-3
has caused the Debian Bug report #490921,
regarding CVE-2008-2232: privilege escalation
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [EMAIL PROTECTED]
immediately.)


-- 
490921: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=490921
Debian Bug Tracking System
Contact [EMAIL PROTECTED] with problems
--- Begin Message ---
Package: afuse
Version: 0.2-2
Severity: grave
Tags: security
Justification: user security hole

Hi

A privilege escalation has been reported against afuse.
This issue is CVE-2008-2232.

Here is some additional information:

afuse accepts a command line of the form
  afuse /path -o mount_template="mount-script %m %r" \
      unmount_template="unmount-script %m %r"
It replaces %m with the mountpoint and %r with the next component of the
pathname being accessed.  These interpolated strings are inserted inside
double quotes, but metacharacters within them are not escaped.  The
resulting string is then passed to system() and executed by the shell.

Therefore, an attacker with read access to the afuse filesystem can gain
the privileges of its owner, using paths such as
  /path/";arbitrary command;"
  /path/`arbitrary command`

The patch attached is from the original is from the original reporter
Anders Kaseorg, please honour him in the changelog.

When you fix this issue, please mention the CVE id in your changelog.

Cheers
Steffen
diff -ur afuse-0.2.orig/src/afuse.c afuse-0.2/src/afuse.c
--- afuse-0.2.orig/src/afuse.c	2008-02-18 17:16:32.000000000 -0500
+++ afuse-0.2/src/afuse.c	2008-07-10 21:50:06.000000000 -0400
@@ -280,14 +280,19 @@
 }
 
 
-// !!FIXME!! allow escaping of %'s
 // Note: this method strips out quotes and applies them itself as should be appropriate
-char *expand_template(const char *template, const char *mount_point, const char *root_name)
+bool run_template(const char *template, const char *mount_point, const char *root_name)
 {
 	int len = 0;
+	int nargs = 1;
 	int i;
-	char *expanded_name;
-	char *expanded_name_start;
+	char *buf;
+	char *p;
+	char **args;
+	char **arg;
+	bool quote = false;
+	pid_t pid;
+	int status;
 
 	// calculate length
 	for(i = 0; template[i]; i++)
@@ -295,53 +300,100 @@
 			switch(template[i + 1])
 			{
 				case 'm':
-					len += strlen(mount_point) + 2;
+					len += strlen(mount_point);
 					i++;
 					break;
 				case 'r':
-					len += strlen(root_name) + 2;
+					len += strlen(root_name);
+					i++;
+					break;
+				case '%':
+					len++;
 					i++;
 					break;
 			}
-		} else if(template[i] != '"')
+		} else if(template[i] == ' ' && !quote) {
+			len++;
+			nargs++;
+		} else if(template[i] == '"')
+			quote = !quote;
+		else if(template[i] == '\\' && template[i + 1])
+			len++, i++;
+		else
 			len++;
 
-	expanded_name_start = expanded_name = my_malloc(len + 1);
+	buf = my_malloc(len + 1);
+	args = my_malloc((nargs + 1) * sizeof(*args));
+
+	p = buf;
+	arg = args;
+	*arg++ = p;
 
 	for(i = 0; template[i]; i++)
 		if(template[i] == '%') {
-			int j = 0;
 			switch(template[i + 1])
 			{
 				case 'm':
-					*expanded_name++ = '"';
-					while(mount_point[j])
-						*expanded_name++ = mount_point[j++];
-					*expanded_name++ = '"';
+					strcpy(p, mount_point);
+					p += strlen(mount_point);
 					i++;
 					break;
 				case 'r':
-					*expanded_name++ = '"';
-					while(root_name[j])
-						*expanded_name++ = root_name[j++];
-					*expanded_name++ = '"';
+					strcpy(p, root_name);
+					p += strlen(root_name);
+					i++;
+					break;
+				case '%':
+					*p++ = '%';
 					i++;
 					break;
 			}
-		} else if(template[i] != '"')
-			*expanded_name++ = template[i];
-
-	*expanded_name = '\0';
-
-	return expanded_name_start;
+		} else if(template[i] == ' ' && !quote) {
+			*p++ = '\0';
+			*arg++ = p;
+		} else if(template[i] == '"')
+			quote = !quote;
+		else if(template[i] == '\\' && template[i + 1])
+			*p++ = template[++i];
+		else
+			*p++ = template[i];
+
+	*p = '\0';
+	*arg = NULL;
+
+	pid = fork();
+	if(pid == -1) {
+		fprintf(stderr, "Failed to fork (%s)\n", strerror(errno));
+		free(args);
+		free(buf);
+		return false;
+	}
+	if(pid == 0) {
+		execvp(args[0], args);
+		abort();
+	}
+	pid = waitpid(pid, &status, 0);
+	if(pid == -1) {
+		fprintf(stderr, "Failed to waitpid (%s)\n", strerror(errno));
+		free(args);
+		free(buf);
+		return false;
+	}
+	if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+		fprintf(stderr, "Failed to invoke command: %s\n", args[0]);
+		free(args);
+		free(buf);
+		return false;
+	}
+	free(args);
+	free(buf);
+	return true;
 }
 
 mount_list_t *do_mount(const char *root_name)
 {
 	char *mount_point;
-	char *mount_command;
 	mount_list_t *mount;
-	int sysret;
 
 	fprintf(stderr, "Mounting: %s\n", root_name);
 
@@ -351,57 +403,33 @@
 		return NULL;
 	}
 
-	mount_command = expand_template(user_options.mount_command_template,
-	                                mount_point, root_name);
-	sysret = system(mount_command);
-
-	fprintf(stderr, "sysret: %.8x\n", sysret);
-
-	if(sysret) {
-		fprintf(stderr, "Failed to invoke mount command: '%s' (%s)\n",
-			mount_command, sysret != -1 ?
-				"Error executing mount" :
-				strerror(errno));
-
+	if(!run_template(user_options.mount_command_template,
+			 mount_point, root_name)) {
 		// remove the now unused directory
 		if( rmdir(mount_point) == -1 )
 			fprintf(stderr, "Failed to remove mount point dir: %s (%s)",
 				mount_point, strerror(errno));
 
-		free(mount_command);
 		free(mount_point);
 		return NULL;
 	}
 
 	mount = add_mount(root_name, mount_point);
-
-	free(mount_command);
 	return mount;
 }
 
 int do_umount(mount_list_t *mount)
 {
-	char *unmount_command;
-	int sysret;
-
 	fprintf(stderr, "Unmounting: %s\n", mount->root_name);
 
-	unmount_command = expand_template(user_options.unmount_command_template,
-	                                  mount->mount_point, mount->root_name);
-	sysret = system(unmount_command);
-	if(sysret) {
-		fprintf(stderr, "Failed to invoke unmount command: '%s' (%s)\n",
-		        unmount_command, sysret != -1 ?
-			               "Error executing mount" :
-				       strerror(errno));
-		/* Still unmount anyway */
-	}
+	run_template(user_options.unmount_command_template,
+		     mount->mount_point, mount->root_name);
+	/* Still unmount anyway */
 
 	if( rmdir(mount->mount_point) == -1 )
 		fprintf(stderr, "Failed to remove mount point dir: %s (%s)",
 				mount->mount_point, strerror(errno));
 	remove_mount(mount);
-	free(unmount_command);
 	return 1;
 }
 

--- End Message ---
--- Begin Message ---
Source: afuse
Source-Version: 0.2-3

We believe that the bug you reported is fixed in the latest version of
afuse, which is due to be installed in the Debian FTP archive:

afuse_0.2-3.diff.gz
  to pool/main/a/afuse/afuse_0.2-3.diff.gz
afuse_0.2-3.dsc
  to pool/main/a/afuse/afuse_0.2-3.dsc
afuse_0.2-3_i386.deb
  to pool/main/a/afuse/afuse_0.2-3_i386.deb



A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [EMAIL PROTECTED],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Varun Hiremath <[EMAIL PROTECTED]> (supplier of updated afuse package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [EMAIL PROTECTED])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Format: 1.8
Date: Wed, 16 Jul 2008 00:06:59 +0530
Source: afuse
Binary: afuse
Architecture: source i386
Version: 0.2-3
Distribution: unstable
Urgency: high
Maintainer: Varun Hiremath <[EMAIL PROTECTED]>
Changed-By: Varun Hiremath <[EMAIL PROTECTED]>
Description: 
 afuse      - automounting file system implemented in user-space using FUSE
Closes: 490921
Changes: 
 afuse (0.2-3) unstable; urgency=high
 .
   * Security fix for CVE-2008-2232: Add afuse-template-tokenize.diff patch
     to fix potential privilege escalation caused by unescaped
     meta-characters in path. Thanks to Anders Kaseorg for the
     patch. (Closes: #490921)
   * Bump Standards-Version to 3.8.0
Checksums-Sha1: 
 48c440510d316104004d60aab98c276e1522a337 1140 afuse_0.2-3.dsc
 c01fdb74fc458c780c3181e2f9201a6071181c2d 4411 afuse_0.2-3.diff.gz
 aa36e345f8533add58bb4cfa9300dc83fb894dfe 16514 afuse_0.2-3_i386.deb
Checksums-Sha256: 
 8cdd4f4b0e2fd142ca3cc4a6254b9935d258cc117927767cd52d871269fdc938 1140 
afuse_0.2-3.dsc
 1755e5196bfc4b590bb7bb31ff67e225557dedf6ebb202d5a2ec40ba6863ec03 4411 
afuse_0.2-3.diff.gz
 138dd5d294df1abd21e2ca402c57bd13f238fcb615e8c1eec61bb6dbc4895594 16514 
afuse_0.2-3_i386.deb
Files: 
 7ab98f70e5f076ca4fcd66ecf4d6e6e9 1140 utils optional afuse_0.2-3.dsc
 9da55e79dcd4682a866bccd616cfe911 4411 utils optional afuse_0.2-3.diff.gz
 f1c9159ca9b1f403599873aa41601726 16514 utils optional afuse_0.2-3_i386.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIfO7wPEFSUMxFMZcRAtQ8AJ4nmeGiuEBEKIv0/gxvcgnElUqJ3ACePnYy
9wzt9UmCfQWlSxY9awSActo=
=+1VA
-----END PGP SIGNATURE-----



--- End Message ---

Reply via email to