1 #include <TargetConditionals.h>
12 #include <sys/sysctl.h>
13 #include <System/sys/fsgetpath.h>
14 #include <hfs/hfs_fsctl.h>
16 #include "hfs-tests.h"
17 #include "test-utils.h"
19 TEST(list_ids
, .run_as_root
= true)
29 } __attribute__((aligned(4), packed
)) attrs
[MAX_FILES
];
31 static char *path
[MAX_FILES
];
32 static int fd
[MAX_FILES
];
34 static uint32_t max_ids
= 1000000;
35 static uint32_t max_ids_per_iter
= 262144;
37 int run_list_ids(__unused test_ctx_t
*ctx
)
39 // The data partition needs to be HFS
42 assert(statfs("/private/var", &sfs
) == 0);
43 if (strcmp(sfs
.f_fstypename
, "hfs")) {
44 printf("list_ids needs hfs on the data partition.\n");
49 uint32_t *file_ids
= malloc(4 * max_ids
);
52 bzero(file_ids
, 4 * max_ids
);
54 struct listxattrid_cp listxattrid_file_ids
= {
55 .flags
= (LSXCP_PROT_CLASS_A
| LSXCP_PROT_CLASS_B
56 | LSXCP_PROT_CLASS_C
| LSXCP_UNROLLED_KEYS
),
60 listxattrid_file_ids
.count
= max_ids_per_iter
;
61 listxattrid_file_ids
.fileid
= file_ids
+ count
;
63 assert_no_err(fsctl("/private/var", HFSIOC_LISTXATTRID_CP
, &listxattrid_file_ids
, 0));
65 count
+= listxattrid_file_ids
.count
;
66 assert(count
< max_ids
);
67 } while (count
== max_ids_per_iter
);
69 void *buf
= malloc(1 KB
);
70 memset(buf
, 0x25, 1 KB
);
72 for (unsigned i
= 0; i
< MAX_FILES
; i
++) {
74 asprintf(&path
[i
], "/private/var/get-matched_listid.data.%u", getpid()+i
);
77 assert_with_errno((fd
[i
] = open(path
[i
], O_RDWR
| O_TRUNC
| O_CREAT
, 0666)) >= 0);
80 check_io(write(fd
[i
], buf
, 1 KB
), 1 KB
);
82 // Change file to class B
83 assert_no_err(fcntl(fd
[i
], F_SETPROTECTIONCLASS
, 2));
85 struct attrlist attrlist
= {
86 .bitmapcount
= ATTR_BIT_MAP_COUNT
,
87 .commonattr
= ATTR_CMN_FILEID
| ATTR_CMN_DATA_PROTECT_FLAGS
,
90 assert_no_err(fgetattrlist(fd
[i
], &attrlist
, &attrs
[i
], sizeof(attrs
), 0));
91 assert((attrs
[i
].dp_flags
& 0x1f) == 2);
95 bool release_build
= false;
97 if (fcntl(fd
[0], F_RECYCLE
)) {
98 assert_equal_int(errno
, ENOTTY
);
102 // HFS_KR_OP_SET_INFO doesn't run in releae build.
106 for (unsigned i
= 0; i
< MAX_FILES
; i
++) {
108 hfs_key_roll_args_t args
;
110 // Change the revision and os version
111 args
.api_version
= HFS_KR_API_LATEST_VERSION
;
112 args
.operation
= HFS_KR_OP_SET_INFO
;
113 args
.key_revision
= 0x0200;
114 args
.key_os_version
= CP_OS_VERS_PRE_71
;
115 assert_no_err(ffsctl(fd
[i
], HFSIOC_KEY_ROLL
, &args
, 0));
117 args
.operation
= HFS_KR_OP_STATUS
;
118 assert_no_err(ffsctl(fd
[i
], HFSIOC_KEY_ROLL
, &args
, 0));
120 assert(args
.done
== -1
121 && args
.key_revision
== 0x0200
122 && args
.key_os_version
== CP_OS_VERS_PRE_71
);
126 max_ids_per_iter
= 48;
128 bzero(file_ids
, 4 * max_ids
);
130 struct cp_listids list_file_ids
= {
131 .api_version
= CPLIDS_API_VERSION_1
,
132 .flags
= CPLID_MAX_OS_VERSION
| CPLID_PROT_CLASS_B
,
133 .max_key_os_version
= CP_OS_VERS_71
,
137 list_file_ids
.count
= max_ids_per_iter
;
138 list_file_ids
.file_ids
= file_ids
+ count
;
140 if (fsctl("/private/var", HFSIOC_CP_LIST_IDS
, &list_file_ids
, 0) < 0) {
141 assert_with_errno(errno
== EINTR
);
143 bzero(list_file_ids
.state
, sizeof(list_file_ids
.state
));
146 count
+= list_file_ids
.count
;
148 assert(count
< max_ids
);
150 } while (list_file_ids
.count
== max_ids_per_iter
);
152 assert(count
== MAX_FILES
);
154 statfs("/private/var", &sfs
);
156 for (i
= 0; i
< count
; i
++) {
157 char path_name
[PATH_MAX
];
159 if (fsgetpath(path_name
, sizeof(path
), &sfs
.f_fsid
,
160 (uint64_t)file_ids
[i
]) < 0) {
161 assert_with_errno(errno
== ENOENT
);
164 assert(file_ids
[i
] == attrs
[i
].file_id
);
172 for (i
= 0; i
< MAX_FILES
; i
++) {
173 assert_no_err(close(fd
[i
]));
183 #endif // TARGET_OS_EMBEDDED