Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fscache: Fix incomplete initialisation of inline key space

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: ec0328e46d6e ("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>

authored by

David Howells and committed by
Greg Kroah-Hartman
1ff22883 169b8033

+5 -23
+4 -19
fs/fscache/cookie.c
··· 70 70 } 71 71 72 72 /* 73 - * initialise an cookie jar slab element prior to any use 74 - */ 75 - void fscache_cookie_init_once(void *_cookie) 76 - { 77 - struct fscache_cookie *cookie = _cookie; 78 - 79 - memset(cookie, 0, sizeof(*cookie)); 80 - spin_lock_init(&cookie->lock); 81 - spin_lock_init(&cookie->stores_lock); 82 - INIT_HLIST_HEAD(&cookie->backing_objects); 83 - } 84 - 85 - /* 86 73 * Set the index key in a cookie. The cookie struct has space for a 12-byte 87 74 * key plus length and hash, but if that's not big enough, it's instead a 88 75 * pointer to a buffer containing 3 bytes of hash, 1 byte of length and then ··· 82 95 u32 *buf; 83 96 int i; 84 97 85 - cookie->key_len = index_key_len; 86 - 87 98 if (index_key_len > sizeof(cookie->inline_key)) { 88 99 buf = kzalloc(index_key_len, GFP_KERNEL); 89 100 if (!buf) ··· 89 104 cookie->key = buf; 90 105 } else { 91 106 buf = (u32 *)cookie->inline_key; 92 - buf[0] = 0; 93 - buf[1] = 0; 94 - buf[2] = 0; 95 107 } 96 108 97 109 memcpy(buf, index_key, index_key_len); ··· 143 161 struct fscache_cookie *cookie; 144 162 145 163 /* allocate and initialise a cookie */ 146 - cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL); 164 + cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL); 147 165 if (!cookie) 148 166 return NULL; 149 167 ··· 174 192 cookie->netfs_data = netfs_data; 175 193 cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET); 176 194 cookie->type = def->type; 195 + spin_lock_init(&cookie->lock); 196 + spin_lock_init(&cookie->stores_lock); 197 + INIT_HLIST_HEAD(&cookie->backing_objects); 177 198 178 199 /* radix tree insertion won't use the preallocation pool unless it's 179 200 * told it may not wait */
-1
fs/fscache/internal.h
··· 51 51 extern struct kmem_cache *fscache_cookie_jar; 52 52 53 53 extern void fscache_free_cookie(struct fscache_cookie *); 54 - extern void fscache_cookie_init_once(void *); 55 54 extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *, 56 55 const struct fscache_cookie_def *, 57 56 const void *, size_t,
+1 -3
fs/fscache/main.c
··· 143 143 144 144 fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar", 145 145 sizeof(struct fscache_cookie), 146 - 0, 147 - 0, 148 - fscache_cookie_init_once); 146 + 0, 0, NULL); 149 147 if (!fscache_cookie_jar) { 150 148 pr_notice("Failed to allocate a cookie jar\n"); 151 149 ret = -ENOMEM;