commit a58d541cf4357ab0aa7ae5e21765de35f65c6177
Author: Jeff Garzik <j...@garzik.org>
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 <jgar...@redhat.com>

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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to