Commit Graph
23 Commits
Author SHA1 Message Date
Ernesto A. Fernández 9921ef9205 Implement reads for fusion drives
So far I haven't been able to figure out fusion drives to an extent that
would allow me to implement writes. I'm tired of it, and I think the
effort is probably pointless because apfs fusion drives aren't all that
popular. I might reconsider if people request the feature, but for now
just add read-only support, which is almost trivial.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-02-12 18:27:02 -03:00
Ernesto A. Fernández f78e6c876b Allow read-only mounts of dataless snapshots
A user has encountered a volume with the dataless snapshots flag:

  https://github.com/linux-apfs/linux-apfs-rw/issues/86

I'm not really sure what "dataless snapshots" are, and so far I have
failed to trigger them under macos. I can set the
SNAP_META_PENDING_DATALESS flag in a snapshot myself, and macos will
call it "dataless", but their fsck doesn't complain no matter what I do
with the other fields, so I can't tell what is expected.

I can't imagine any risk in mounting such a volume read-only, so allow
that much from now on. Keep writes banned just in case, and avoid
mounting the dataless snapshots themselves, since I have no idea what
that entails.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-12-03 20:33:18 -03:00
Ernesto A. Fernández 6e7371ae02 Sync apfs_raw.h with the fsck again
I've recently noticed a number of new flags and added them to the fsck.
I heven't quite figured out most of them yet, but copy the information
here anyway. Also add checks for the new incompatible features, so that
they don't get accepted by default.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-05-03 20:54:26 -03:00
Ernesto A. Fernández 2a10ca61e6 Update the volume superblock with latest fields
If the latest newfs_apfs creates an image with the default options,
older versions of fsck_apfs complain about an unknown volume superblock
field called "apfs_doc_id_index_flags". Several such new fields appear
to have been added, and after some bit flipping I managed to retrieve
the names for all of them, except for "apfs_doc_id_tree_oid" which is
only a (probably correct) guess.

I have no plans for these fields right now, but document them all in
apfs_raw.h anyway, so that I don't forget.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-04-23 19:51:27 -03:00
Ernesto A. Fernández 1d9630b194 Get rid of zero-length arrays
According to checkpatch.pl, the use of zero-length arrays is now
deprecated in the kernel. Replace them all with C99 flexible array
members.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-10-26 21:56:56 -03:00
Ernesto A. Fernández 2d6cdba8f6 Fix trivial style issues
Some code that wasn't originally written by me has a style that differs
slightly from the rest of the module. Since I've been refactoring
compress.c quite a lot lately, I have made the inconsistencies more
visible, so I think it's a good time to switch everything to the typical
kernel style.

For this purpose I'm running checkpatch.pl for the first time in years,
and it has detected a handful of other issues that I introduced myself.
Fix most of the issues now, but I prefer to leave the zero-length array
stuff for a separate patch.

For the record, at the moment I'm choosing to ignore style inconsistency
in the compression libraries, even in libzbitmap which I wrote myself. I
prefer to keep them as close to upstream as possible.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-10-26 21:44:30 -03:00
Ernesto A. Fernández 2e63fbc8dd Add APFS prefix to all object type macros
Some recently defined object types are missing the "APFS_" prefix. I've
fixed this a while back in the fsck, do it in the driver too.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-02-21 22:54:39 -03:00
Ernesto A. Fernández bbc07ce208 Support attr compression for LZBITMAP
Support for LZBITMAP was previously limited to resource compression,
simply because I had never encountered any attr-compressed files that I
could use for testing. Using the same tool from the previous patch[0]
and one of our iphone vms, I now managed to create one. Add support.

[0]: https://github.com/Siguza/fscmp

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-26 17:22:46 -03:00
Ernesto A. Fernández dc829884cb Support reads of LZFSE-compressed files
Using the official LZFSE library (which I already dumped here in the
previous patch), add support for LZFSE compression. For testing I used
images created with the following tool:

  https://github.com/Siguza/fscmp

I've tested both resource and attribute compression. For resource
compression, I also tested a file that had a single uncompressed block.
That block had 0xff in the first byte, but I don't know if that's a
general rule so it's better to just check for the first byte of the
LZFSE magic.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-25 21:16:54 -03:00
Ernesto A. Fernández 588475e5f7 Support reads of LZVN-compressed files
Use Apple's official LZFSE library[0] to add support for LZVN
compression. Their code for LZFSE compression proper is also dumped with
this patch, but it's not actually rigged up for the driver because I
have no image to test it on.

For the record, the build on Linux 5.15 produces the following objtool
warning:

  lzfse/lzvn_decode_base.o: warning: objtool: lzvn_decode()+0x1b0: sibling call from callable instruction with modified stack frame

I'm not sure what this means, but there seems to be no sibling call in
that position, just a regular goto:

   1b0:   e9 00 00 00 00          jmp    1b5 <lzvn_decode+0x1b5>

I'll ignore it for now, but I guess I should report it if it's a false
positive.

[0]: https://github.com/lzfse/lzfse

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-24 18:50:21 -03:00
Ernesto A. Fernández 66526b4674 Support reads of LZBITMAP-compressed files
Use my recent LZBITMAP library to implement reads of these compressed
files.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-18 19:38:33 -03:00
Ernesto A. Fernández 11b3392aab Add support for "plain" compression
There is a weird compression mode that is not actually compressed at
all, add support for it. This patch is just a copy of Stan's code for
our internal tool.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-18 19:34:25 -03:00
Ernesto A. Fernández 14a15bd372 Add support for sealed volume reads
Add suport for reads from sealed volumes. The main differences are that
catalog index nodes are bigger, and that file extents are kept in a
separate tree.

