Commit 607566aeccde6ffccde5eef173ed0d277eec4a2d

Authored by Josh Boyer
Committed by Linus Torvalds
1 parent 8f4c344696

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 /*