Merge "libc: Add O_PATH support for fgetxattr / fsetxattr"
This commit is contained in:
		@@ -129,8 +129,10 @@ libc_bionic_ndk_src_files := \
 | 
				
			|||||||
    bionic/fchmod.cpp \
 | 
					    bionic/fchmod.cpp \
 | 
				
			||||||
    bionic/fchmodat.cpp \
 | 
					    bionic/fchmodat.cpp \
 | 
				
			||||||
    bionic/ffs.cpp \
 | 
					    bionic/ffs.cpp \
 | 
				
			||||||
 | 
					    bionic/fgetxattr.cpp \
 | 
				
			||||||
    bionic/flockfile.cpp \
 | 
					    bionic/flockfile.cpp \
 | 
				
			||||||
    bionic/fpclassify.cpp \
 | 
					    bionic/fpclassify.cpp \
 | 
				
			||||||
 | 
					    bionic/fsetxattr.cpp \
 | 
				
			||||||
    bionic/ftruncate.cpp \
 | 
					    bionic/ftruncate.cpp \
 | 
				
			||||||
    bionic/futimens.cpp \
 | 
					    bionic/futimens.cpp \
 | 
				
			||||||
    bionic/getcwd.cpp \
 | 
					    bionic/getcwd.cpp \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -122,8 +122,8 @@ int         fdatasync(int) all
 | 
				
			|||||||
int         fchown:fchown32(int, uid_t, gid_t)  arm,x86
 | 
					int         fchown:fchown32(int, uid_t, gid_t)  arm,x86
 | 
				
			||||||
int         fchown:fchown(int, uid_t, gid_t)    arm64,mips,mips64,x86_64
 | 
					int         fchown:fchown(int, uid_t, gid_t)    arm64,mips,mips64,x86_64
 | 
				
			||||||
void        sync(void)  all
 | 
					void        sync(void)  all
 | 
				
			||||||
int         fsetxattr(int, const char*, const void*, size_t, int) all
 | 
					int         ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
 | 
				
			||||||
ssize_t     fgetxattr(int, const char*, void*, size_t) all
 | 
					ssize_t     ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all
 | 
				
			||||||
ssize_t     flistxattr(int, char*, size_t) all
 | 
					ssize_t     flistxattr(int, char*, size_t) all
 | 
				
			||||||
int         fremovexattr(int, const char*) all
 | 
					int         fremovexattr(int, const char*) all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fgetxattr)
 | 
					ENTRY(___fgetxattr)
 | 
				
			||||||
    mov     ip, r7
 | 
					    mov     ip, r7
 | 
				
			||||||
    ldr     r7, =__NR_fgetxattr
 | 
					    ldr     r7, =__NR_fgetxattr
 | 
				
			||||||
    swi     #0
 | 
					    swi     #0
 | 
				
			||||||
@@ -11,4 +11,5 @@ ENTRY(fgetxattr)
 | 
				
			|||||||
    bxls    lr
 | 
					    bxls    lr
 | 
				
			||||||
    neg     r0, r0
 | 
					    neg     r0, r0
 | 
				
			||||||
    b       __set_errno_internal
 | 
					    b       __set_errno_internal
 | 
				
			||||||
END(fgetxattr)
 | 
					END(___fgetxattr)
 | 
				
			||||||
 | 
					.hidden ___fgetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fsetxattr)
 | 
					ENTRY(___fsetxattr)
 | 
				
			||||||
    mov     ip, sp
 | 
					    mov     ip, sp
 | 
				
			||||||
    stmfd   sp!, {r4, r5, r6, r7}
 | 
					    stmfd   sp!, {r4, r5, r6, r7}
 | 
				
			||||||
    .cfi_def_cfa_offset 16
 | 
					    .cfi_def_cfa_offset 16
 | 
				
			||||||
@@ -19,4 +19,5 @@ ENTRY(fsetxattr)
 | 
				
			|||||||
    bxls    lr
 | 
					    bxls    lr
 | 
				
			||||||
    neg     r0, r0
 | 
					    neg     r0, r0
 | 
				
			||||||
    b       __set_errno_internal
 | 
					    b       __set_errno_internal
 | 
				
			||||||
END(fsetxattr)
 | 
					END(___fsetxattr)
 | 
				
			||||||
 | 
					.hidden ___fsetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fgetxattr)
 | 
					ENTRY(___fgetxattr)
 | 
				
			||||||
    mov     x8, __NR_fgetxattr
 | 
					    mov     x8, __NR_fgetxattr
 | 
				
			||||||
    svc     #0
 | 
					    svc     #0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,4 +11,5 @@ ENTRY(fgetxattr)
 | 
				
			|||||||
    b.hi    __set_errno_internal
 | 
					    b.hi    __set_errno_internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
