Commit 607566aeccde6ffccde5eef173ed0d277eec4a2d
Committed by
Linus Torvalds
1 parent
8f4c344696
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
CacheFiles: Fix memory leak in cachefiles_check_auxdata error paths
In cachefiles_check_auxdata(), we allocate auxbuf but fail to free it if we determine there's an error or that the data is stale. Further, assigning the output of vfs_getxattr() to auxbuf->len gives problems with checking for errors as auxbuf->len is a u16. We don't actually need to set auxbuf->len, so keep the length in a variable for now. We shouldn't need to check the upper limit of the buffer as an overflow there should be indicated by -ERANGE. While we're at it, fscache_check_aux() returns an enum value, not an int, so assign it to an appropriately typed variable rather than to ret. Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> Signed-off-by: David Howells <dhowells@redhat.com> cc: Hongyi Jia <jiayisuse@gmail.com> cc: Milosz Tanski <milosz@adfin.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 15 additions and 14 deletions Side-by-side Diff
fs/cachefiles/xattr.c
... | ... | @@ -162,8 +162,9 @@ |
162 | 162 | int cachefiles_check_auxdata(struct cachefiles_object *object) |
163 | 163 | { |
164 | 164 | struct cachefiles_xattr *auxbuf; |
165 | + enum fscache_checkaux validity; | |
165 | 166 | struct dentry *dentry = object->dentry; |
166 | - unsigned int dlen; | |
167 | + ssize_t xlen; | |
167 | 168 | int ret; |
168 | 169 | |
169 | 170 | ASSERT(dentry); |
170 | 171 | |
171 | 172 | |
172 | 173 | |
... | ... | @@ -174,22 +175,22 @@ |
174 | 175 | if (!auxbuf) |
175 | 176 | return -ENOMEM; |
176 | 177 | |
177 | - auxbuf->len = vfs_getxattr(dentry, cachefiles_xattr_cache, | |
178 | - &auxbuf->type, 512 + 1); | |
179 | - if (auxbuf->len < 1) | |
180 | - return -ESTALE; | |
178 | + xlen = vfs_getxattr(dentry, cachefiles_xattr_cache, | |
179 | + &auxbuf->type, 512 + 1); | |
180 | + ret = -ESTALE; | |
181 | + if (xlen < 1 || | |
182 | + auxbuf->type != object->fscache.cookie->def->type) | |
183 | + goto error; | |
181 | 184 | |
182 | - if (auxbuf->type != object->fscache.cookie->def->type) | |
183 | - return -ESTALE; | |
185 | + xlen--; | |
186 | + validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen); | |
187 | + if (validity != FSCACHE_CHECKAUX_OKAY) | |
188 | + goto error; | |
184 | 189 | |
185 | - dlen = auxbuf->len - 1; | |
186 | - ret = fscache_check_aux(&object->fscache, &auxbuf->data, dlen); | |
187 | - | |
190 | + ret = 0; | |
191 | +error: | |
188 | 192 | kfree(auxbuf); |
189 | - if (ret != FSCACHE_CHECKAUX_OKAY) | |
190 | - return -ESTALE; | |
191 | - | |
192 | - return 0; | |
193 | + return ret; | |
193 | 194 | } |
194 | 195 | |
195 | 196 | /* |