aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2016-09-01 05:12:00 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-09-01 05:12:00 -0400
commit7cb35119d067191ce9ebc380a599db0b03cbd9d9 (patch)
tree15168c61d1f884399b4acdb81eb19092e43b453b /fs/overlayfs
parent0eb45fc3bb7a2cf9c9c93d9e95986a841e5f4625 (diff)
ovl: listxattr: use strnlen()
Be defensive about what underlying fs provides us in the returned xattr list buffer. If it's not properly null terminated, bail out with a warning insead of BUG. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Cc: <stable@vger.kernel.org>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/inode.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 1878591f6a2d..c75625c1efa3 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -255,7 +255,8 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
255{ 255{
256 struct dentry *realdentry = ovl_dentry_real(dentry); 256 struct dentry *realdentry = ovl_dentry_real(dentry);
257 ssize_t res; 257 ssize_t res;
258 int off; 258 size_t len;
259 char *s;
259 const struct cred *old_cred; 260 const struct cred *old_cred;
260 261
261 old_cred = ovl_override_creds(dentry->d_sb); 262 old_cred = ovl_override_creds(dentry->d_sb);
@@ -265,17 +266,19 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
265 return res; 266 return res;
266 267
267 /* filter out private xattrs */ 268 /* filter out private xattrs */
268 for (off = 0; off < res;) { 269 for (s = list, len = res; len;) {
269 char *s = list + off; 270 size_t slen = strnlen(s, len) + 1;
270 size_t slen = strlen(s) + 1;
271 271
272 BUG_ON(off + slen > res); 272 /* underlying fs providing us with an broken xattr list? */
273 if (WARN_ON(slen > len))
274 return -EIO;
273 275
276 len -= slen;
274 if (ovl_is_private_xattr(s)) { 277 if (ovl_is_private_xattr(s)) {
275 res -= slen; 278 res -= slen;
276 memmove(s, s + slen, res - off); 279 memmove(s, s + slen, len);
277 } else { 280 } else {
278 off += slen; 281 s += slen;
279 } 282 }
280 } 283 }
281 284