From: Nick Kralevich Date: Sat, 6 Jun 2015 18:23:26 +0000 (-0700) Subject: Add O_PATH support for flistxattr() X-Git-Tag: android-x86-7.1-r1~270^2~230^2~122^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=e1d0810cd7e2aa045d5cc1e7d2b8697acd8467be;p=android-x86%2Fbionic.git Add O_PATH support for flistxattr() A continuation of commit 2825f10b7f61558c264231a536cf3affc0d84204. Add O_PATH compatibility support for flistxattr(). This allows a process to list out all the extended attributes associated with O_PATH file descriptors. Change-Id: Ie2285ac7ad2e4eac427ddba6c2d182d41b130f75 --- diff --git a/libc/Android.mk b/libc/Android.mk index 620f438da..868d15926 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -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 \ diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 4890b89a2..23cc3b6a9 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -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 diff --git a/libc/arch-arm/syscalls/flistxattr.S b/libc/arch-arm/syscalls/___flistxattr.S similarity index 81% rename from libc/arch-arm/syscalls/flistxattr.S rename to libc/arch-arm/syscalls/___flistxattr.S index ee09295f6..8ae8b7e93 100644 --- a/libc/arch-arm/syscalls/flistxattr.S +++ b/libc/arch-arm/syscalls/___flistxattr.S @@ -2,7 +2,7 @@ #include -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 diff --git a/libc/arch-arm64/syscalls/flistxattr.S b/libc/arch-arm64/syscalls/___flistxattr.S similarity index 78% rename from libc/arch-arm64/syscalls/flistxattr.S rename to libc/arch-arm64/syscalls/___flistxattr.S index 8921bb4cc..02c84784e 100644 --- a/libc/arch-arm64/syscalls/flistxattr.S +++ b/libc/arch-arm64/syscalls/___flistxattr.S @@ -2,7 +2,7 @@ #include -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 diff --git a/libc/arch-mips/syscalls/flistxattr.S b/libc/arch-mips/syscalls/___flistxattr.S similarity index 81% rename from libc/arch-mips/syscalls/flistxattr.S rename to libc/arch-mips/syscalls/___flistxattr.S index 0b715327d..5a4a53d5b 100644 --- a/libc/arch-mips/syscalls/flistxattr.S +++ b/libc/arch-mips/syscalls/___flistxattr.S @@ -2,7 +2,7 @@ #include -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 diff --git a/libc/arch-mips64/syscalls/flistxattr.S b/libc/arch-mips64/syscalls/___flistxattr.S similarity index 85% rename from libc/arch-mips64/syscalls/flistxattr.S rename to libc/arch-mips64/syscalls/___flistxattr.S index 1d5b1b028..586bcf747 100644 --- a/libc/arch-mips64/syscalls/flistxattr.S +++ b/libc/arch-mips64/syscalls/___flistxattr.S @@ -2,7 +2,7 @@ #include -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 diff --git a/libc/arch-x86/syscalls/flistxattr.S b/libc/arch-x86/syscalls/___flistxattr.S similarity index 91% rename from libc/arch-x86/syscalls/flistxattr.S rename to libc/arch-x86/syscalls/___flistxattr.S index fc81a374c..a67967b1f 100644 --- a/libc/arch-x86/syscalls/flistxattr.S +++ b/libc/arch-x86/syscalls/___flistxattr.S @@ -2,7 +2,7 @@ #include -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 diff --git a/libc/arch-x86_64/syscalls/flistxattr.S b/libc/arch-x86_64/syscalls/___flistxattr.S similarity index 80% rename from libc/arch-x86_64/syscalls/flistxattr.S rename to libc/arch-x86_64/syscalls/___flistxattr.S index aa02db1e2..b4695cc90 100644 --- a/libc/arch-x86_64/syscalls/flistxattr.S +++ b/libc/arch-x86_64/syscalls/___flistxattr.S @@ -2,7 +2,7 @@ #include -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 diff --git a/libc/bionic/flistxattr.cpp b/libc/bionic/flistxattr.cpp new file mode 100644 index 000000000..05a96d24a --- /dev/null +++ b/libc/bionic/flistxattr.cpp @@ -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 +#include +#include +#include +#include +#include + +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); +} diff --git a/tests/sys_xattr_test.cpp b/tests/sys_xattr_test.cpp index 184268220..113ec267c 100644 --- a/tests/sys_xattr_test.cpp +++ b/tests/sys_xattr_test.cpp @@ -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(res) <= sizeof(buf)); + ASSERT_TRUE(memmem(buf, res, "user.foo", 9) != NULL); +#else + ASSERT_EQ(-1, res); + ASSERT_EQ(EBADF, errno); +#endif + close(fd); }