master
c 1,293 lines 49.6 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 Xattr.c
8
9 Abstract:
10
11 This file is a xattr test.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include "lxtutil.h"
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 #include <sys/ptrace.h>
23 #include <sys/syscall.h>
24 #include <sys/uio.h>
25 #include <sched.h>
26 #include <signal.h>
27 #include <time.h>
28 #include <limits.h>
29 #include <sys/mman.h>
30 #include <sys/prctl.h>
31 #include <sys/user.h>
32 #include <stddef.h>
33 #include <fcntl.h>
34 #include "lxtfs.h"
35 #include <sys/xattr.h>
36 #include <libmount/libmount.h>
37 #include "lxtmount.h"
38
39 #if !defined(__amd64__) && !defined(__aarch64__)
40
41 #include <sys/capability.h>
42
43 #else
44
45 #include <sys/cdefs.h>
46 #include <linux/capability.h>
47
48 #define _LINUX_CAPABILITY_VERSION_3 0x20080522
49
50 #endif
51
52 #define LXT_NAME "xattr"
53 #define LXT_NAME_DRVFS "xattr_drvfs"
54
55 #define LXT_XATTR_MODE 0777
56 #define LXT_XATTR_UID 1004
57 #define LXT_XATTR_GID 1004
58 #define LXT_XATTR_TEST_PARENT "/data/xattrtest"
59 #define LXT_XATTR_ACCESS_FILE_PATH LXT_XATTR_TEST_PARENT "/xattrAccessFile"
60 #define LXT_XATTR_FILE_PATH LXT_XATTR_TEST_PARENT "/xattrFile"
61 #define LXT_XATTR_DIR_PATH LXT_XATTR_TEST_PARENT "/xattrDir"
62 #define LXT_XATTR_LINK_PATH LXT_XATTR_TEST_PARENT "/xattrLink"
63 #define LXT_XATTR_FIFO_PATH LXT_XATTR_TEST_PARENT "/xattrFifo"
64 #define LXT_XATTR_SIZE_MAX (4040)
65 #define LXT_XATTR_CASE_SENSITIVE_LENGTH (sizeof(LXT_XATTR_CASE_SENSITIVE) - 1)
66 #define LXT_XATTR_TEST_VALUE "test"
67 #define LXT_XATTR_TEST_LENGTH (sizeof(LXT_XATTR_TEST_VALUE) - 1)
68
69 #define LXT_XATTR_PATH_COUNT (LXT_COUNT_OF(g_XattrPaths))
70
71 int XattrTestCreatePaths(int* Fds);
72
73 void XattrTestDeletePaths(int* Fds);
74
75 LXT_VARIATION_HANDLER XattrAccessTest;
76 LXT_VARIATION_HANDLER XattrListTest;
77 LXT_VARIATION_HANDLER XattrGetTest;
78 LXT_VARIATION_HANDLER XattrRemoveTest;
79 LXT_VARIATION_HANDLER XattrSetTest;
80
81 //
82 // Global constants
83 //
84
85 static const LXT_VARIATION g_LxtVariations[] = {
86 {"xattr list", XattrListTest}, {"xattr get", XattrGetTest}, {"xattr set", XattrSetTest}, {"xattr remove", XattrRemoveTest}, {"xattr access", XattrAccessTest}};
87
88 static const char* g_XattrPaths[] = {
89 LXT_XATTR_FILE_PATH, LXT_XATTR_DIR_PATH, LXT_XATTR_LINK_PATH, LXT_XATTR_FIFO_PATH, "/dev/null", "/proc/cpuinfo"};
90
91 ssize_t GetXattr(const char* Path, const char* Name, void* Value, size_t Size)
92 {
93 size_t Result = LxtGetxattr(Path, Name, Value, Size);
94 if (Result < 0)
95 {
96 int SavedErrno = errno;
97 ssize_t SavedResult = Result;
98 Result = LxtGetxattr(Path, Name, NULL, 0);
99 LxtLogInfo("getxattr(%s, %s, NULL, 0) = %Iu", Path, Name, Result);
100 errno = SavedErrno;
101 Result = SavedResult;
102 }
103
104 return Result;
105 }
106
107 int XattrTestEntry(int Argc, char* Argv[])
108
109 /*++
110 --*/
111
112 {
113
114 LXT_ARGS Args;
115 int Index;
116 const char* Name;
117 int Result;
118 bool UseDrvFs;
119
120 Name = LXT_NAME;
121 UseDrvFs = false;
122 for (Index = 1; Index < Argc; Index += 1)
123 {
124 if (strcmp(Argv[Index], "drvfs") == 0)
125 {
126 UseDrvFs = true;
127 Name = LXT_NAME_DRVFS;
128 break;
129 }
130 }
131
132 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, Name));
133 LxtCheckResult(LxtFsTestSetup(&Args, LXT_XATTR_TEST_PARENT, "/xattrtest", UseDrvFs));
134
135 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
136
137 ErrorExit:
138 LxtFsTestCleanup(LXT_XATTR_TEST_PARENT, "/xattrtest", UseDrvFs);
139 LxtUninitialize();
140 return !LXT_SUCCESS(Result);
141 }
142
143 int XattrTestCreatePaths(int* Fds)
144
145 /*++
146 --*/
147
148 {
149
150 int Fd;
151 int Index;
152 int Result;
153
154 memset(Fds, -1, sizeof(*Fds) * LXT_XATTR_PATH_COUNT);
155 XattrTestDeletePaths(NULL);
156 LxtCheckErrno(Fd = creat(LXT_XATTR_FILE_PATH, LXT_XATTR_MODE));
157 LxtClose(Fd);
158 LxtCheckErrno(mkdir(LXT_XATTR_DIR_PATH, LXT_XATTR_MODE));
159 LxtCheckErrno(symlink(LXT_XATTR_FILE_PATH, LXT_XATTR_LINK_PATH));
160 LxtCheckErrno(mkfifo(LXT_XATTR_FIFO_PATH, LXT_XATTR_MODE));
161 for (Index = 0; Index < LXT_XATTR_PATH_COUNT; ++Index)
162 {
163 Fds[Index] = open(g_XattrPaths[Index], O_RDONLY | O_NONBLOCK);
164 }
165
166 ErrorExit:
167 return Result;
168 }
169
170 void XattrTestDeletePaths(int* Fds)
171
172 {
173
174 int Index;
175
176 if (Fds != NULL)
177 {
178 for (Index = 0; Index < LXT_XATTR_PATH_COUNT; ++Index)
179 {
180 if (Fds[Index] != -1)
181 {
182 LxtClose(Fds[Index]);
183 Fds[Index] = -1;
184 }
185 }
186 }
187
188 unlink(LXT_XATTR_FILE_PATH);
189 rmdir(LXT_XATTR_DIR_PATH);
190 unlink(LXT_XATTR_LINK_PATH);
191 unlink(LXT_XATTR_FIFO_PATH);
192 return;
193 }
194
195 int XattrListTest(PLXT_ARGS Args)
196
197 /*++
198 --*/
199
200 {
201
202 char Buffer[1024];
203 ssize_t ExpectedSize;
204 int Fds[LXT_XATTR_PATH_COUNT];
205 int Index;
206 ssize_t Result;
207 ssize_t Size;
208
209 LxtCheckErrno(XattrTestCreatePaths(Fds));
210 for (Index = 0; Index < (LXT_XATTR_PATH_COUNT - 1); ++Index)
211 {
212
213 LxtLogInfo("%s", g_XattrPaths[Index]);
214
215 //
216 // Check that the xattr syscalls return 0 for all entries to indicate no
217 // attributes are present.
218 //
219 // N.B. DrvFs (not in WslFs mode) will return the case sensitivity
220 // attribute for directories only.
221 //
222
223 if ((Index == 1) && ((g_LxtFsInfo.FsType == LxtFsTypeDrvFs) || (g_LxtFsInfo.FsType == LxtFsTypeVirtioFs)))
224 {
225 ExpectedSize = LXT_XATTR_CASE_SENSITIVE_LENGTH + 1;
226 }
227 else
228 {
229 ExpectedSize = 0;
230 }
231
232 LxtCheckErrno(Size = LxtListxattr(g_XattrPaths[Index], Buffer, sizeof(Buffer)));
233 LxtCheckEqual(Size, ExpectedSize, "%lld");
234 LxtCheckErrno(Size = LxtLlistxattr(g_XattrPaths[Index], Buffer, sizeof(Buffer)));
235 LxtCheckEqual(Size, ExpectedSize, "%lld");
236 LxtCheckErrno(Size = LxtFlistxattr(Fds[Index], Buffer, sizeof(Buffer)));
237 LxtCheckEqual(Size, ExpectedSize, "%lld");
238
239 //
240 // Check that the buffer and size are not validated if there are no
241 // attributes.
242 //
243
244 if (ExpectedSize == 0)
245 {
246 LxtCheckErrnoZeroSuccess(LxtListxattr(g_XattrPaths[Index], 0x1, sizeof(Buffer)));
247 LxtCheckErrnoZeroSuccess(LxtLlistxattr(g_XattrPaths[Index], 0x1, sizeof(Buffer)));
248 LxtCheckErrnoZeroSuccess(LxtFlistxattr(Fds[Index], 0x1, sizeof(Buffer)));
249 LxtCheckErrnoZeroSuccess(LxtListxattr(g_XattrPaths[Index], Buffer, -1));
250 LxtCheckErrnoZeroSuccess(LxtLlistxattr(g_XattrPaths[Index], Buffer, -1));
251 LxtCheckErrnoZeroSuccess(LxtFlistxattr(Fds[Index], Buffer, -1));
252 }
253 }
254
255 //
256 // Check for invalid parameters.
257 //
258
259 LxtCheckErrnoFailure(LxtListxattr(0x1, Buffer, sizeof(Buffer)), EFAULT);
260 LxtCheckErrnoFailure(LxtLlistxattr(0x1, Buffer, sizeof(Buffer)), EFAULT);
261 LxtCheckErrnoFailure(LxtFlistxattr(-1, Buffer, sizeof(Buffer)), EBADF);
262
263 Result = LXT_RESULT_SUCCESS;
264
265 ErrorExit:
266 XattrTestDeletePaths(Fds);
267 return (int)Result;
268 }
269
270 int XattrGetTest(PLXT_ARGS Args)
271
272 /*++
273 --*/
274
275 {
276
277 char Buffer[1024];
278 int Failures[] = {ENODATA, ENODATA, ENODATA, ENODATA, ENODATA, ENOTSUP, ENOTSUP};
279 int Fds[LXT_XATTR_PATH_COUNT];
280 int Index;
281 char* Name = "security.capability";
282 ssize_t Result;
283
284 LxtCheckErrno(XattrTestCreatePaths(Fds));
285 for (Index = 0; Index < LXT_XATTR_PATH_COUNT; ++Index)
286 {
287
288 //
289 // Check that the xattr syscalls return 0 for all entries to indicate no
290 // attributes are present.
291 //
292
293 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[Index], Name, Buffer, sizeof(Buffer)), Failures[Index]);
294 LxtCheckErrnoFailure(LxtLgetxattr(g_XattrPaths[Index], Name, Buffer, sizeof(Buffer)), Failures[Index]);
295 LxtCheckErrnoFailure(LxtFgetxattr(Fds[Index], Name, Buffer, sizeof(Buffer)), Failures[Index]);
296
297 //
298 // Check that the buffer and size are not validated if there are no
299 // attributes.
300 //
301
302 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[Index], Name, 0x1, sizeof(Buffer)), Failures[Index]);
303 LxtCheckErrnoFailure(LxtLgetxattr(g_XattrPaths[Index], Name, 0x1, sizeof(Buffer)), Failures[Index]);
304 LxtCheckErrnoFailure(LxtFgetxattr(Fds[Index], Name, 0x1, sizeof(Buffer)), Failures[Index]);
305 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[Index], Name, Buffer, -1), Failures[Index]);
306 LxtCheckErrnoFailure(LxtLgetxattr(g_XattrPaths[Index], Name, Buffer, -1), Failures[Index]);
307 LxtCheckErrnoFailure(LxtFgetxattr(Fds[Index], Name, Buffer, -1), Failures[Index]);
308 }
309
310 //
311 // Check for invalid parameters.
312 //
313
314 LxtCheckErrnoFailure(LxtGetxattr(0x1, Name, Buffer, sizeof(Buffer)), EFAULT);
315 LxtCheckErrnoFailure(LxtLgetxattr(0x1, Name, Buffer, sizeof(Buffer)), EFAULT);
316 LxtCheckErrnoFailure(LxtFgetxattr(-1, Name, Buffer, sizeof(Buffer)), EBADF);
317
318 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[0], 0x1, Buffer, sizeof(Buffer)), EFAULT);
319 LxtCheckErrnoFailure(LxtLgetxattr(g_XattrPaths[0], 0x1, Buffer, sizeof(Buffer)), EFAULT);
320 LxtCheckErrnoFailure(LxtFgetxattr(Fds[0], 0x1, Buffer, sizeof(Buffer)), EFAULT);
321
322 if (g_LxtFsInfo.FsType != LxtFsTypeVirtioFs)
323 {
324 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer)), ENOTSUP);
325 LxtCheckErrnoFailure(LxtLgetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer)), ENOTSUP);
326 LxtCheckErrnoFailure(LxtFgetxattr(Fds[0], "invalid.name", Buffer, sizeof(Buffer)), ENOTSUP);
327 }
328 else
329 {
330 // The virtioFs implementation does not restrict the allowed attribute names, but these values will not be present.
331 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer)), ENODATA);
332 LxtCheckErrnoFailure(LxtLgetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer)), ENODATA);
333 LxtCheckErrnoFailure(LxtFgetxattr(Fds[0], "invalid.name", Buffer, sizeof(Buffer)), ENODATA);
334 }
335
336 Result = LXT_RESULT_SUCCESS;
337
338 ErrorExit:
339 XattrTestDeletePaths(Fds);
340 return (int)Result;
341 }
342
343 int XattrRemoveTest(PLXT_ARGS Args)
344
345 /*++
346 --*/
347
348 {
349
350 char Buffer[1024];
351 int Fds[LXT_XATTR_PATH_COUNT];
352 int Index;
353 char* Name = "security.capability";
354 int Result;
355 char TestData[] = "test";
356
357 LxtCheckErrno(XattrTestCreatePaths(Fds));
358 for (Index = 0; Index < LXT_XATTR_PATH_COUNT - 1; ++Index)
359 {
360
361 LxtLogInfo("%s %s", g_XattrPaths[Index], Name);
362
363 //
364 // Check that the xattr syscalls return the correct error code for all
365 // entries to indicate no attributes are present.
366 //
367 LxtCheckErrnoFailure(LxtRemovexattr(g_XattrPaths[Index], Name), ENODATA);
368 LxtCheckErrnoFailure(LxtLremovexattr(g_XattrPaths[Index], Name), ENODATA);
369 LxtCheckErrnoFailure(LxtFremovexattr(Fds[Index], Name), ENODATA);
370 }
371
372 //
373 // Create three ea's and delete them in various orders.
374 //
375
376 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.1", TestData, sizeof(TestData), 0));
377 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.2", TestData, sizeof(TestData), 0));
378 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.3", TestData, sizeof(TestData), 0));
379 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.1"));
380 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.2"));
381 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.3"));
382
383 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.1", TestData, sizeof(TestData), 0));
384 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.2", TestData, sizeof(TestData), 0));
385 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.3", TestData, sizeof(TestData), 0));
386 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.1"));
387 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.3"));
388 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.2"));
389
390 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.1", TestData, sizeof(TestData), 0));
391 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.2", TestData, sizeof(TestData), 0));
392 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.3", TestData, sizeof(TestData), 0));
393 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.2"));
394 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.1"));
395 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.3"));
396
397 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.1", TestData, sizeof(TestData), 0));
398 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.2", TestData, sizeof(TestData), 0));
399 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.3", TestData, sizeof(TestData), 0));
400 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.2"));
401 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.3"));
402 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.1"));
403
404 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.1", TestData, sizeof(TestData), 0));
405 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.2", TestData, sizeof(TestData), 0));
406 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.3", TestData, sizeof(TestData), 0));
407 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.3"));
408 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.1"));
409 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.2"));
410
411 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.1", TestData, sizeof(TestData), 0));
412 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.2", TestData, sizeof(TestData), 0));
413 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.3", TestData, sizeof(TestData), 0));
414 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.3"));
415 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.2"));
416 LxtCheckErrno(LxtRemovexattr(g_XattrPaths[0], "user.1"));
417
418 //
419 // Check for invalid parameters.
420 //
421
422 LxtCheckErrnoFailure(LxtRemovexattr(0x1, Name), EFAULT);
423 LxtCheckErrnoFailure(LxtLremovexattr(0x1, Name), EFAULT);
424 LxtCheckErrnoFailure(LxtFremovexattr(-1, Name), EBADF);
425
426 LxtCheckErrnoFailure(LxtRemovexattr(g_XattrPaths[0], 0x1), EFAULT);
427 LxtCheckErrnoFailure(LxtLremovexattr(g_XattrPaths[0], 0x1), EFAULT);
428 LxtCheckErrnoFailure(LxtFremovexattr(Fds[0], 0x1), EFAULT);
429
430 if (g_LxtFsInfo.FsType != LxtFsTypeVirtioFs)
431 {
432 LxtCheckErrnoFailure(LxtRemovexattr(g_XattrPaths[0], "invalid.name"), ENOTSUP);
433 LxtCheckErrnoFailure(LxtLremovexattr(g_XattrPaths[0], "invalid.name"), ENOTSUP);
434 LxtCheckErrnoFailure(LxtFremovexattr(Fds[0], "invalid.name"), ENOTSUP);
435 }
436 else
437 {
438 // The virtioFs implementation does not restrict the allowed attribute names, but these values will not be present.
439 LxtCheckErrnoFailure(LxtRemovexattr(g_XattrPaths[0], "invalid.name"), ENODATA);
440 LxtCheckErrnoFailure(LxtLremovexattr(g_XattrPaths[0], "invalid.name"), ENODATA);
441 LxtCheckErrnoFailure(LxtFremovexattr(Fds[0], "invalid.name"), ENODATA);
442 }
443
444 Result = LXT_RESULT_SUCCESS;
445
446 ErrorExit:
447 XattrTestDeletePaths(Fds);
448 return Result;
449 }
450
451 int XattrSetTest(PLXT_ARGS Args)
452
453 /*++
454 --*/
455
456 {
457
458 char* AttrName;
459 char Buffer[1024];
460 int Count;
461 char* DynamicBuffer;
462 int DynamicBufferSize;
463 int Fds[LXT_XATTR_PATH_COUNT];
464 int Index;
465 char* Name = "security.foo";
466 int NameIndex;
467 ssize_t Result;
468 int Size;
469 struct
470 {
471 char Name[256];
472 bool Found;
473 } TestXattrs[103];
474
475 int TotalCount;
476 int TotalSize;
477
478 DynamicBuffer = NULL;
479 LxtCheckErrno(XattrTestCreatePaths(Fds));
480
481 //
482 // Check for invalid parameters.
483 //
484
485 LxtCheckErrnoFailure(LxtSetxattr(0x1, Name, Buffer, sizeof(Buffer), 0), EFAULT);
486 LxtCheckErrnoFailure(LxtLsetxattr(0x1, Name, Buffer, sizeof(Buffer), 0), EFAULT);
487 LxtCheckErrnoFailure(LxtFsetxattr(-1, Name, Buffer, sizeof(Buffer), 0), EBADF);
488
489 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], 0x1, Buffer, sizeof(Buffer), 0), EFAULT);
490 LxtCheckErrnoFailure(LxtLsetxattr(g_XattrPaths[0], 0x1, Buffer, sizeof(Buffer), 0), EFAULT);
491 LxtCheckErrnoFailure(LxtFsetxattr(Fds[0], 0x1, Buffer, sizeof(Buffer), 0), EFAULT);
492
493 if (g_LxtFsInfo.FsType != LxtFsTypeVirtioFs)
494 {
495 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer), 0), ENOTSUP);
496 LxtCheckErrnoFailure(LxtLsetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer), 0), ENOTSUP);
497 LxtCheckErrnoFailure(LxtFsetxattr(Fds[0], "invalid.name", Buffer, sizeof(Buffer), 0), ENOTSUP);
498
499 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], "security.", Buffer, sizeof(Buffer), 0), EINVAL);
500 LxtCheckErrnoFailure(LxtLsetxattr(g_XattrPaths[0], "security.", Buffer, sizeof(Buffer), 0), EINVAL);
501 LxtCheckErrnoFailure(LxtFsetxattr(Fds[0], "security.", Buffer, sizeof(Buffer), 0), EINVAL);
502
503 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], "trusted.", Buffer, sizeof(Buffer), 0), EINVAL);
504 LxtCheckErrnoFailure(LxtLsetxattr(g_XattrPaths[0], "trusted.", Buffer, sizeof(Buffer), 0), EINVAL);
505 LxtCheckErrnoFailure(LxtFsetxattr(Fds[0], "trusted.", Buffer, sizeof(Buffer), 0), EINVAL);
506
507 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], "user.", Buffer, sizeof(Buffer), 0), EINVAL);
508 LxtCheckErrnoFailure(LxtLsetxattr(g_XattrPaths[0], "user.", Buffer, sizeof(Buffer), 0), EINVAL);
509 LxtCheckErrnoFailure(LxtFsetxattr(Fds[0], "user.", Buffer, sizeof(Buffer), 0), EINVAL);
510 }
511 else
512 {
513 // The virtioFs implementation does not restrict the allowed attribute names.
514 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer), 0));
515 LxtCheckErrno(LxtLsetxattr(g_XattrPaths[0], "invalid.name", Buffer, sizeof(Buffer), 0));
516 LxtCheckErrno(LxtFsetxattr(Fds[0], "invalid.name", Buffer, sizeof(Buffer), 0));
517 }
518
519 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], "system.", Buffer, sizeof(Buffer), 0), ENOTSUP);
520 LxtCheckErrnoFailure(LxtLsetxattr(g_XattrPaths[0], "system.", Buffer, sizeof(Buffer), 0), ENOTSUP);
521 LxtCheckErrnoFailure(LxtFsetxattr(Fds[0], "system.", Buffer, sizeof(Buffer), 0), ENOTSUP);
522
523 AttrName =
524 "user."
525 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
526 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
527 "ooooooooooo";
528 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], AttrName, Buffer, sizeof(Buffer), 0), ERANGE);
529 LxtCheckErrnoFailure(LxtLsetxattr(g_XattrPaths[0], AttrName, Buffer, sizeof(Buffer), 0), ERANGE);
530 LxtCheckErrnoFailure(LxtFsetxattr(Fds[0], AttrName, Buffer, sizeof(Buffer), 0), ERANGE);
531
532 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], Name, Buffer, sizeof(Buffer), 10), EINVAL);
533
534 //
535 // Create an attribute and read it back, using various buffer sizes.
536 //
537
538 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], "user.test", "1234", 4, 0));
539 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.test", NULL, 0));
540 LxtCheckEqual(Size, 4, "%d");
541 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.test", Buffer, sizeof(Buffer)));
542 LxtCheckEqual(Size, 4, "%d");
543 Buffer[4] = '\0';
544 LxtCheckStringEqual(Buffer, "1234");
545 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.test", Buffer, 4));
546 LxtCheckEqual(Size, 4, "%d");
547 Buffer[4] = '\0';
548 LxtCheckStringEqual(Buffer, "1234");
549 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[0], "user.test", Buffer, 3), ERANGE);
550 LxtCheckErrnoZeroSuccess(LxtRemovexattr(g_XattrPaths[0], "user.test"));
551
552 //
553 // Create a max length attribute, and ensure that it exists afterwards.
554 //
555 // N.B. Max length is based on ext4 limits; LxFs and DrvFs allow bigger
556 // attributes.
557 //
558
559 DynamicBuffer = malloc(LXT_XATTR_SIZE_MAX);
560 for (Index = 0; Index < LXT_XATTR_SIZE_MAX; Index += 1)
561 {
562 DynamicBuffer[Index] = (char)Index;
563 }
564
565 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], "user.0", DynamicBuffer, LXT_XATTR_SIZE_MAX, 0));
566 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.0", NULL, 0));
567 LxtCheckEqual(Size, LXT_XATTR_SIZE_MAX, "%d");
568 LxtCheckErrnoZeroSuccess(LxtRemovexattr(g_XattrPaths[0], "user.0"));
569
570 Count = 0;
571 memset(TestXattrs, 0, sizeof(TestXattrs));
572
573 //
574 // Create a zero length attribute.
575 //
576
577 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], "user.zero", NULL, 0, 0));
578 LxtCheckErrnoZeroSuccess(LxtGetxattr(g_XattrPaths[0], "user.zero", NULL, 0));
579 strncpy(TestXattrs[Count].Name, "user.zero", sizeof(TestXattrs[Count].Name) - 1);
580 Count += 1;
581
582 //
583 // Create an attribute with the maximum name length.
584 //
585
586 if (g_LxtFsInfo.Flags.DrvFsBehavior != 0)
587 {
588 AttrName =
589 "user."
590 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
591 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
592 "oooooooooooooo";
593 }
594 else
595 {
596 AttrName =
597 "user."
598 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
599 "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
600 "oooooooooooooooooo";
601 }
602
603 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], AttrName, NULL, 0, 0));
604 LxtCheckErrnoZeroSuccess(LxtGetxattr(g_XattrPaths[0], AttrName, NULL, 0));
605 strncpy(TestXattrs[Count].Name, AttrName, sizeof(TestXattrs[Count].Name) - 1);
606 Count += 1;
607
608 //
609 // A bunch of attributes to exercise listing.
610 //
611
612 for (int Index = 0; Index < 100; Index += 1)
613 {
614 snprintf(TestXattrs[Count].Name, sizeof(TestXattrs[Count].Name), "user.test%d", Index);
615
616 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], TestXattrs[Count].Name, DynamicBuffer, 10, 0));
617
618 Count += 1;
619 }
620
621 //
622 // Check the behavior of XATTR_CREATE.
623 //
624
625 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.test0", NULL, 0));
626 LxtCheckEqual(Size, 10, "%d");
627 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], "user.test0", DynamicBuffer, 15, XATTR_CREATE), EEXIST);
628
629 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.test0", NULL, 0));
630 LxtCheckEqual(Size, 10, "%d");
631 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], "user.new", DynamicBuffer, 15, XATTR_CREATE));
632
633 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.new", NULL, 0));
634 LxtCheckEqual(Size, 15, "%d");
635 strncpy(TestXattrs[Count].Name, "user.new", sizeof(TestXattrs[Count].Name) - 1);
636 Count += 1;
637 //
638 // Check the behavior of XATTR_REPLACE.
639 //
640
641 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.test0", NULL, 0));
642 LxtCheckEqual(Size, 10, "%d");
643 LxtCheckErrnoFailure(LxtSetxattr(g_XattrPaths[0], "user.new2", DynamicBuffer, 15, XATTR_REPLACE), ENODATA);
644
645 LxtCheckErrnoFailure(LxtGetxattr(g_XattrPaths[0], "user.new2", NULL, 0), ENODATA);
646
647 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], "user.new", DynamicBuffer, 10, XATTR_REPLACE));
648
649 LxtCheckErrno(Size = GetXattr(g_XattrPaths[0], "user.new", NULL, 0));
650 LxtCheckEqual(Size, 10, "%d");
651
652 //
653 // Set a zero-length extended attribute with XATTR_REPLACE.
654 //
655 // N.B. Plan 9 does not support this, as it treats this operation like a
656 // remove.
657 //
658
659 if (g_LxtFsInfo.FsType != LxtFsTypePlan9)
660 {
661 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], "user.new", NULL, 0, XATTR_REPLACE));
662
663 LxtCheckErrnoZeroSuccess(LxtGetxattr(g_XattrPaths[0], "user.new", NULL, 0));
664 LxtCheckErrnoZeroSuccess(LxtSetxattr(g_XattrPaths[0], "user.new", "", 0, XATTR_REPLACE));
665
666 LxtCheckErrnoZeroSuccess(LxtGetxattr(g_XattrPaths[0], "user.new", NULL, 0));
667 }
668
669 //
670 // List the attributes.
671 //
672
673 TotalCount = Count;
674 for (Index = 0; Index < 10; Index += 1)
675 {
676 LxtCheckErrno(DynamicBufferSize = LxtListxattr(g_XattrPaths[0], 0, NULL));
677 LxtLogInfo("listxattr returned %d", DynamicBufferSize);
678 DynamicBuffer = realloc(DynamicBuffer, DynamicBufferSize);
679 if (DynamicBuffer == NULL)
680 {
681 Result = LXT_RESULT_FAILURE;
682 LxtLogError("realloc(%p %d) failed", DynamicBuffer, DynamicBufferSize);
683 goto ErrorExit;
684 }
685
686 //
687 // Ensure that the number of extended attributes returned matches the number created.
688 //
689
690 DynamicBufferSize = LxtListxattr(g_XattrPaths[0], DynamicBuffer, DynamicBufferSize);
691 if (DynamicBufferSize > 0)
692 {
693 break;
694 }
695 else if (errno != ERANGE)
696 {
697 LxtLogError("listxattr returned %d", errno);
698 goto ErrorExit;
699 }
700
701 //
702 // Sleep before retrying.
703 //
704
705 sleep(1);
706 }
707
708 if (DynamicBufferSize < 0)
709 {
710 LxtLogError("listxattr returned %d", errno);
711 Result = LXT_RESULT_FAILURE;
712 goto ErrorExit;
713 }
714
715 for (Index = 0; Index < DynamicBufferSize; Index += strlen(&DynamicBuffer[Index]) + 1)
716 {
717 for (NameIndex = 0; NameIndex < TotalCount; NameIndex += 1)
718 {
719 if (strcmp(TestXattrs[NameIndex].Name, &DynamicBuffer[Index]) == 0)
720 {
721 if (TestXattrs[NameIndex].Found != false)
722 {
723 LxtLogError("Duplicate attribute: %s", &DynamicBuffer[Index]);
724 Result = LXT_RESULT_FAILURE;
725 goto ErrorExit;
726 }
727
728 TestXattrs[NameIndex].Found = true;
729 break;
730 }
731 }
732
733 if (NameIndex == TotalCount)
734 {
735 LxtLogError("Unknown attribute in listing: %s", &DynamicBuffer[Index]);
736 Result = LXT_RESULT_FAILURE;
737 goto ErrorExit;
738 }
739
740 LxtRemovexattr(g_XattrPaths[0], &DynamicBuffer[Index]);
741 Count -= 1;
742 }
743
744 for (NameIndex = 0; NameIndex < TotalCount; NameIndex += 1)
745 {
746 if (TestXattrs[NameIndex].Found == false)
747 {
748 LxtLogError("Attribute missing from listing: %s", TestXattrs[NameIndex].Name);
749 Result = LXT_RESULT_FAILURE;
750 goto ErrorExit;
751 }
752 }
753
754 LxtCheckEqual(Count, 0, "%d");
755 LxtCheckEqual(LxtListxattr(g_XattrPaths[0], DynamicBuffer, DynamicBufferSize), 0, "%d");
756
757 //
758 // Ensure that two extended attributes with the same name but different
759 // cases can be created.
760 //
761 // N.B. DrvFs, WslFs and Plan 9 do not support this.
762 //
763
764 if (g_LxtFsInfo.Flags.DrvFsBehavior == 0)
765 {
766 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.foo", NULL, 0, 0));
767 LxtCheckErrno(LxtSetxattr(g_XattrPaths[0], "user.FOO", NULL, 0, 0));
768 LxtCheckErrno(Result = LxtListxattr(g_XattrPaths[0], Buffer, sizeof(Buffer)));
769 Count = 0;
770 for (Index = 0; Index < Result; Index += strlen(&Buffer[Index]) + 1)
771 {
772 LxtLogInfo("%s", &Buffer[Index]);
773 Count += 1;
774 }
775
776 LxtCheckEqual(Count, 2, "%d");
777 }
778
779 Result = LXT_RESULT_SUCCESS;
780
781 ErrorExit:
782 XattrTestDeletePaths(Fds);
783 if (DynamicBuffer != NULL)
784 {
785 free(DynamicBuffer);
786 }
787
788 return (int)Result;
789 }
790
791 int XattrAccessTest(PLXT_ARGS Args)
792
793 /*++
794 --*/
795
796 {
797
798 // Example system.posix_acl_access structure created by "setfacl -m u:root:r"
799 char AclAccess[] = {2, 0, 0, 0, 1, 0, 6, 0, 0xff, 0xff, 0xff, 0xff, 2, 0, 4, 0, 0, 0, 0, 0, 4, 0,
800 4, 0, 0xff, 0xff, 0xff, 0xff, 16, 0, 4, 0, 0xff, 0xff, 0xff, 0xff, 32, 0, 4, 0, -1, -1, -1, -1};
801
802 // Example security.capability structure created by "setcap cap_net_raw+ep"
803 char Capability[] = {1, 0, 0, 2, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
804
805 char Buffer[1024];
806 struct __user_cap_data_struct CapData[2];
807 struct __user_cap_header_struct CapHeader;
808 int ChildPid;
809 int Fd;
810 ssize_t Result;
811
812 ChildPid = -1;
813 Fd = -1;
814 LxtCheckErrno(Fd = creat(LXT_XATTR_ACCESS_FILE_PATH, 0777));
815
816 /*
817
818 //
819 // TODO: Enable this test variation once extended attributes in the system
820 // namespace are supported.
821 //
822
823 //
824 // Set the system.posix_acl_access EA and validate access to get, set, and list.
825 //
826
827 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", AclAccess, sizeof(AclAccess), 0));
828 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", Buffer, sizeof(Buffer)));
829 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0000));
830
831 LxtCheckErrno(ChildPid = fork());
832 if (ChildPid == 0) {
833 LxtCheckErrno(prctl(PR_SET_KEEPCAPS, 1));
834 LxtCheckErrno(setgid(LXT_XATTR_GID));
835 LxtCheckErrno(setuid(LXT_XATTR_UID));
836 memset(&CapData, 0, sizeof(CapData));
837 memset(&CapHeader, 0, sizeof(CapHeader));
838 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
839 CapData[CAP_TO_INDEX(CAP_FOWNER)].permitted |= CAP_TO_MASK(CAP_FOWNER);
840 CapData[0].effective = CapData[0].permitted;
841 CapData[1].effective = CapData[1].permitted;
842 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
843 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
844 LxtCheckEqual(Result, sizeof("system.posix_acl_access"), "%Iu");
845 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", Buffer, sizeof(Buffer)));
846 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", AclAccess, sizeof(AclAccess), 0));
847
848 //
849 // Drop the CAP_FOWNER capability and attempt again.
850 //
851
852 memset(&CapData, 0, sizeof(CapData));
853 memset(&CapHeader, 0, sizeof(CapHeader));
854 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
855 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
856 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
857 LxtCheckEqual(Result, sizeof("system.posix_acl_access"), "%Iu");
858 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", Buffer, sizeof(Buffer)));
859 LxtCheckErrnoFailure(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", AclAccess, sizeof(AclAccess), 0),
860 EPERM); Result = LXT_RESULT_SUCCESS; goto ErrorExit;
861 }
862
863 //
864 // Wait for the child to exit.
865 //
866
867 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
868 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0000));
869
870 //
871 // Set the system.posix_acl_access EA and ensure it is able to be queried.
872 //
873
874 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", AclAccess, sizeof(AclAccess), 0));
875 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", Buffer, sizeof(Buffer)));
876 LxtCheckErrno(chown(LXT_XATTR_ACCESS_FILE_PATH, LXT_XATTR_UID, LXT_XATTR_GID));
877
878 LxtCheckErrno(ChildPid = fork());
879 if (ChildPid == 0) {
880 LxtCheckErrno(prctl(PR_SET_KEEPCAPS, 1));
881 LxtCheckErrno(setgid(LXT_XATTR_GID));
882 LxtCheckErrno(setuid(LXT_XATTR_UID));
883 memset(&CapData, 0, sizeof(CapData));
884 memset(&CapHeader, 0, sizeof(CapHeader));
885 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
886 CapData[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted |= CAP_TO_MASK(CAP_DAC_OVERRIDE);
887 CapData[0].effective = CapData[0].permitted;
888 CapData[1].effective = CapData[1].permitted;
889 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
890 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
891 LxtCheckEqual(Result, sizeof("system.posix_acl_access"), "%Iu");
892 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", Buffer, sizeof(Buffer)));
893 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", AclAccess, sizeof(AclAccess), 0));
894
895 //
896 // Drop the CAP_DAC_OVERRIDE capability and attempt again.
897 //
898
899 memset(&CapData, 0, sizeof(CapData));
900 memset(&CapHeader, 0, sizeof(CapHeader));
901 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
902 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
903 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
904 LxtCheckEqual(Result, sizeof("system.posix_acl_access"), "%Iu");
905 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", Buffer, sizeof(Buffer)));
906 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access", AclAccess, sizeof(AclAccess), 0));
907 Result = LXT_RESULT_SUCCESS;
908 goto ErrorExit;
909 }
910
911 //
912 // Wait for the child to exit.
913 //
914
915 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
916 LxtCheckErrno(LxtRemovexattr(LXT_XATTR_ACCESS_FILE_PATH, "system.posix_acl_access"));
917 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0777));
918
919 */
920
921 //
922 // Set the security.capability EA and validate access to get, set, and list.
923 //
924
925 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Capability, sizeof(Capability), 0));
926 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Buffer, sizeof(Buffer)));
927 LxtCheckEqual(Result, sizeof(Capability), "%Iu");
928 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0000));
929 LxtCheckErrno(ChildPid = fork());
930 if (ChildPid == 0)
931 {
932 LxtCheckErrno(prctl(PR_SET_KEEPCAPS, 1));
933 LxtCheckErrno(setgid(LXT_XATTR_GID));
934 LxtCheckErrno(setuid(LXT_XATTR_UID));
935 memset(&CapData, 0, sizeof(CapData));
936 memset(&CapHeader, 0, sizeof(CapHeader));
937 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
938 CapData[CAP_TO_INDEX(CAP_SETFCAP)].permitted |= CAP_TO_MASK(CAP_SETFCAP);
939 CapData[0].effective = CapData[0].permitted;
940 CapData[1].effective = CapData[1].permitted;
941 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
942 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
943 LxtCheckEqual(Result, sizeof("security.capability"), "%Iu");
944 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Buffer, sizeof(Buffer)));
945 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Capability, sizeof(Capability), 0));
946
947 //
948 // Drop the CAP_SETFCAP capability and attempt again.
949 //
950
951 memset(&CapData, 0, sizeof(CapData));
952 memset(&CapHeader, 0, sizeof(CapHeader));
953 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
954 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
955 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
956 LxtCheckEqual(Result, sizeof("security.capability"), "%Iu");
957 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Buffer, sizeof(Buffer)));
958 LxtCheckEqual(Result, sizeof(Capability), "%Iu");
959 LxtCheckErrnoFailure(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Capability, sizeof(Capability), 0), EPERM);
960 Result = LXT_RESULT_SUCCESS;
961 goto ErrorExit;
962 }
963
964 //
965 // Wait for the child to exit.
966 //
967
968 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
969
970 //
971 // Validate that the security.capability EA is removed when the file changes owners.
972 //
973
974 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Capability, sizeof(Capability), 0));
975 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Buffer, sizeof(Buffer)));
976 LxtCheckErrno(chown(LXT_XATTR_ACCESS_FILE_PATH, 0, 0));
977 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
978 LxtCheckEqual(Result, 0, "%Iu");
979 LxtCheckErrnoFailure(LxtGetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Buffer, sizeof(Buffer)), ENODATA);
980 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Capability, sizeof(Capability), 0));
981 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Buffer, sizeof(Buffer)));
982 LxtCheckEqual(Result, sizeof(Capability), "%Iu");
983 LxtCheckErrno(LxtRemovexattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability"));
984 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
985 LxtCheckEqual(Result, 0, "%Iu");
986 LxtCheckErrnoFailure(LxtGetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.capability", Buffer, sizeof(Buffer)), ENODATA);
987 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0777));
988
989 //
990 // Set the security.foo EA and validate access to get, set, and list.
991 //
992
993 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Capability, sizeof(Capability), 0));
994 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Buffer, sizeof(Buffer)));
995 LxtCheckEqual(Result, sizeof(Capability), "%Iu");
996 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0000));
997 LxtCheckErrno(ChildPid = fork());
998 if (ChildPid == 0)
999 {
1000 LxtCheckErrno(prctl(PR_SET_KEEPCAPS, 1));
1001 LxtCheckErrno(setgid(LXT_XATTR_GID));
1002 LxtCheckErrno(setuid(LXT_XATTR_UID));
1003 memset(&CapData, 0, sizeof(CapData));
1004 memset(&CapHeader, 0, sizeof(CapHeader));
1005 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1006 CapData[CAP_TO_INDEX(CAP_SYS_ADMIN)].permitted |= CAP_TO_MASK(CAP_SYS_ADMIN);
1007 CapData[0].effective = CapData[0].permitted;
1008 CapData[1].effective = CapData[1].permitted;
1009 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1010 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1011 LxtCheckEqual(Result, sizeof("security.foo"), "%Iu");
1012 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Buffer, sizeof(Buffer)));
1013 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Capability, sizeof(Capability), 0));
1014
1015 //
1016 // Drop the CAP_SYS_ADMIN capability and attempt again.
1017 //
1018
1019 memset(&CapData, 0, sizeof(CapData));
1020 memset(&CapHeader, 0, sizeof(CapHeader));
1021 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1022 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1023 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1024 LxtCheckEqual(Result, sizeof("security.foo"), "%Iu");
1025 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Buffer, sizeof(Buffer)));
1026 LxtCheckEqual(Result, sizeof(Capability), "%Iu");
1027 LxtCheckErrnoFailure(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Capability, sizeof(Capability), 0), EPERM);
1028 Result = LXT_RESULT_SUCCESS;
1029 goto ErrorExit;
1030 }
1031
1032 //
1033 // Wait for the child to exit.
1034 //
1035
1036 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
1037
1038 //
1039 // Validate that the security.foo EA is not removed when the file changes owners.
1040 //
1041
1042 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Capability, sizeof(Capability), 0));
1043 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Buffer, sizeof(Buffer)));
1044 LxtCheckErrno(chown(LXT_XATTR_ACCESS_FILE_PATH, 0, 0));
1045 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1046 LxtCheckEqual(Result, sizeof("security.foo"), "%Iu");
1047 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Buffer, sizeof(Buffer)));
1048 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Capability, sizeof(Capability), 0));
1049 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Buffer, sizeof(Buffer)));
1050 LxtCheckEqual(Result, sizeof(Capability), "%Iu");
1051 LxtCheckErrno(LxtRemovexattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo"));
1052 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1053 LxtCheckEqual(Result, 0, "%Iu");
1054 LxtCheckErrnoFailure(LxtGetxattr(LXT_XATTR_ACCESS_FILE_PATH, "security.foo", Buffer, sizeof(Buffer)), ENODATA);
1055 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0777));
1056
1057 //
1058 // Set the user.foo EA and ensure it is able to be queried.
1059 //
1060
1061 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", LXT_XATTR_TEST_VALUE, LXT_XATTR_TEST_LENGTH, 0));
1062 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", NULL, 0));
1063 LxtCheckErrno(chown(LXT_XATTR_ACCESS_FILE_PATH, LXT_XATTR_UID, LXT_XATTR_GID));
1064 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0700));
1065
1066 //
1067 // Fork and change the child to a UID that does not own the file.
1068 //
1069
1070 LxtCheckErrno(ChildPid = fork());
1071 if (ChildPid == 0)
1072 {
1073 LxtCheckErrno(setuid(LXT_XATTR_UID));
1074 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1075 LxtCheckEqual(Result, sizeof("user.foo"), "%Iu");
1076 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", NULL, 0));
1077 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", LXT_XATTR_TEST_VALUE, LXT_XATTR_TEST_LENGTH, 0));
1078 goto ErrorExit;
1079 }
1080
1081 //
1082 // Wait for the child to exit.
1083 //
1084
1085 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
1086 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0070));
1087
1088 //
1089 // Fork and change the child to a UID that does not own the file.
1090 //
1091
1092 LxtCheckErrno(ChildPid = fork());
1093 if (ChildPid == 0)
1094 {
1095
1096 //
1097 // First try with the CAP_DAC_OVERRIDE capability.
1098 //
1099
1100 LxtCheckErrno(prctl(PR_SET_KEEPCAPS, 1));
1101 LxtCheckErrno(setuid(LXT_XATTR_UID + 1));
1102 memset(&CapData, 0, sizeof(CapData));
1103 memset(&CapHeader, 0, sizeof(CapHeader));
1104 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1105 CapData[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted |= CAP_TO_MASK(CAP_DAC_OVERRIDE);
1106 CapData[0].effective = CapData[0].permitted;
1107 CapData[1].effective = CapData[1].permitted;
1108 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1109 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1110 LxtCheckEqual(Result, sizeof("user.foo"), "%Iu");
1111 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", NULL, 0));
1112 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", LXT_XATTR_TEST_VALUE, LXT_XATTR_TEST_LENGTH, 0));
1113
1114 //
1115 // Drop the CAP_DAC_OVERRIDE capability and attempt again.
1116 //
1117
1118 memset(&CapData, 0, sizeof(CapData));
1119 memset(&CapHeader, 0, sizeof(CapHeader));
1120 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1121 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1122 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1123 LxtCheckEqual(Result, sizeof("user.foo"), "%Iu");
1124 LxtCheckErrnoFailure(LxtGetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", NULL, 0), EACCES);
1125 LxtCheckErrnoFailure(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", LXT_XATTR_TEST_VALUE, LXT_XATTR_TEST_LENGTH, 0), EACCES);
1126 goto ErrorExit;
1127 }
1128
1129 //
1130 // Wait for the child to exit.
1131 //
1132
1133 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
1134 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0007));
1135
1136 //
1137 // Fork and change the child to a UID that does not own the file with the
1138 // other bits set.
1139 //
1140
1141 LxtCheckErrno(ChildPid = fork());
1142 if (ChildPid == 0)
1143 {
1144 LxtCheckErrno(setuid(LXT_XATTR_UID + 1));
1145 memset(&CapData, 0, sizeof(CapData));
1146 memset(&CapHeader, 0, sizeof(CapHeader));
1147 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1148 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1149 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1150 LxtCheckEqual(Result, sizeof("user.foo"), "%Iu");
1151 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", NULL, 0));
1152 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", LXT_XATTR_TEST_VALUE, LXT_XATTR_TEST_LENGTH, 0));
1153 goto ErrorExit;
1154 }
1155
1156 //
1157 // Wait for the child to exit.
1158 //
1159
1160 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
1161 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0002));
1162
1163 //
1164 // Fork and change the child to a UID that does not own the file with the
1165 // other bits set.
1166 //
1167
1168 LxtCheckErrno(ChildPid = fork());
1169 if (ChildPid == 0)
1170 {
1171 LxtCheckErrno(setuid(LXT_XATTR_UID + 1));
1172 memset(&CapData, 0, sizeof(CapData));
1173 memset(&CapHeader, 0, sizeof(CapHeader));
1174 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1175 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1176 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1177 LxtCheckEqual(Result, sizeof("user.foo"), "%Iu");
1178 LxtCheckErrnoFailure(LxtGetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", NULL, 0), EACCES);
1179 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", LXT_XATTR_TEST_VALUE, LXT_XATTR_TEST_LENGTH, 0));
1180 goto ErrorExit;
1181 }
1182
1183 //
1184 // Wait for the child to exit.
1185 //
1186
1187 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
1188 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0004));
1189
1190 //
1191 // Fork and change the child to a UID that does not own the file with the
1192 // other bits set.
1193 //
1194
1195 LxtCheckErrno(ChildPid = fork());
1196 if (ChildPid == 0)
1197 {
1198 LxtCheckErrno(setuid(LXT_XATTR_UID + 1));
1199 memset(&CapData, 0, sizeof(CapData));
1200 memset(&CapHeader, 0, sizeof(CapHeader));
1201 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1202 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1203 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1204 LxtCheckEqual(Result, sizeof("user.foo"), "%Iu");
1205 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", NULL, 0));
1206 LxtCheckErrnoFailure(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo", LXT_XATTR_TEST_VALUE, LXT_XATTR_TEST_LENGTH, 0), EACCES);
1207 goto ErrorExit;
1208 }
1209
1210 //
1211 // Wait for the child to exit.
1212 //
1213
1214 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
1215 LxtCheckErrno(LxtRemovexattr(LXT_XATTR_ACCESS_FILE_PATH, "user.foo"));
1216 LxtCheckErrno(chown(LXT_XATTR_ACCESS_FILE_PATH, 0, 0));
1217 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0777));
1218
1219 //
1220 // Test the trusted namespace, the caller requires the CAP_SYS_ADMIN
1221 // capability to read to write EA's in the trusted namespace.
1222 //
1223
1224 Buffer[0] = 'y';
1225 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "trusted.overlay.opaque", Buffer, 1, 0));
1226 LxtCheckErrno(Result = GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "trusted.overlay.opaque", Buffer, sizeof(Buffer)));
1227 LxtCheckErrno(chmod(LXT_XATTR_ACCESS_FILE_PATH, 0000));
1228
1229 LxtCheckErrno(ChildPid = fork());
1230 if (ChildPid == 0)
1231 {
1232 LxtCheckErrno(prctl(PR_SET_KEEPCAPS, 1));
1233 memset(&CapData, 0, sizeof(CapData));
1234 memset(&CapHeader, 0, sizeof(CapHeader));
1235 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1236 CapData[CAP_TO_INDEX(CAP_SYS_ADMIN)].permitted |= CAP_TO_MASK(CAP_SYS_ADMIN);
1237 CapData[0].effective = CapData[0].permitted;
1238 CapData[1].effective = CapData[1].permitted;
1239 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1240 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1241 LxtCheckEqual(Result, sizeof("trusted.overlay.opaque"), "%Iu");
1242 LxtCheckErrno(GetXattr(LXT_XATTR_ACCESS_FILE_PATH, "trusted.overlay.opaque", NULL, 0));
1243 LxtCheckErrno(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "trusted.overlay.opaque", Buffer, 1, 0));
1244
1245 //
1246 // Drop the CAP_SYS_ADMIN capability and attempt again.
1247 //
1248 // N.B. Unlike other namespaces, names in the trusted namespace will
1249 // not be returned if the caller does not have the correct permission.
1250 // This is file system specific, and Plan 9 does not do this.
1251 //
1252
1253 memset(&CapData, 0, sizeof(CapData));
1254 memset(&CapHeader, 0, sizeof(CapHeader));
1255 CapHeader.version = _LINUX_CAPABILITY_VERSION_3;
1256 LxtCheckErrno(LxtCapSet(&CapHeader, CapData));
1257 LxtCheckErrno(Result = LxtListxattr(LXT_XATTR_ACCESS_FILE_PATH, 0, NULL));
1258 if ((g_LxtFsInfo.FsType == LxtFsTypePlan9) || (g_LxtFsInfo.FsType == LxtFsTypeVirtioFs))
1259 {
1260 LxtCheckEqual(Result, sizeof("trusted.overlay.opaque"), "%Iu");
1261 }
1262 else
1263 {
1264 LxtCheckEqual(Result, 0, "%Iu");
1265 }
1266
1267 LxtCheckErrnoFailure(LxtGetxattr(LXT_XATTR_ACCESS_FILE_PATH, "trusted.overlay.opaque", NULL, 0), ENODATA);
1268 LxtCheckErrnoFailure(LxtSetxattr(LXT_XATTR_ACCESS_FILE_PATH, "trusted.overlay.opaque", Buffer, 1, 0), EPERM);
1269 goto ErrorExit;
1270 }
1271
1272 //
1273 // Wait for the child to exit.
1274 //
1275
1276 LxtCheckErrno(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
1277
1278 Result = LXT_RESULT_SUCCESS;
1279
1280 ErrorExit:
1281 if (Fd != 0)
1282 {
1283 LxtClose(Fd);
1284 }
1285
1286 if (ChildPid == 0)
1287 {
1288 _exit(Result);
1289 }
1290
1291 unlink(LXT_XATTR_ACCESS_FILE_PATH);
1292 return (int)Result;
1293 }