summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-10-17 10:23:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-18 05:32:21 -0400
commit1ff22883b0b2f7a73eb2609ffe879c9fd96f6328 (patch)
tree113747086e8d148ccd64a1cfcec97f10f558071e
parent169b803397499be85bdd1e3d07d6f5e3d4bd669e (diff)
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>
-rw-r--r--fs/fscache/cookie.c23
-rw-r--r--fs/fscache/internal.h1
-rw-r--r--fs/fscache/main.c4
3 files changed, 5 insertions, 23 deletions
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index 83bfe04456b6..b52f1dcd5dea 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -70,19 +70,6 @@ void fscache_free_cookie(struct fscache_cookie *cookie)
70} 70}
71 71
72/* 72/*
73 * initialise an cookie jar slab element prior to any use
74 */
75void 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 * Set the index key in a cookie. The cookie struct has space for a 12-byte 73 * Set the index key in a cookie. The cookie struct has space for a 12-byte
87 * key plus length and hash, but if that's not big enough, it's instead a 74 * key plus length and hash, but if that's not big enough, it's instead a
88 * pointer to a buffer containing 3 bytes of hash, 1 byte of length and then 75 * pointer to a buffer containing 3 bytes of hash, 1 byte of length and then
@@ -95,8 +82,6 @@ static int fscache_set_key(struct fscache_cookie *cookie,
95 u32 *buf; 82 u32 *buf;
96 int i; 83 int i;
97 84
98 cookie->key_len = index_key_len;
99
100 if (index_key_len > sizeof(cookie->inline_key)) { 85 if (index_key_len > sizeof(cookie->inline_key)) {
101 buf = kzalloc(index_key_len, GFP_KERNEL); 86 buf = kzalloc(index_key_len, GFP_KERNEL);
102 if (!buf) 87 if (!buf)
@@ -104,9 +89,6 @@ static int fscache_set_key(struct fscache_cookie *cookie,
104 cookie->key = buf; 89 cookie->key = buf;
105 } else { 90 } else {
106 buf = (u32 *)cookie->inline_key; 91 buf = (u32 *)cookie->inline_key;
107 buf[0] = 0;
108 buf[1] = 0;
109 buf[2] = 0;
110 } 92 }
111 93
112 memcpy(buf, index_key, index_key_len); 94 memcpy(buf, index_key, index_key_len);
@@ -161,7 +143,7 @@ struct fscache_cookie *fscache_alloc_cookie(
161 struct fscache_cookie *cookie; 143 struct fscache_cookie *cookie;
162 144
163 /* allocate and initialise a cookie */ 145 /* 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);
165 if (!cookie) 147 if (!cookie)
166 return NULL; 148 return NULL;
167 149
@@ -192,6 +174,9 @@ struct fscache_cookie *fscache_alloc_cookie(
192 cookie->netfs_data = netfs_data; 174 cookie->netfs_data = netfs_data;
193 cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET); 175 cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET);
194 cookie->type = def->type; 176 cookie->type = def->type;
177 spin_lock_init(&cookie->lock);
178 spin_lock_init(&cookie->stores_lock);
179 INIT_HLIST_HEAD(&cookie->backing_objects);
195 180
196 /* radix tree insertion won't use the preallocation pool unless it's 181 /* radix tree insertion won't use the preallocation pool unless it's
197 * told it may not wait */ 182 * told it may not wait */
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index f83328a7f048..d6209022e965 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -51,7 +51,6 @@ extern struct fscache_cache *fscache_select_cache_for_object(
51extern struct kmem_cache *fscache_cookie_jar; 51extern struct kmem_cache *fscache_cookie_jar;
52 52
53extern void fscache_free_cookie(struct fscache_cookie *); 53extern void fscache_free_cookie(struct fscache_cookie *);
54extern void fscache_cookie_init_once(void *);
55extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *, 54extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *,
56 const struct fscache_cookie_def *, 55 const struct fscache_cookie_def *,
57 const void *, size_t, 56 const void *, size_t,
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
index 7dce110bf17d..30ad89db1efc 100644
--- a/fs/fscache/main.c
+++ b/fs/fscache/main.c
@@ -143,9 +143,7 @@ static int __init fscache_init(void)
143 143
144 fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar", 144 fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
145 sizeof(struct fscache_cookie), 145 sizeof(struct fscache_cookie),
146 0, 146 0, 0, NULL);
147 0,
148 fscache_cookie_init_once);
149 if (!fscache_cookie_jar) { 147 if (!fscache_cookie_jar) {
150 pr_notice("Failed to allocate a cookie jar\n"); 148 pr_notice("Failed to allocate a cookie jar\n");
151 ret = -ENOMEM; 149 ret = -ENOMEM;