428 Commits
Author SHA1 Message Date
Ernesto A. Fernández 3721463ba7 0.2.1
This release gets apfs-label and mkapfs to run on systems with 16K
pages. Similar changes are also needed in the fsck, but that can wait
because it's only a testing tool for my own use.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-06-02 16:50:22 -03:00
Integral da54ccefa0 apfsck: use DIV_ROUND_UP macro 2025-01-09 12:42:08 -03:00
Ernesto A. Fernández a6f9ec1485 apfsck: implement more checks for fusion drives
I was hoping that this commit would include all layout checks for fusion
drives, but I couldn't quite figure out tenant records, or why there are
multiple different cache mechanisms. I'm having a hard time getting back
into this research, and I'm not even sure if there's any point to it at
all, so I'll just leave things as they are for now.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-01-08 19:45:52 -03:00
Ernesto A. Fernández 54fc1b615b 0.2.0
I've never made any releases for apfsprogs before because it was mostly
intended for my own use, to help me test the driver. But at this point a
few of the tools might actually be useful to others, and even the mkfs
is probably mature enough to be safe, so I guess I should start. I'm
using 0.2.0 because all of the man pages have been set to 0.1 until now.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-11-06 19:51:38 -03:00
Ernesto A. Fernández 8c109f51a9 apfsck: check the block zero magic before all else
When I mistakenly run the fsck on a whole disk, instead of running it on
the apfs partition, I get a confusing "block size is too small" error
message. To avoid this noise, run no checks at all until we have
confirmed that we are working with an apfs filesystem. If not, explain
this clearly to the user.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-11-05 18:55:54 -03:00
Ernesto A. Fernández 9a13a8ffbe apfsck: update boundary checks for free_next array
Back when I was only working with relatively small disks I was under the
impression that ip_bm_free_next was just a fixed-length 256-bit field.
In reality it's an array of 16-bit fields, with 16 times as many entries
as the number of bitmap blocks needed to map the internal pool. Fix the
boundary checks in spaceman_256_from_off() and rename it accordingly.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-11-05 16:26:24 -03:00
Integral 51563c42f3 Fix exit code when GIT_COMMIT is not null (#14) 2024-11-05 16:05:35 -03:00
Integral 56c81b8d1f Replace exit(1) with exit(EXIT_FAILURE) to improve code portablility (#15)
* Replace exit(1) with exit(EXIT_FAILURE) to improve code portablility
2024-11-04 16:45:58 -03:00
Ernesto A. Fernández 5e234275a6 apfsck: let the free ip bitmap list go backwards
While implementing the correct ip bitmap list in the driver, I realized
that expecting all entries between two consecutive free bitmaps to be
used made everything stupidly complicated for no reason. So I just
implemented the list in the way that made sense: allocating new bitmaps
in the head and freeing the old ones in the tail, without worrying about
the direction of the jump for each link. The resulting images were
accepted by the official implementations, so I guess that was indeed the
right way.

My fsck does complain of course, so get rid of this silly check.
Instead, just count the free blocks so that we can later confirm that
every used block is marked as invalid.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-30 19:28:42 -03:00
Ernesto A. Fernández 52d9425738 apfsck: fix size checks for disks not used in full
I just noticed that the fsck reports corruption whenever my mkfs creates
a filesystem that doesn't use the whole disk. I don't test this much
because I don't need it right now, and I don't even know if the official
implementations accept it. But it's important to have it working for the
ENOSPC tests of xfstests, which will be important once I actually start
checking for ENOSPC before starting transactions.

Anyway, fix this to the best of my understanding right now, though I may
need to make more changes in the future once I finally get around to
testing these devices on macos.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-30 02:30:35 -03:00
Ernesto A. Fernández ca165ab34c apfsck: fix out-of-bounds write from last patch
The used_bitmaps array was allocated with one slot for each used ip
bitmap block, but it should also have a slot for the free tail. This
isn´t serious because I don't expect anyone to use this fsck other than
me (lots of similar issues probably exist), but it's causing the mkfs
tests to fail, so fix it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-30 02:14:25 -03:00
Ernesto A. Fernández 6ab4fbaa8d apfsck: correct the ip bitmap list checks
I never fully understood how the ip bitmap list was supposed to work,
but now I'm noticing that the difference between what I do and what the
official driver does are bad enough to quickly corrupt the list when a
container moves back and forth. Of course this is only an issue for
filesystems above 1.32 TiB or so, but it's still pretty serious.

So, I thought about it harder and I'm pretty sure I finally figured it
out: the array entries for each free bitmap are actually kept in a
linked list, that starts in sm_ip_bm_free_head and ends in
sm_ip_bm_free_tail. All entries outside the list (that is, the entries
for the used blocks) are marked with the invalid index 0xFFFF. The tail
itself also gets 0xFFFF even though it's free, because it has no next
entry - so that accounts for the constant off-by-one weirdness in the
number of free blocks.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-25 17:15:11 -03:00
Ernesto A. Fernández d7c51ee27a apfsck: support wrapped ephemeral objects
As I explained before in commit 19b8d6d8 ("apfsck: verify order of
checkpoint mappings"), ephemeral objects (or at least the spaceman) can
wrap around. Add support for reading such objects to the fsck.

This is of course not possible using only mmap as we do now, so
ephemeral objects will need to be copied to allocated memory, and some
hacky changes are needed to free such memory correctly. Also a few
checks inside free_cpoint_map() have become redundant, so make sure they
happen in full inside parse_cpoint_map() and parse_cpoint_map_blocks()
instead.

For the record, this was all tested against an image created by my
driver after applying patch dfdafd2a07cf ("Wrap ephemeral objects around
if there is no room") and rigging it so that transactions would fail
after a wrapped-around object was discovered.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-23 18:06:42 -03:00
Ernesto A. Fernández 19b8d6d835 apfsck: verify order of checkpoint mappings
I have recently noticed that Apple refuses to acknowledge drives that
were formatted by my mkfs, unless my driver wrote to them at least once.
The official fsck does not report any corruption, but after some
experiments it seems that the problem is that checkpoint mappings are
supposed to be in order, and not leave any holes.

For containers with a multiblock spaceman, the object itself is supposed
to wrap around, again leaving no holes. When the official driver mounts
a 7T container that wrapped around precisely when my driver unmounted
it, the last transaction gets silently discarded. This should be
extremely rare, but I need to fix it.

Start by putting the proper checks in place for the mappings.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-18 16:20:58 -03:00
Ernesto A. Fernández 06284a471d apfsck: remove old comment on multiblock objects
Multiblock ephemeral objects have been supported for a while, but I just
noticed a line that claims otherwise. Get rid of it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-16 17:57:37 -03:00
Ernesto A. Fernández 572ff87dc4 apfsck: add support for empty fusion drives
Add checks for all the fusion-related structures and fields that show up
in an empty fusion drive. This requires a few changes to the way blocks
are read, so that the fsck knows which drive holds the data. Nothing
major though.

With all this in place, the allocation bitmaps add up, which is always
a good sign. I was hoping to split this into multiple patches, but I got
lazy.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-11 18:42:42 -03:00
Ernesto A. Fernández 86b270b6a6 apfsck: add cli option to specify a tier 2 device
As a first step towards supporting fusion drives, add a command line
option to specify the tier 2 device. We now have two global fd's in use,
so give them names that are less confusing. As a simple sanity check,
fix the block count check, which is the first to fail if the fsck gets
run against the main device alone.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-10-11 18:42:32 -03:00
Ernesto A. Fernández 28c0053dcb Allow snapshot xids to match the current xid
I have a check in place to make sure that snapshot xids come strictly
before the current xid, but if a crash happens right after the snapshot
commit they could actually be equal, and that isn't corruption. Allow
it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-05-21 19:53:24 -03:00
Ernesto A. Fernández a393fce90d Allow newer xids in snapshots for sealed volumes
I've just encountered a sealed volume with snapshots, probably for the
first time. I have a check in place to confirm that all snapshots xids
are older than the snapshot, but I had already identified an exception
in the extent reference tree. It seems that more exceptions exist for
sealed volumes. I haven't looked into it in depth, I don't really care
that much because I don't intend to implement sealing. Just ignore this
problem for sealed volumes.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-05-01 20:32:09 -03:00
Ernesto A. Fernández 32e21b8ea7 Document the existence of a new xattr flag
I've just run into an image that uses a new 0x10 xattr flag. I have not
tried to figure it out yet, but document it so that I don't forget.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-05-01 19:41:39 -03:00
Ernesto A. Fernández d384a95ede Add checks for new file extent flags
File extent records have two undocumented flags. One is the crypto flag,
which we don't support yet. As for the other one, I've only seen it once
so far, on an extent that was entirely allocated beyond the end of a
file. I'm guessing that's what it means, but it only seems to be valid
when the volume has the 0x80 incompatible feature. This is all hard to
confirm because I don't know how to preallocate like that in macos, and
the official fsck and driver won't complain at all if you flip this
extent bit.

Put checks in place to see if we trip on something in the future.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-05-01 19:25:30 -03:00
Ernesto A. Fernández 8ce86ec8f3 Add checks for new volume flags
Add to raw.h a few recently noticed flags for the volume superblock. I
don't know much about them yet, but put the usual basic checks in place
in the fsck.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-04-26 20:01:27 -03:00
Ernesto A. Fernández cad634106e apfsck: ignore WAS_EVER_CLONED before the epoch
So far I have mostly ignored this "cloneinfo id epoch" in the fsck, but
I notice now some issues with one of my older images. I guess it was
created before the bugfix, so some inodes have the WAS_CLONED flag, but
not WAS_EVER_CLONED. Since this is technically allowed stop reporting it
as corruption, but leave a warning message in place anyway.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-04-15 21:44:12 -03:00
Ernesto A. Fernández d073e7321d Support tiny disks in the ephemeral info checks
Containers with smaller than 128M use a different value for the minimum
size of the data area. Change this.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-03-28 17:46:31 -03:00
Ernesto A. Fernández 2736e2913f Don't check the sparse byte count for orphans
My driver now splits orphan deletion among multiple transactions, but it
doesn't bother to update the inode record for half-deleted files. This
is reasonable because the orphans are not real files, and we don't want
to waste time on them. My fsck is still checking one field though: the
sparse byte count. Stop that.

By the way, the official driver behaves like us in all cases I've
encountered so far, but I have never seen what it does to sparse files.
I have confirmed, however, that the official fsck has no problem with
this, so it's probably the same.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-03-22 21:38:17 -03:00