Merge "Add O_PATH support for flistxattr()"

This commit is contained in:
Nick Kralevich 2015-06-08 17:39:00 +00:00 committed by Gerrit Code Review
commit 12fb28bbd8
10 changed files with 108 additions and 13 deletions

View File

@ -130,6 +130,7 @@ libc_bionic_ndk_src_files := \
bionic/fchmodat.cpp \
bionic/ffs.cpp \
bionic/fgetxattr.cpp \
bionic/flistxattr.cpp \
bionic/flockfile.cpp \
bionic/fpclassify.cpp \
bionic/fsetxattr.cpp \

View File

@ -124,7 +124,7 @@ int fchown:fchown(int, uid_t, gid_t) arm64,mips,mips64,x86_64
void sync(void) all
int ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
ssize_t ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all
ssize_t flistxattr(int, char*, size_t) all
ssize_t ___flistxattr:flistxattr(int, char*, size_t) all
int fremovexattr(int, const char*) all
int __getdents64:getdents64(unsigned int, struct dirent*, unsigned int) arm,arm64,mips,mips64,x86,x86_64

View File

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(flistxattr)
ENTRY(___flistxattr)
mov ip, r7
ldr r7, =__NR_flistxattr
swi #0
@ -11,4 +11,5 @@ ENTRY(flistxattr)
bxls lr
neg r0, r0
b __set_errno_internal
END(flistxattr)
END(___flistxattr)
.hidden ___flistxattr

View File

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(flistxattr)
ENTRY(___flistxattr)
mov x8, __NR_flistxattr
svc #0
@ -11,4 +11,5 @@ ENTRY(flistxattr)
b.hi __set_errno_internal
ret
END(flistxattr)
END(___flistxattr)
.hidden ___flistxattr

View File

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(flistxattr)
ENTRY(___flistxattr)
.set noreorder
.cpload t9
li v0, __NR_flistxattr
@ -16,4 +16,5 @@ ENTRY(flistxattr)
j t9
nop
.set reorder
END(flistxattr)
END(___flistxattr)
.hidden ___flistxattr

View File

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(flistxattr)
ENTRY(___flistxattr)
.set push
.set noreorder
li v0, __NR_flistxattr
@ -22,4 +22,5 @@ ENTRY(flistxattr)
j t9
move ra, t0
.set pop
END(flistxattr)
END(___flistxattr)
.hidden ___flistxattr

View File

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(flistxattr)
ENTRY(___flistxattr)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
@ -28,4 +28,5 @@ ENTRY(flistxattr)
popl %ecx
popl %ebx
ret
END(flistxattr)
END(___flistxattr)
.hidden ___flistxattr

View File

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(flistxattr)
ENTRY(___flistxattr)
movl $__NR_flistxattr, %eax
syscall
cmpq $-MAX_ERRNO, %rax
@ -12,4 +12,5 @@ ENTRY(flistxattr)
call __set_errno_internal
1:
ret
END(flistxattr)
END(___flistxattr)
.hidden ___flistxattr

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
extern "C" ssize_t ___flistxattr(int, char*, size_t);
ssize_t flistxattr(int fd, char *list, size_t size) {
int saved_errno = errno;
ssize_t result = ___flistxattr(fd, list, size);
if ((result != -1) || (errno != EBADF)) {
return result;
}
// fd could be an O_PATH file descriptor, and the kernel
// may not directly support fgetxattr() on such a file descriptor.
// Use /proc/self/fd instead to emulate this support.
int fd_flag = fcntl(fd, F_GETFL);
if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) {
errno = EBADF;
return -1;
}
char buf[40];
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
errno = saved_errno;
return listxattr(buf, list, size);
}

View File

@ -80,6 +80,7 @@ TEST(sys_xattr, fsetxattr_with_opath) {
ASSERT_EQ(-1, res);
ASSERT_EQ(EBADF, errno);
#endif
close(fd);
}
TEST(sys_xattr, fsetxattr_with_opath_toosmall) {
@ -97,4 +98,32 @@ TEST(sys_xattr, fsetxattr_with_opath_toosmall) {
ASSERT_EQ(-1, res);
ASSERT_EQ(EBADF, errno);
#endif
close(fd);
}
TEST(sys_xattr, flistattr) {
TemporaryFile tf;
char buf[65536]; // 64kB is max possible xattr list size. See "man 7 xattr".
ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "bar", 4, 0));
ssize_t result = flistxattr(tf.fd, buf, sizeof(buf));
ASSERT_TRUE(result >= 9);
ASSERT_TRUE(memmem(buf, sizeof(buf), "user.foo", 9) != NULL);
}
TEST(sys_xattr, flistattr_opath) {
TemporaryFile tf;
char buf[65536]; // 64kB is max possible xattr list size. See "man 7 xattr".
ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "bar", 4, 0));
int fd = open(tf.filename, O_PATH);
ASSERT_NE(-1, fd);
ssize_t res = flistxattr(fd, buf, sizeof(buf));
#if defined(__BIONIC__)
ASSERT_TRUE(res >= 9);
ASSERT_TRUE(static_cast<size_t>(res) <= sizeof(buf));
ASSERT_TRUE(memmem(buf, res, "user.foo", 9) != NULL);
#else
ASSERT_EQ(-1, res);
ASSERT_EQ(EBADF, errno);
#endif
close(fd);
}