END(fgetxattr)
 | 
					END(___fgetxattr)
 | 
				
			||||||
 | 
					.hidden ___fgetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fsetxattr)
 | 
					ENTRY(___fsetxattr)
 | 
				
			||||||
    mov     x8, __NR_fsetxattr
 | 
					    mov     x8, __NR_fsetxattr
 | 
				
			||||||
    svc     #0
 | 
					    svc     #0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,4 +11,5 @@ ENTRY(fsetxattr)
 | 
				
			|||||||
    b.hi    __set_errno_internal
 | 
					    b.hi    __set_errno_internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
END(fsetxattr)
 | 
					END(___fsetxattr)
 | 
				
			||||||
 | 
					.hidden ___fsetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fgetxattr)
 | 
					ENTRY(___fgetxattr)
 | 
				
			||||||
    .set noreorder
 | 
					    .set noreorder
 | 
				
			||||||
    .cpload t9
 | 
					    .cpload t9
 | 
				
			||||||
    li v0, __NR_fgetxattr
 | 
					    li v0, __NR_fgetxattr
 | 
				
			||||||
@@ -16,4 +16,5 @@ ENTRY(fgetxattr)
 | 
				
			|||||||
    j t9
 | 
					    j t9
 | 
				
			||||||
    nop
 | 
					    nop
 | 
				
			||||||
    .set reorder
 | 
					    .set reorder
 | 
				
			||||||
END(fgetxattr)
 | 
					END(___fgetxattr)
 | 
				
			||||||
 | 
					.hidden ___fgetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fsetxattr)
 | 
					ENTRY(___fsetxattr)
 | 
				
			||||||
    .set noreorder
 | 
					    .set noreorder
 | 
				
			||||||
    .cpload t9
 | 
					    .cpload t9
 | 
				
			||||||
    li v0, __NR_fsetxattr
 | 
					    li v0, __NR_fsetxattr
 | 
				
			||||||
@@ -16,4 +16,5 @@ ENTRY(fsetxattr)
 | 
				
			|||||||
    j t9
 | 
					    j t9
 | 
				
			||||||
    nop
 | 
					    nop
 | 
				
			||||||
    .set reorder
 | 
					    .set reorder
 | 
				
			||||||
END(fsetxattr)
 | 
					END(___fsetxattr)
 | 
				
			||||||
 | 
					.hidden ___fsetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fgetxattr)
 | 
					ENTRY(___fgetxattr)
 | 
				
			||||||
    .set push
 | 
					    .set push
 | 
				
			||||||
    .set noreorder
 | 
					    .set noreorder
 | 
				
			||||||
    li v0, __NR_fgetxattr
 | 
					    li v0, __NR_fgetxattr
 | 
				
			||||||
@@ -22,4 +22,5 @@ ENTRY(fgetxattr)
 | 
				
			|||||||
    j t9
 | 
					    j t9
 | 
				
			||||||
    move ra, t0
 | 
					    move ra, t0
 | 
				
			||||||
    .set pop
 | 
					    .set pop
 | 
				
			||||||
END(fgetxattr)
 | 
					END(___fgetxattr)
 | 
				
			||||||
 | 
					.hidden ___fgetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fsetxattr)
 | 
					ENTRY(___fsetxattr)
 | 
				
			||||||
    .set push
 | 
					    .set push
 | 
				
			||||||
    .set noreorder
 | 
					    .set noreorder
 | 
				
			||||||
    li v0, __NR_fsetxattr
 | 
					    li v0, __NR_fsetxattr
 | 
				
			||||||
@@ -22,4 +22,5 @@ ENTRY(fsetxattr)
 | 
				
			|||||||
    j t9
 | 
					    j t9
 | 
				
			||||||
    move ra, t0
 | 
					    move ra, t0
 | 
				
			||||||
    .set pop
 | 
					    .set pop
 | 
				
			||||||
END(fsetxattr)
 | 
					END(___fsetxattr)
 | 
				
			||||||
 | 
					.hidden ___fsetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fgetxattr)
 | 
					ENTRY(___fgetxattr)
 | 
				
			||||||
    pushl   %ebx
 | 
					    pushl   %ebx
 | 
				
			||||||
    .cfi_def_cfa_offset 8
 | 
					    .cfi_def_cfa_offset 8
 | 
				
			||||||
    .cfi_rel_offset ebx, 0
 | 
					    .cfi_rel_offset ebx, 0
 | 
				
			||||||
@@ -33,4 +33,5 @@ ENTRY(fgetxattr)
 | 
				
			|||||||
    popl    %ecx
 | 
					    popl    %ecx
 | 
				
			||||||
    popl    %ebx
 | 
					    popl    %ebx
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
END(fgetxattr)
 | 
					END(___fgetxattr)
 | 
				
			||||||
 | 
					.hidden ___fgetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fsetxattr)
 | 
					ENTRY(___fsetxattr)
 | 
				
			||||||
    pushl   %ebx
 | 
					    pushl   %ebx
 | 
				
			||||||
    .cfi_def_cfa_offset 8
 | 
					    .cfi_def_cfa_offset 8
 | 
				
			||||||
    .cfi_rel_offset ebx, 0
 | 
					    .cfi_rel_offset ebx, 0
 | 
				
			||||||
@@ -38,4 +38,5 @@ ENTRY(fsetxattr)
 | 
				
			|||||||
    popl    %ecx
 | 
					    popl    %ecx
 | 
				
			||||||
    popl    %ebx
 | 
					    popl    %ebx
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
END(fsetxattr)
 | 
					END(___fsetxattr)
 | 
				
			||||||
 | 
					.hidden ___fsetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fgetxattr)
 | 
					ENTRY(___fgetxattr)
 | 
				
			||||||
    movq    %rcx, %r10
 | 
					    movq    %rcx, %r10
 | 
				
			||||||
    movl    $__NR_fgetxattr, %eax
 | 
					    movl    $__NR_fgetxattr, %eax
 | 
				
			||||||
    syscall
 | 
					    syscall
 | 
				
			||||||
@@ -13,4 +13,5 @@ ENTRY(fgetxattr)
 | 
				
			|||||||
    call    __set_errno_internal
 | 
					    call    __set_errno_internal
 | 
				
			||||||
1:
 | 
					1:
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
END(fgetxattr)
 | 
					END(___fgetxattr)
 | 
				
			||||||
 | 
					.hidden ___fgetxattr
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(fsetxattr)
 | 
					ENTRY(___fsetxattr)
 | 
				
			||||||
    movq    %rcx, %r10
 | 
					    movq    %rcx, %r10
 | 
				
			||||||
    movl    $__NR_fsetxattr, %eax
 | 
					    movl    $__NR_fsetxattr, %eax
 | 
				
			||||||
    syscall
 | 
					    syscall
 | 
				
			||||||
@@ -13,4 +13,5 @@ ENTRY(fsetxattr)
 | 
				
			|||||||
    call    __set_errno_internal
 | 
					    call    __set_errno_internal
 | 
				
			||||||
