1 /*
2 * Copyright (c) 2002-2005 Roland McGrath <roland@redhat.com>
3 * Copyright (c) 2004 Ulrich Drepper <drepper@redhat.com>
4 * Copyright (c) 2005-2021 Dmitry V. Levin <ldv@strace.io>
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-or-later
8 */
9
10 #include "defs.h"
11
12 #ifdef HAVE_SYS_XATTR_H
13 # include <sys/xattr.h>
14 #endif
15
16 #include "xlat/xattrflags.h"
17
18 #ifndef XATTR_SIZE_MAX
19 # define XATTR_SIZE_MAX 65536
20 #endif
21
22 static void
23 print_xattr_val(struct tcb *const tcp,
24 const kernel_ulong_t addr,
25 const kernel_ulong_t insize,
26 const kernel_ulong_t size)
27 {
28 /* value */
29 if (size > XATTR_SIZE_MAX)
30 printaddr(addr);
31 else
32 printstr_ex(tcp, addr, size, QUOTE_OMIT_TRAILING_0);
33 tprint_arg_next();
34
35 /* size */
36 PRINT_VAL_U(insize);
37 }
38
39 SYS_FUNC(setxattr)
40 {
41 /* pathname */
42 printpath(tcp, tcp->u_arg[0]);
43 tprint_arg_next();
44
45 /* name */
46 printstr(tcp, tcp->u_arg[1]);
47 tprint_arg_next();
48
49 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
50 tprint_arg_next();
51
52 /* flags */
53 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
54 return RVAL_DECODED;
55 }
56
57 SYS_FUNC(fsetxattr)
58 {
59 /* fd */
60 printfd(tcp, tcp->u_arg[0]);
61 tprint_arg_next();
62
63 /* name */
64 printstr(tcp, tcp->u_arg[1]);
65 tprint_arg_next();
66
67 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
68 tprint_arg_next();
69
70 /* flags */
71 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
72 return RVAL_DECODED;
73 }
74
75 SYS_FUNC(getxattr)
76 {
77 if (entering(tcp)) {
78 /* pathname */
79 printpath(tcp, tcp->u_arg[0]);
80 tprint_arg_next();
81
82 /* name */
83 printstr(tcp, tcp->u_arg[1]);
84 tprint_arg_next();
85 } else {
86 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_rval);
87 }
88 return 0;
89 }
90
91 SYS_FUNC(fgetxattr)
92 {
93 if (entering(tcp)) {
94 /* fd */
95 printfd(tcp, tcp->u_arg[0]);
96 tprint_arg_next();
97
98 /* name */
99 printstr(tcp, tcp->u_arg[1]);
100 tprint_arg_next();
101 } else {
102 print_xattr_val(tcp, tcp->u_arg[2], tcp->u_arg[3], tcp->u_rval);
103 }
104 return 0;
105 }
106
107 static void
108 print_xattr_list(struct tcb *const tcp, const kernel_ulong_t addr,
109 const kernel_ulong_t size)
110 {
111 /* list */
112 if (!size || syserror(tcp)) {
113 printaddr(addr);
114 } else {
115 printstrn(tcp, addr, tcp->u_rval);
116 }
117 tprint_arg_next();
118
119 /* size */
120 PRINT_VAL_U(size);
121 }
122
123 SYS_FUNC(listxattr)
124 {
125 if (entering(tcp)) {
126 /* pathname */
127 printpath(tcp, tcp->u_arg[0]);
128 tprint_arg_next();
129 } else {
130 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
131 }
132 return 0;
133 }
134
135 SYS_FUNC(flistxattr)
136 {
137 if (entering(tcp)) {
138 /* fd */
139 printfd(tcp, tcp->u_arg[0]);
140 tprint_arg_next();
141 } else {
142 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
143 }
144 return 0;
145 }
146
147 SYS_FUNC(removexattr)
148 {
149 /* pathname */
150 printpath(tcp, tcp->u_arg[0]);
151 tprint_arg_next();
152
153 /* name */
154 printstr(tcp, tcp->u_arg[1]);
155 return RVAL_DECODED;
156 }
157
158 SYS_FUNC(fremovexattr)
159 {
160 /* fd */
161 printfd(tcp, tcp->u_arg[0]);
162 tprint_arg_next();
163
164 /* name */
165 printstr(tcp, tcp->u_arg[1]);
166 return RVAL_DECODED;
167 }