basic/xattr-util: do not cast ssize_t to int

gcc warns about unitialized memory access because it notices that ssize_t which
is < 0 could be cast to positive int value. We know that this can't really
happen because only -1 can be returned, but OTOH, in principle a large
*positive* value cannot be cast properly. This is unlikely too, since xattrs
cannot be too large, but it seems cleaner to just use a size_t to return the
value and avoid the cast altoghter. This makes the code simpler and gcc is
happy too.

The following warning goes away:
[113/1502] Compiling C object 'src/basic/basic@sta/xattr-util.c.o'.
In file included from ../src/basic/alloc-util.h:28:0,
                 from ../src/basic/xattr-util.c:30:
../src/basic/xattr-util.c: In function ‘fd_getcrtime_at’:
../src/basic/macro.h:207:60: warning: ‘b’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                 UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
                                                            ^
../src/basic/xattr-util.c:155:19: note: ‘b’ was declared here
         usec_t a, b;
                   ^
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2018-02-25 21:25:33 +01:00
parent 3554ef5177
commit e4de62591b
3 changed files with 30 additions and 14 deletions

View File

@ -107,7 +107,14 @@ int fgetxattr_malloc(int fd, const char *name, char **value) {
}
}
ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
int fgetxattrat_fake(
int dirfd,
const char *filename,
const char *attribute,
void *value, size_t size,
int flags,
size_t *ret_size) {
char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
_cleanup_close_ int fd = -1;
ssize_t l;
@ -134,7 +141,8 @@ ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute,
if (l < 0)
return -errno;
return l;
*ret_size = l;
return 0;
}
static int parse_crtime(le64_t le, usec_t *usec) {
@ -154,7 +162,7 @@ int fd_getcrtime_at(int dirfd, const char *name, usec_t *ret, int flags) {
struct_statx sx;
usec_t a, b;
le64_t le;
ssize_t n;
size_t n;
int r;
assert(ret);
@ -180,13 +188,13 @@ int fd_getcrtime_at(int dirfd, const char *name, usec_t *ret, int flags) {
else
a = USEC_INFINITY;
n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
if (n < 0)
r = -errno;
else if (n != sizeof(le))
r = -EIO;
else
r = parse_crtime(le, &b);
r = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags, &n);
if (r >= 0) {
if (n != sizeof(le))
r = -EIO;
else
r = parse_crtime(le, &b);
}
if (r < 0) {
if (a != USEC_INFINITY) {
*ret = a;

View File

@ -29,7 +29,13 @@
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
int fgetxattr_malloc(int fd, const char *name, char **value);
ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags);
int fgetxattrat_fake(
int dirfd,
const char *filename,
const char *attribute,
void *value, size_t size,
int flags,
size_t *ret_size);
int fd_setcrtime(int fd, usec_t usec);

View File

@ -36,8 +36,9 @@ static void test_fgetxattrat_fake(void) {
char t[] = "/var/tmp/xattrtestXXXXXX";
_cleanup_close_ int fd = -1;
const char *x;
char v[3] = {};
char v[3];
int r;
size_t size;
assert_se(mkdtemp(t));
x = strjoina(t, "/test");
@ -51,13 +52,14 @@ static void test_fgetxattrat_fake(void) {
fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
assert_se(fd >= 0);
assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0);
assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0, &size) >= 0);
assert_se(size == 3);
assert_se(memcmp(v, "bar", 3) == 0);
safe_close(fd);
fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
assert_se(fd >= 0);
assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA);
assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0, &size) == -ENODATA);
cleanup:
assert_se(unlink(x) >= 0);