[PATCH] tabled: fix key corruption

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



commit a58d541cf4357ab0aa7ae5e21765de35f65c6177
Author: Jeff Garzik <jeff@xxxxxxxxxx>
Date:   Sat Mar 6 17:44:51 2010 -0500

    tabled: fix key corruption due to string overrun
    
    When obtaining the path (and thus, the object key) from the URI, it went
    unnoticed that the URI-based strings are not null terminated, but instead
    length-delimited via a separate variable.  This resulted in incorrect keys
    being associated with each object, if the key contained spaces or other
    unusual chars.
    
    Signed-off-by: Jeff Garzik <jgarzik@xxxxxxxxxx>

diff --git a/server/bucket.c b/server/bucket.c
index 300a8a6..0acf987 100644
--- a/server/bucket.c
+++ b/server/bucket.c
@@ -376,34 +376,49 @@ static int bucket_find(DB_TXN *txn, const char *bucket, char *owner,
  * Parse the uri_path and return bucket and path, strndup-ed.
  * Returns true iff succeeded. Else, bucket and path are unchanged.
  */
-bool bucket_base(const char *uri_path, char **pbucket, char **ppath)
+bool bucket_base(const char *uri_path, size_t uri_path_len,
+		 char **pbucket, char **ppath)
 {
 	const char *p;
 	char *bucket, *path;
 
-	if (*uri_path != '/')
+	if (!uri_path_len || *uri_path != '/')
 		return false;
+
 	uri_path++;
+	uri_path_len--;
 
-	if (uri_path[0] == '\0') {
+	/* just a slash; no bucket, path == / */
+	if (uri_path_len == 0) {
 		bucket = NULL;
 		if ((path = strdup("/")) == NULL)
 			return false;
-	} else if ((p = strchr(uri_path, '/')) == NULL) {
-		if ((bucket = strdup(uri_path)) == NULL)
+	}
+	
+	/* no slash; just a bucket, no path, force path to / */
+	else if ((p = memchr(uri_path, '/', uri_path_len)) == NULL) {
+		if ((bucket = g_strndup(uri_path, uri_path_len)) == NULL)
 			return false;
 		if ((path = strdup("/")) == NULL) {	/* fake slash */
 			free(bucket);
 			return false;
 		}
-	} else {
-		if ((bucket = g_strndup(uri_path, p - uri_path)) == NULL)
+	}
+	
+	/* otherwise, bucket precedes first slash; path follows */
+	else {
+		size_t bucket_len = p - uri_path;
+
+		if ((bucket = g_strndup(uri_path, bucket_len)) == NULL)
 			return false;
-		if ((path = strdup(p)) == NULL) {	/* include slash */
+
+		/* include slash */
+		if ((path = g_strndup(p, uri_path_len - bucket_len)) == NULL) {
 			free(bucket);
 			return false;
 		}
 	}
+
 	*pbucket = bucket;
 	*ppath = path;
 	return true;
diff --git a/server/server.c b/server/server.c
index e5d356e..e0d785c 100644
--- a/server/server.c
+++ b/server/server.c
@@ -846,17 +846,19 @@ static bool cli_evt_http_req(struct client *cli, unsigned int events)
 
 	/* attempt to obtain bucket name from URI path */
 	if (!bucket)
-		buck_in_path = bucket_base(req->uri.path, &bucket, &path);
+		buck_in_path = bucket_base(req->uri.path, req->uri.path_len,
+					   &bucket, &path);
 	else
-		path = strdup(req->uri.path);
+		path = g_strndup(req->uri.path, req->uri.path_len);
 
 	if (!path)
 		path = strdup("/");
 	key = pathtokey(path);
 
 	if (debugging)
-		applog(LOG_INFO, "%s: method %s, path '%s', bucket '%s'",
-		       cli->addr_host, method, path, bucket);
+		applog(LOG_INFO,
+		       "%s: method %s, path '%s', key '%s', bucket '%s'",
+		       cli->addr_host, method, path, key, bucket);
 
 	if (auth) {
 		err = authcheck(&cli->req, buck_in_path? NULL: bucket, auth,
diff --git a/server/tabled.h b/server/tabled.h
index 91cccae..72bf20d 100644
--- a/server/tabled.h
+++ b/server/tabled.h
@@ -272,7 +272,8 @@ extern bool bucket_del(struct client *cli, const char *user, const char *bucket)
 extern bool bucket_add(struct client *cli, const char *user, const char *bucket);
 extern bool bucket_valid(const char *bucket);
 extern char *bucket_host(const char *host, const char *ourhost);
-extern bool bucket_base(const char *uri_path, char **pbucket, char **ppath);
+extern bool bucket_base(const char *uri_path, size_t uri_path_len,
+			char **pbucket, char **ppath);
 extern bool service_list(struct client *cli, const char *user);
 
 /* object.c */
--
To unsubscribe from this list: send the line "unsubscribe hail-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Fedora Clound]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux