1 /* 2 * Copyright (c) 2002-2005 Roland McGrath <roland (at) redhat.com> 3 * Copyright (c) 2004 Ulrich Drepper <drepper (at) redhat.com> 4 * Copyright (c) 2005-2015 Dmitry V. Levin <ldv (at) altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "defs.h" 31 32 #ifdef HAVE_SYS_XATTR_H 33 # include <sys/xattr.h> 34 #endif 35 36 #include "xlat/xattrflags.h" 37 38 static void 39 print_xattr_val(struct tcb *tcp, 40 unsigned long addr, 41 unsigned long insize, 42 unsigned long size) 43 { 44 char *buf = NULL; 45 unsigned int len; 46 47 tprints(", "); 48 49 if (insize == 0) 50 goto done; 51 52 len = size; 53 if (size != (unsigned long) len) 54 goto done; 55 56 if (!len) { 57 tprintf("\"\", %ld", insize); 58 return; 59 } 60 61 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) 62 goto done; 63 64 buf = malloc(len); 65 if (!buf) 66 goto done; 67 68 if (umoven(tcp, addr, len, buf) < 0) { 69 free(buf); 70 buf = NULL; 71 goto done; 72 } 73 74 /* Don't print terminating NUL if there is one. */ 75 if (buf[len - 1] == '\0') 76 --len; 77 78 done: 79 if (buf) { 80 print_quoted_string(buf, len, 0); 81 free(buf); 82 } else { 83 printaddr(addr); 84 } 85 tprintf(", %ld", insize); 86 } 87 88 SYS_FUNC(setxattr) 89 { 90 printpath(tcp, tcp->u_arg[0]); 91 tprints(", "); 92 printstr(tcp, tcp->u_arg[1], -1); 93 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]); 94 tprints(", "); 95 printflags(xattrflags, tcp->u_arg[4], "XATTR_???"); 96 return RVAL_DECODED; 97 } 98 99 SYS_FUNC(fsetxattr) 100 { 101 printfd(tcp, tcp->u_arg[0]); 102 tprints(", "); 103 printstr(tcp, tcp->u_arg[1], -1); 104 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]); 105 tprints(", "); 106 printflags(xattrflags, tcp->u_arg[4], "XATTR_???"); 107 return RVAL_DECODED; 108 } 109 110 SYS_FUNC(getxattr) 111 { 112 if (entering(tcp)) { 113 printpath(tcp, tcp->u_arg[0]); 114 tprints(", "); 115 printstr(tcp, tcp->u_arg[1], -1); 116 } else { 117 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_rval); 118 } 119 return 0; 120 } 121 122 SYS_FUNC(fgetxattr) 123 { 124 if (entering(tcp)) { 125 printfd(tcp, tcp->u_arg[0]); 126 tprints(", "); 127 printstr(tcp, tcp->u_arg[1], -1); 128 } else { 129 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_rval); 130 } 131 return 0; 132 } 133 134 static void 135 print_xattr_list(struct tcb *tcp, unsigned long addr, unsigned long size) 136 { 137 if (syserror(tcp)) { 138 printaddr(addr); 139 } else { 140 unsigned long len = 141 (size < (unsigned long) tcp->u_rval) ? 142 size : (unsigned long) tcp->u_rval; 143 printstr(tcp, addr, len); 144 } 145 tprintf(", %lu", size); 146 } 147 148 SYS_FUNC(listxattr) 149 { 150 if (entering(tcp)) { 151 printpath(tcp, tcp->u_arg[0]); 152 tprints(", "); 153 } else { 154 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]); 155 } 156 return 0; 157 } 158 159 SYS_FUNC(flistxattr) 160 { 161 if (entering(tcp)) { 162 printfd(tcp, tcp->u_arg[0]); 163 tprints(", "); 164 } else { 165 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]); 166 } 167 return 0; 168 } 169 170 SYS_FUNC(removexattr) 171 { 172 printpath(tcp, tcp->u_arg[0]); 173 tprints(", "); 174 printstr(tcp, tcp->u_arg[1], -1); 175 return RVAL_DECODED; 176 } 177 178 SYS_FUNC(fremovexattr) 179 { 180 printfd(tcp, tcp->u_arg[0]); 181 tprints(", "); 182 printstr(tcp, tcp->u_arg[1], -1); 183 return RVAL_DECODED; 184 } 185