]> git.saurik.com Git - apple/hfs.git/blob - tests/cases/test-raw-dev-unaligned.c
hfs-366.70.1.tar.gz
[apple/hfs.git] / tests / cases / test-raw-dev-unaligned.c
1 #include <sys/fcntl.h>
2 #include <unistd.h>
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <sys/param.h>
8 #include <sys/mount.h>
9
10 #include "hfs-tests.h"
11 #include "test-utils.h"
12 #include "disk-image.h"
13
14 TEST(raw_dev_unaligned, .run_as_root = 1);
15
16 int run_raw_dev_unaligned(__unused test_ctx_t *ctx)
17 {
18 struct statfs sfs;
19
20 assert(statfs("/tmp", &sfs) == 0);
21 if (strcmp(sfs.f_fstypename, "hfs")) {
22 printf("raw_dev_aligned needs hfs as root file system - skipping.\n");
23 return 0;
24 }
25
26 int fd = open("/tmp/raw-dev-unaligned", O_CREAT | O_RDWR | O_TRUNC, 0666);
27
28 assert_with_errno(fd >= 0);
29
30 assert_no_err(ftruncate(fd, 4096));
31
32 assert_no_err(fcntl(fd, F_FULLFSYNC));
33
34 struct log2phys l2p = {};
35
36 assert_no_err(fcntl(fd, F_LOG2PHYS_EXT, &l2p));
37
38 assert(!strncmp(sfs.f_mntfromname, "/dev/disk", 9));
39
40 char *rdev;
41 asprintf(&rdev, "/dev/rdisk%s", sfs.f_mntfromname + 9);
42
43 int raw_fd;
44 assert_with_errno((raw_fd = open(rdev, O_RDWR)) >= 0);
45
46 void *buf = malloc(16384);
47
48 off_t offset = l2p.l2p_devoffset;
49
50 // Make p non-aligned
51 char *p = (char *)((((uintptr_t)buf + 64) & ~63) + 8);
52
53 unsigned bs = 4096;
54 if (bs < sfs.f_bsize)
55 bs = sfs.f_bsize;
56
57 check_io(pread(raw_fd, p, bs, offset), bs);
58
59 // Make a change
60 check_io(pwrite(fd, &fd, 4, 0), 4);
61
62 assert_no_err(fcntl(fd, F_FULLFSYNC));
63
64 char *state = malloc(bs);
65
66 /*
67 * Make sure it changed on the raw device so we know we've got the
68 * correct location. We can't actually check the contents because
69 * it's encrypted on iOS.
70 */
71 check_io(pread(raw_fd, state, bs, offset), bs);
72
73 assert(memcmp(state, p, bs));
74
75 assert_no_err(close(fd));
76
77 for (int i = 0; i < 3000; ++i) {
78 for (unsigned i = 0; i < bs; ++i)
79 state[i] ^= 0xff;
80 memcpy(p, state, bs);
81 check_io(pwrite(raw_fd, p, bs, offset), bs);
82 check_io(pread(raw_fd, p, bs, offset), bs);
83 assert(!memcmp(p, state, bs));
84 }
85
86 // cleanup
87 assert_no_err(close(raw_fd));
88 assert_no_err(unlink("/tmp/raw-dev-unaligned"));
89 free(buf);
90 free(state);
91
92 return 0;
93 }