aboutsummaryrefslogtreecommitdiffstats
path: root/xattrs.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2008-02-06 07:52:00 -0800
committerWayne Davison <wayned@samba.org>2008-02-06 07:52:00 -0800
commit71daa07fb1c791c0f5eba3fc1b615df3a46441fc (patch)
treeab9c4b28dea66dd66244f118dc245306f22e7f7a /xattrs.c
parent287bb276d551a967a98037a603794e46965604d3 (diff)
downloadandroid_external_rsync-71daa07fb1c791c0f5eba3fc1b615df3a46441fc.tar.gz
android_external_rsync-71daa07fb1c791c0f5eba3fc1b615df3a46441fc.tar.bz2
android_external_rsync-71daa07fb1c791c0f5eba3fc1b615df3a46441fc.zip
Make get_xattr_names() even safer at fetching the list of attr names.
Diffstat (limited to 'xattrs.c')
-rw-r--r--xattrs.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/xattrs.c b/xattrs.c
index 61d4f607..9eca6bdb 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -111,6 +111,7 @@ static int rsync_xal_compare_names(const void *x1, const void *x2)
static ssize_t get_xattr_names(const char *fname)
{
ssize_t list_len;
+ double arg;
if (!namebuf) {
namebuf_len = 1024;
@@ -119,39 +120,36 @@ static ssize_t get_xattr_names(const char *fname)
out_of_memory("get_xattr_names");
}
- /* The length returned includes all the '\0' terminators. */
- list_len = sys_llistxattr(fname, namebuf, namebuf_len);
- if (list_len > (ssize_t)namebuf_len) {
- list_len = -1;
- errno = ERANGE;
- }
- if (list_len >= 0)
- return list_len;
- if (errno == ENOTSUP)
- return 0;
- if (errno == ERANGE) {
- list_len = sys_llistxattr(fname, NULL, 0);
- if (list_len < 0) {
+ while (1) {
+ /* The length returned includes all the '\0' terminators. */
+ list_len = sys_llistxattr(fname, namebuf, namebuf_len);
+ if (list_len >= 0) {
+ if ((size_t)list_len <= namebuf_len)
+ break;
+ } else if (errno == ENOTSUP)
+ return 0;
+ else if (errno != ERANGE) {
+ arg = (double)namebuf_len;
+ got_error:
rsyserr(FERROR_XFER, errno,
- "get_xattr_names: llistxattr(\"%s\",0) failed",
- fname);
+ "get_xattr_names: llistxattr(\"%s\",%.0f) failed",
+ fname, arg);
return -1;
}
+ list_len = sys_llistxattr(fname, NULL, 0);
+ if (list_len < 0) {
+ arg = 0;
+ goto got_error;
+ }
if (namebuf_len)
free(namebuf);
namebuf_len = list_len + 1024;
namebuf = new_array(char, namebuf_len);
if (!namebuf)
out_of_memory("get_xattr_names");
- list_len = sys_llistxattr(fname, namebuf, namebuf_len);
- if (list_len >= 0)
- return list_len;
}
- rsyserr(FERROR_XFER, errno,
- "get_xattr_names: llistxattr(\"%s\",%ld) failed",
- fname, (long)namebuf_len);
- return -1;
+ return list_len;
}
/* On entry, the *len_ptr parameter contains the size of the extra space we