Writes could in theory be supported as well, as we do in our internal
tool. It would probably be a bit too hacky though, so I'll wait to see
if anybody asks for it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-13 23:12:19 -03:00
Ernesto A. Fernández 97863ab914 Add support for taking snapshots
Implement an ioctl that creates a snapshot for the current transaction.
A matching userland tool has already been added to apfsprogs.

Note that, at this point, snapshots won't be handled correctly on later
writes at all. Being able to actually create snapshots for testing is
only the first step in that direction.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-06 19:38:54 -03:00
Ernesto A. Fernández 4c64a6e74d Update the disk layout
Recent work on the fsck has involved a lot of changes to the disk layout
header over there. Bring as many of those changes as possible back to
the kernel, where they will soon be needed, at least for implementing
snapshots.

Also clean up the kernel header by getting rid of duplicated definitions
for the superblock magic, and by using UUID_SIZE everywhere instead of
16. It might have been cleaner to do this stuff in separate commits, but
I would probably have forgottent about it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-01-06 19:36:57 -03:00
Ernesto A. Fernández dc1ed2cfe7 Rename SPDX license identifier
It seems that the license identifier currently in use (GPL-2.0) has been
deprecated:

  https://spdx.org/licenses/GPL-2.0.html

I don't know how important this is in practice, but I've received some
complaints about it:

  https://github.com/linux-apfs/linux-apfs-rw/issues/18

So, just run

  sed -i 's/2\.0/2.0-only/' *.{c,h}
  sed -i 's/2\.0/2.0-only/' Makefile

and change it to GPL-2.0-only.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-11-16 18:41:54 -03:00
Ernesto A. Fernández f62948f5a9 Implement FS_IOC_SETFLAGS/FS_IOC_GETFLAGS ioctls
The BSD flags used by APFS are not an exact match for the inode flags
used in Linux, but they are close enough that I can at least support
three of them. I don't know if this is important, but the HFS+ module
does it, so follow its lead.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-08-27 20:34:31 -03:00
Ernesto A. Fernández f14d0c4b02 Put a limit on file sizes
I currently get filesystem corruption after running generic/466 from
xfstests. This is a test of writes to huge filesystem offsets, and the
corruption happens because extent lengths wrap around at 2^56 bytes.

According to the documentation, it appears that the intended file size
limit is 2^63, so the proper way to fix this would involve creating a
large number of maximum-length hole extents. I haven't confirmed this
with the official implementation, but either way it seems like a waste
of effort for current disk sizes. Just ban the creation of files that
wouldn't fit in a single extent.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-08-25 19:19:32 -03:00
Ernesto A. Fernández 3d45d06688 Continue fixing build problems on older kernels
Luflosi has reported some new build failures:

  https://github.com/linux-apfs/linux-apfs-rw/issues/12#issuecomment-890317156

One problem is that the UUID_SIZE macro was not defined until 4.13, so
provide a definition of our own for older kernels. Also, while not
strictly necessary, include the uuid header explicitly (right now it
only works because <linux/fs.h> is included in apfs.h before
"apfs_raw.h").

The other problem is that lockdep_assert_held_write() had a different
name before 5.3, and may not even exist in some older kernels. This
macro is just for debugging, so define it as a no-op when not available.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-07-31 18:33:03 -03:00
Stan Skowronek 7b3ef1e683 Add support for per-file keys
[ernesto: fixed sparse warnings, added commit title]

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-04-20 15:35:52 -03:00
Stan Skowronek 16c9c4f9b1 Support read of zlib-compressed files
[ernesto: silenced sparse, used bool type, added commit title]

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-04-07 17:45:52 -03:00
Ernesto A. Fernández 4a6c0e2b77 Support simultaneous mount of multiple volumes
Separate the in-memory volume and container superblocks, and keep all
mounted containers in a linked list. Each container will hold a pointer
to its block device; when a mount is requested, we traverse the list to
check if it's a new container. Keep one vfs superblock for each mounted
volume, but only assign it a fake anonymous bdev; all disk operations
must be forwarded to the container's bdev, with the use of the new
apfs_sb_bread() and apfs_map_bh() functions.

All the mount changes require that we implement our own ->mount()
function, closely based on bdev_mount() and the btrfs equivalent. I
can't claim to be confident that all changes here are correct, much more
testing is needed.

To simplify access to the container, define two new helpers similar to
APFS_SB(): APFS_NXI() to retrieve the container superblock info, and
APFS_SM() to retrieve the space manager. Also move the usual assertion
that an object is part of the current transaction to its own inline
function; this saves me from rewriting all the callers and has the added
benefit of silencing "unused variable" warnings when the module is built
without APFS_DEBUG.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-04-06 23:08:56 -03:00
Ernesto A. Fernández 45f56acb46 Set up a standalone repository for the APFS module
Start a new out-of-tree repository, like linux-apfs-oot but with write
support.

To get the module to build independently, rewrite the Makefile and
add a definition for the APFS_SUPER_MAGIC macro.  Since the intention is
to support a range of kernel versions, use preprocessor checks to handle
kernels without statx, without iversion, and without SB_RDONLY.

Provide a README file based on the original documentation, but with
additional build and mount instructions.  Add a LICENSE file as well.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-03-31 17:16:24 -03:00