1:
 | 
					1:
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
END(fsetxattr)
 | 
					END(___fsetxattr)
 | 
				
			||||||
 | 
					.hidden ___fsetxattr
 | 
				
			||||||
							
								
								
									
										59
									
								
								libc/bionic/fgetxattr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								libc/bionic/fgetxattr.cpp
									
									
									
									
									
										Normal 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 ___fgetxattr(int, const char*, void*, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t fgetxattr(int fd, const char *name, void *value, size_t size) {
 | 
				
			||||||
 | 
					  int saved_errno = errno;
 | 
				
			||||||
 | 
					  ssize_t result = ___fgetxattr(fd, name, value, 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 getxattr(buf, name, value, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										59
									
								
								libc/bionic/fsetxattr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								libc/bionic/fsetxattr.cpp
									
									
									
									
									
										Normal 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" int ___fsetxattr(int, const char*, const void*, size_t, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int fsetxattr(int fd, const char* name, const void* value, size_t size, int flags) {
 | 
				
			||||||
 | 
					  int saved_errno = errno;
 | 
				
			||||||
 | 
					  int result = ___fsetxattr(fd, name, value, size, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ((result == 0) || (errno != EBADF)) {
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // fd could be an O_PATH file descriptor, and the kernel
 | 
				
			||||||
 | 
					  // may not directly support fsetxattr() 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 setxattr(buf, name, value, size, flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -107,6 +107,7 @@ libBionicStandardTests_src_files := \
 | 
				
			|||||||
    sys_time_test.cpp \
 | 
					    sys_time_test.cpp \
 | 
				
			||||||
    sys_types_test.cpp \
 | 
					    sys_types_test.cpp \
 | 
				
			||||||
    sys_vfs_test.cpp \
 | 
					    sys_vfs_test.cpp \
 | 
				
			||||||
 | 
					    sys_xattr_test.cpp \
 | 
				
			||||||
    system_properties_test.cpp \
 | 
					    system_properties_test.cpp \
 | 
				
			||||||
    time_test.cpp \
 | 
					    time_test.cpp \
 | 
				
			||||||
    uchar_test.cpp \
 | 
					    uchar_test.cpp \
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										100
									
								
								tests/sys_xattr_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								tests/sys_xattr_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2015 The Android Open Source Project
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <gtest/gtest.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/xattr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "TemporaryFile.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(sys_xattr, setxattr) {
 | 
				
			||||||
 | 
					  TemporaryFile tf;
 | 
				
			||||||
 | 
					  char buf[10];
 | 
				
			||||||
 | 
					  ASSERT_EQ(0, setxattr(tf.filename, "user.foo", "bar", 4, 0));
 | 
				
			||||||
 | 
					  ASSERT_EQ(4, getxattr(tf.filename, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					  ASSERT_STREQ("bar", buf);
 | 
				
			||||||
 | 
					  buf[0] = '\0';
 | 
				
			||||||
 | 
					  ASSERT_EQ(4, lgetxattr(tf.filename, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					  ASSERT_STREQ("bar", buf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(sys_xattr, fsetxattr) {
 | 
				
			||||||
 | 
					  TemporaryFile tf;
 | 
				
			||||||
 | 
					  char buf[10];
 | 
				
			||||||
 | 
					  ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "bar", 4, 0));
 | 
				
			||||||
 | 
					  ASSERT_EQ(4, fgetxattr(tf.fd, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					  ASSERT_STREQ("bar", buf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(sys_xattr, fsetxattr_zerobuf) {
 | 
				
			||||||
 | 
					  TemporaryFile tf;
 | 
				
			||||||
 | 
					  char buf[10];
 | 
				
			||||||
 | 
					  ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "", 0, 0));
 | 
				
			||||||
 | 
					  ASSERT_EQ(0, fgetxattr(tf.fd, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(sys_xattr, fsetxattr_toosmallbuf) {
 | 
				
			||||||
 | 
					  TemporaryFile tf;
 | 
				
			||||||
 | 
					  char buf[10];
 | 
				
			||||||
 | 
					  ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "01234567890123456789", 21, 0));
 | 
				
			||||||
 | 
					  ASSERT_EQ(-1, fgetxattr(tf.fd, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					  ASSERT_EQ(ERANGE, errno);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(sys_xattr, fsetxattr_invalidfd) {
 | 
				
			||||||
 | 
					  char buf[10];
 | 
				
			||||||
 | 
					  errno = 0;
 | 
				
			||||||
 | 
					  ASSERT_EQ(-1, fsetxattr(65535, "user.foo", "0123", 5, 0));
 | 
				
			||||||
 | 
					  ASSERT_EQ(EBADF, errno);
 | 
				
			||||||
 | 
					  errno = 0;
 | 
				
			||||||
 | 
					  ASSERT_EQ(-1, fgetxattr(65535, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					  ASSERT_EQ(EBADF, errno);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(sys_xattr, fsetxattr_with_opath) {
 | 
				
			||||||
 | 
					  TemporaryFile tf;
 | 
				
			||||||
 | 
					  int fd = open(tf.filename, O_PATH);
 | 
				
			||||||
 | 
					  ASSERT_NE(-1, fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int res = fsetxattr(fd, "user.foo", "bar", 4, 0);
 | 
				
			||||||
 | 
					#if defined(__BIONIC__)
 | 
				
			||||||
 | 
					  char buf[10];
 | 
				
			||||||
 | 
					  ASSERT_EQ(0, res);
 | 
				
			||||||
 | 
					  ASSERT_EQ(4, fgetxattr(fd, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					  ASSERT_STREQ("bar", buf);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  ASSERT_EQ(-1, res);
 | 
				
			||||||
 | 
					  ASSERT_EQ(EBADF, errno);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(sys_xattr, fsetxattr_with_opath_toosmall) {
 | 
				
			||||||
 | 
					  TemporaryFile tf;
 | 
				
			||||||
 | 
					  int fd = open(tf.filename, O_PATH);
 | 
				
			||||||
 | 
					  ASSERT_NE(-1, fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int res = fsetxattr(fd, "user.foo", "01234567890123456789", 21, 0);
 | 
				
			||||||
 | 
					#if defined(__BIONIC__)
 | 
				
			||||||
 | 
					  char buf[10];
 | 
				
			||||||
 | 
					  ASSERT_EQ(0, res);
 | 
				
			||||||
 | 
					  ASSERT_EQ(-1, fgetxattr(fd, "user.foo", buf, sizeof(buf)));
 | 
				
			||||||
 | 
					  ASSERT_EQ(ERANGE, errno);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  ASSERT_EQ(-1, res);
 | 
				
			||||||
 | 
					  ASSERT_EQ(EBADF, errno);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user