挂载放置在静态变量中的文件系统映像

问题描述

可以循环挂载包含文件系统映像的二进制文件。我想将该二进制文件放入一个 C 静态变量中,然后挂载它。这可能吗?如果是这样,我需要什么 C API 魔法?

解决方法

我们需要采取几个步骤

  1. 创建文件系统映像
  2. 将此图像嵌入到二进制文件中
  3. 将嵌入的图像安装为只读文件系统。

听起来您已经知道如何演奏词干 1 和 2,但不知道如何演奏第 3 步。

我准备了 ab.sqfs 图像和 a.out,其中包含偏移 0x3010 处的图像。以下是挂载此文件系统的命令:

# optional,look at the bytes of the filesystem from step 1 
xxd -l 16 -g1 ab.sqfs
00000000: 68 73 71 73 07 00 00 00 6c 61 ce 60 00 00 02 00  hsqs....la.`....

# optional: confirm that we have the correct file offset to the start of FS image
xxd -l 16 -g1 -s 0x3010 a.out
00003010: 68 73 71 73 07 00 00 00 6c 61 ce 60 00 00 02 00  hsqs....la.`....

# create a loop device which "points" into the file:
sudo losetup -r -o 0x3010 loop0 a.out 
losetup: a.out: Warning: file does not fit into a 512-byte sector; the end of the file will be ignored.

# optional: confirm that (just created) /dev/loop0 contains expected bytes
sudo xxd -l 16 -g1 /dev/loop0
00000000: 68 73 71 73 07 00 00 00 6c 61 ce 60 00 00 02 00  hsqs....la.`....

# create directory on which the FS will be mounted
mkdir /tmp/mnt         

# finally mount the FS:
sudo mount -oro /dev/loop0 /tmp/mnt

# optional: verify contents of /tmp/mnt
ls -lR /tmp/mnt
... has exactly the files I've put into it.

我需要什么 C API 魔法?

您可以在 losetup 下运行 mountstrace 命令来观察它们的作用。 losetup 的关键步骤是:

openat(AT_FDCWD,"/tmp/a.out",O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD,"/dev/loop0",O_RDONLY|O_CLOEXEC) = 4
ioctl(4,LOOP_SET_FD,3)                = 0
ioctl(4,LOOP_SET_STATUS64,{lo_offset=0x3010,lo_number=0,lo_flags=LO_FLAGS_READ_ONLY,lo_file_name="/tmp/a.out",...}) = 0

对于mount

mount("/dev/loop0","/tmp/mnt","squashfs",MS_RDONLY,NULL) = 0

这些调用可以由应用程序本身执行,也可以通过“外壳”到外部 losetupmount 命令来执行。