Skip to content

Commit 1ff2288

Browse files
dhowellsgregkh
authored andcommitted
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: ec0328e ("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>
1 parent 169b803 commit 1ff2288

File tree

3 files changed

+5
-23
lines changed

3 files changed

+5
-23
lines changed

fs/fscache/cookie.c

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,6 @@ void fscache_free_cookie(struct fscache_cookie *cookie)
6969
}
7070
}
7171

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-
8572
/*
8673
* Set the index key in a cookie. The cookie struct has space for a 12-byte
8774
* key plus length and hash, but if that's not big enough, it's instead a
@@ -95,18 +82,13 @@ static int fscache_set_key(struct fscache_cookie *cookie,
9582
u32 *buf;
9683
int i;
9784

98-
cookie->key_len = index_key_len;
99-
10085
if (index_key_len > sizeof(cookie->inline_key)) {
10186
buf = kzalloc(index_key_len, GFP_KERNEL);
10287
if (!buf)
10388
return -ENOMEM;
10489
cookie->key = buf;
10590
} else {
10691
buf = (u32 *)cookie->inline_key;
107-
buf[0] = 0;
108-
buf[1] = 0;
109-
buf[2] = 0;
11092
}
11193

11294
memcpy(buf, index_key, index_key_len);
@@ -161,7 +143,7 @@ struct fscache_cookie *fscache_alloc_cookie(
161143
struct fscache_cookie *cookie;
162144

163145
/* allocate and initialise a cookie */
164-
cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL);
146+
cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
165147
if (!cookie)
166148
return NULL;
167149

@@ -192,6 +174,9 @@ struct fscache_cookie *fscache_alloc_cookie(
192174
cookie->netfs_data = netfs_data;
193175
cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET);
194176
cookie->type = def->type;
177+
spin_lock_init(&cookie->lock);
178+
spin_lock_init(&cookie->stores_lock);
179+
INIT_HLIST_HEAD(&cookie->backing_objects);
195180

196181
/* radix tree insertion won't use the preallocation pool unless it's
197182
* told it may not wait */

fs/fscache/internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ extern struct fscache_cache *fscache_select_cache_for_object(
5151
extern struct kmem_cache *fscache_cookie_jar;
5252

5353
extern void fscache_free_cookie(struct fscache_cookie *);
54-
extern void fscache_cookie_init_once(void *);
5554
extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *,
5655
const struct fscache_cookie_def *,
5756
const void *, size_t,

fs/fscache/main.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,7 @@ static int __init fscache_init(void)
143143

144144
fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
145145
sizeof(struct fscache_cookie),
146-
0,
147-
0,
148-
fscache_cookie_init_once);
146+
0, 0, NULL);
149147
if (!fscache_cookie_jar) {
150148
pr_notice("Failed to allocate a cookie jar\n");
151149
ret = -ENOMEM;

0 commit comments

Comments
 (0)