]>
git.saurik.com Git - apple/copyfile.git/blob - copyfile_test/readonly_fd_test.c
2 // Copyright (c) 2020 Apple Inc. All rights reserved.
12 #include <sys/types.h>
17 #include <sys/xattr.h>
19 #include "readonly_fd_test.h"
20 #include "test_utils.h"
24 bool test_readonly_fd_metadata(const char *basedir
)
26 char filename
[] = ".readonly-ops-XXXXXX";
34 static const char test_name
[] = "readonly_fd_metadata";
35 printf("START [%s]\n", test_name
);
37 assert_with_errno((dirfd
= open(basedir
, O_RDONLY
| O_DIRECTORY
)) != -1);
38 assert_with_errno((tmpfd
= mkstempsat_np(dirfd
, filename
, 0)) != -1);
41 assert_with_errno((fd
= openat(dirfd
, filename
, O_RDONLY
)) != -1);
45 // confirm that writes are disallowed
46 const char data
[] = "failure";
47 assert(write(fd
, data
, sizeof(data
) - 1) == -1);
50 const uid_t uid
= geteuid();
51 const gid_t gid
= getegid();
52 assert_no_err(fchown(fd
, uid
, gid
));
55 assert_no_err(fchmod(fd
, 0644));
56 assert_no_err(fchmod(fd
, 0600));
59 assert_no_err(fchflags(fd
, UF_HIDDEN
));
61 // check setting timestamps with fsetattrlist
62 const time_t mtime
= 978307200;
63 const time_t atime
= mtime
+ 1;
65 struct timeval matimes_usec
[] = {{mtime
, 0}, {atime
, 0}};
66 assert_no_err(futimes(fd
, matimes_usec
));
68 struct attrlist attrlist
= {
69 .bitmapcount
= ATTR_BIT_MAP_COUNT
,
70 .commonattr
= ATTR_CMN_MODTIME
| ATTR_CMN_ACCTIME
,
73 struct timespec mtime
;
74 struct timespec atime
;
75 } matimes_nsec
= {{mtime
, 0}, {atime
, 0}};
76 assert_no_err(fsetattrlist(fd
, &attrlist
, &matimes_nsec
, sizeof(matimes_nsec
), 0));
78 // check adding and removing xattrs
79 static const char key
[] = "local.test-xattr";
80 static const char value
[] = "local.test-xattr.value";
81 assert_no_err(fsetxattr(fd
, key
, value
, sizeof(value
)-1, 0, 0));
82 assert_no_err(fremovexattr(fd
, key
, 0));
85 assert_with_errno((acl
= acl_init(1)) != NULL
);
86 assert_no_err(acl_set_fd(fd
, acl
));
88 // log pass/fail before cleanup
90 printf("PASS [%s]\n", test_name
);
92 printf("FAIL [%s]\n", test_name
);
106 unlinkat(dirfd
, filename
, 0);
116 bool do_readonly_fd_test(const char *apfs_test_directory
, size_t block_size __unused
)
118 // These tests verify the underlying calls needed for COPYFILE_METADATA
119 // operations are safe with O_RDONLY file descriptors. If this fails,
120 // expect <rdar://60074298> to cause many other copyfile() failures.
122 success
= success
&& test_readonly_fd_metadata(apfs_test_directory
);
123 return !success
; // caller expects nonzero to mean failure