|
@@ -255,7 +255,8 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
|
|
|
{
|
|
|
struct dentry *realdentry = ovl_dentry_real(dentry);
|
|
|
ssize_t res;
|
|
|
- int off;
|
|
|
+ size_t len;
|
|
|
+ char *s;
|
|
|
const struct cred *old_cred;
|
|
|
|
|
|
old_cred = ovl_override_creds(dentry->d_sb);
|
|
@@ -265,17 +266,19 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
|
|
|
return res;
|
|
|
|
|
|
/* filter out private xattrs */
|
|
|
- for (off = 0; off < res;) {
|
|
|
- char *s = list + off;
|
|
|
- size_t slen = strlen(s) + 1;
|
|
|
+ for (s = list, len = res; len;) {
|
|
|
+ size_t slen = strnlen(s, len) + 1;
|
|
|
|
|
|
- BUG_ON(off + slen > res);
|
|
|
+ /* underlying fs providing us with an broken xattr list? */
|
|
|
+ if (WARN_ON(slen > len))
|
|
|
+ return -EIO;
|
|
|
|
|
|
+ len -= slen;
|
|
|
if (ovl_is_private_xattr(s)) {
|
|
|
res -= slen;
|
|
|
- memmove(s, s + slen, res - off);
|
|
|
+ memmove(s, s + slen, len);
|
|
|
} else {
|
|
|
- off += slen;
|
|
|
+ s += slen;
|
|
|
}
|
|
|
}
|
|
|
|