]> git.baikalelectronics.ru Git - kernel.git/commitdiff
fscache: Fix incomplete initialisation of inline key space
authorDavid Howells <dhowells@redhat.com>
Wed, 17 Oct 2018 14:23:45 +0000 (15:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Oct 2018 09:32:21 +0000 (11:32 +0200)
The inline key in struct rxrpc_cookie is insufficiently initialized,
zeroing only 3 of the 4 slots, therefore an index_key_len between 13 and 15
bytes will end up hashing uninitialized memory because the memcpy only
partially fills the last buf[] element.

Fix this by clearing fscache_cookie objects on allocation rather than using
the slab constructor to initialise them.  We're going to pretty much fill
in the entire struct anyway, so bringing it into our dcache writably
shouldn't incur much overhead.

This removes the need to do clearance in fscache_set_key() (where we aren't
doing it correctly anyway).

Also, we don't need to set cookie->key_len in fscache_set_key() as we
already did it in the only caller, so remove that.

Fixes: aac5768a9525 ("fscache: Maintain a catalogue of allocated cookies")
Reported-by: syzbot+a95b989b2dde8e806af8@syzkaller.appspotmail.com
Reported-by: Eric Sandeen <sandeen@redhat.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/fscache/cookie.c
fs/fscache/internal.h
fs/fscache/main.c

index 83bfe04456b6a99a196c485830b2ba2bc7419dec..b52f1dcd5dea5733f03bfd10445d73a44a92f635 100644 (file)
@@ -69,19 +69,6 @@ void fscache_free_cookie(struct fscache_cookie *cookie)
        }
 }
 
-/*
- * initialise an cookie jar slab element prior to any use
- */
-void fscache_cookie_init_once(void *_cookie)
-{
-       struct fscache_cookie *cookie = _cookie;
-
-       memset(cookie, 0, sizeof(*cookie));
-       spin_lock_init(&cookie->lock);
-       spin_lock_init(&cookie->stores_lock);
-       INIT_HLIST_HEAD(&cookie->backing_objects);
-}
-
 /*
  * Set the index key in a cookie.  The cookie struct has space for a 12-byte
  * key plus length and hash, but if that's not big enough, it's instead a
@@ -95,8 +82,6 @@ static int fscache_set_key(struct fscache_cookie *cookie,
        u32 *buf;
        int i;
 
-       cookie->key_len = index_key_len;
-
        if (index_key_len > sizeof(cookie->inline_key)) {
                buf = kzalloc(index_key_len, GFP_KERNEL);
                if (!buf)
@@ -104,9 +89,6 @@ static int fscache_set_key(struct fscache_cookie *cookie,
                cookie->key = buf;
        } else {
                buf = (u32 *)cookie->inline_key;
-               buf[0] = 0;
-               buf[1] = 0;
-               buf[2] = 0;
        }
 
        memcpy(buf, index_key, index_key_len);
@@ -161,7 +143,7 @@ struct fscache_cookie *fscache_alloc_cookie(
        struct fscache_cookie *cookie;
 
        /* allocate and initialise a cookie */
-       cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL);
+       cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
        if (!cookie)
                return NULL;
 
@@ -192,6 +174,9 @@ struct fscache_cookie *fscache_alloc_cookie(
        cookie->netfs_data      = netfs_data;
        cookie->flags           = (1 << FSCACHE_COOKIE_NO_DATA_YET);
        cookie->type            = def->type;
+       spin_lock_init(&cookie->lock);
+       spin_lock_init(&cookie->stores_lock);
+       INIT_HLIST_HEAD(&cookie->backing_objects);
 
        /* radix tree insertion won't use the preallocation pool unless it's
         * told it may not wait */
index f83328a7f0482a6d63695779ef941a1532ebfed0..d6209022e96582f107f9226852ee45414b6b445c 100644 (file)
@@ -51,7 +51,6 @@ extern struct fscache_cache *fscache_select_cache_for_object(
 extern struct kmem_cache *fscache_cookie_jar;
 
 extern void fscache_free_cookie(struct fscache_cookie *);
-extern void fscache_cookie_init_once(void *);
 extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *,
                                                   const struct fscache_cookie_def *,
                                                   const void *, size_t,
index 7dce110bf17d04b1d6631c636c5c080f3939d201..30ad89db1efcc6c448823d020b88dfde5a5aa247 100644 (file)
@@ -143,9 +143,7 @@ static int __init fscache_init(void)
 
        fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
                                               sizeof(struct fscache_cookie),
-                                              0,
-                                              0,
-                                              fscache_cookie_init_once);
+                                              0, 0, NULL);
        if (!fscache_cookie_jar) {
                pr_notice("Failed to allocate a cookie jar\n");
                ret = -ENOMEM;