Skip to content

Commit 1807ce4

Browse files
ptrrkssntridge
authored andcommitted
Fix handling of objects with many xattrs on FreeBSD
1 parent 9c175ac commit 1807ce4

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

lib/sysxattrs.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,26 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size)
126126
unsigned char keylen;
127127
ssize_t off, len = extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size);
128128

129-
if (len <= 0 || (size_t)len > size)
129+
if (len <= 0 || size == 0)
130130
return len;
131131

132+
if ((size_t)len >= size) {
133+
/* FreeBSD extattr_list_xx() returns 'size' as 'len' in case there are
134+
more data available, truncating the output, we solve this by signalling
135+
ERANGE in case len == size so that the code in xattrs.c will retry with
136+
a bigger buffer */
137+
errno = ERANGE;
138+
return -1;
139+
}
140+
132141
/* FreeBSD puts a single-byte length before each string, with no '\0'
133142
* terminator. We need to change this into a series of null-terminted
134143
* strings. Since the size is the same, we can simply transform the
135144
* output in place. */
136145
for (off = 0; off < len; off += keylen + 1) {
137146
keylen = ((unsigned char*)list)[off];
138147
if (off + keylen >= len) {
139-
/* Should be impossible, but kernel bugs happen! */
148+
/* Should be impossible, but bugs happen! */
140149
errno = EINVAL;
141150
return -1;
142151
}

0 commit comments

Comments
 (0)