Closed A2uria closed 1 year ago
保持hash一样有什么好处吗? 如果做其他修改比如复制文件进去就不行了
保持hash一样有什么好处吗?
方便复现。
如果做其他修改比如复制文件进去就不行了
确实,但是在控制文件写入顺序及内容不变和不改变时间戳的条件下能实现可复现的构建。
稍微看了一下,build.sh#L739 这里不需要重新 touch 时间戳,构建过程本身存在不可复现的步骤,而且 find -exec touch ...
并不能保证所有节点的时间戳都为 200901010000。
p.s. /dev/XXXXXXXX?
貌似是新加入的文件的时间才需要改 而且其实不改也没问题,没有影响
Best regards
, Howard
From: A2uria @.> Sent: Friday, January 13, 2023 10:09:19 PM To: LSPosed/MagiskOnWSALocal @.> Cc: Howard Wu @.>; Comment @.> Subject: Re: [LSPosed/MagiskOnWSALocal] [Feature Request] Reproducibly produce modified images. (e.g. system_ext.img) (Issue #348)
保持hash一样有什么好处吗?
方便复现。
如果做其他修改比如复制文件进去就不行了
确实,但是在控制文件写入顺序及内容不变和不改变时间戳的条件下能实现可复现的构建。
稍微看了一下,build.sh#L739https://github.com/LSPosed/MagiskOnWSALocal/blob/a5f46350b8ea12c1e25ab84f6f0bfe9fe217ff1e/scripts/build.sh#L739 这里不需要重新 touch 时间戳,构建过程本身存在不可复现的步骤,而且 find -exec touch ... 并不能保证所有节点的时间戳都为 200901010000。
p.s. /dev/XXXXXXXX?
― Reply to this email directly, view it on GitHubhttps://github.com/LSPosed/MagiskOnWSALocal/issues/348#issuecomment-1381912153, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJRNWKYKMDJ6ZCEEAIGHHRTWSFOY7ANCNFSM6AAAAAATZKLNMQ. You are receiving this because you commented.Message ID: @.***>
分区会记录上一次mount的时间,设置fake time没有用
Best regards
, Howard
From: Wu Howard @.> Sent: Friday, January 13, 2023 10:12:27 PM To: LSPosed/MagiskOnWSALocal @.>; LSPosed/MagiskOnWSALocal @.> Cc: Comment @.> Subject: Re: [LSPosed/MagiskOnWSALocal] [Feature Request] Reproducibly produce modified images. (e.g. system_ext.img) (Issue #348)
貌似是新加入的文件的时间才需要改 而且其实不改也没问题,没有影响
Best regards
, Howard
From: A2uria @.> Sent: Friday, January 13, 2023 10:09:19 PM To: LSPosed/MagiskOnWSALocal @.> Cc: Howard Wu @.>; Comment @.> Subject: Re: [LSPosed/MagiskOnWSALocal] [Feature Request] Reproducibly produce modified images. (e.g. system_ext.img) (Issue #348)
保持hash一样有什么好处吗?
方便复现。
如果做其他修改比如复制文件进去就不行了
确实,但是在控制文件写入顺序及内容不变和不改变时间戳的条件下能实现可复现的构建。
稍微看了一下,build.sh#L739https://github.com/LSPosed/MagiskOnWSALocal/blob/a5f46350b8ea12c1e25ab84f6f0bfe9fe217ff1e/scripts/build.sh#L739 这里不需要重新 touch 时间戳,构建过程本身存在不可复现的步骤,而且 find -exec touch ... 并不能保证所有节点的时间戳都为 200901010000。
p.s. /dev/XXXXXXXX?
― Reply to this email directly, view it on GitHubhttps://github.com/LSPosed/MagiskOnWSALocal/issues/348#issuecomment-1381912153, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJRNWKYKMDJ6ZCEEAIGHHRTWSFOY7ANCNFSM6AAAAAATZKLNMQ. You are receiving this because you commented.Message ID: @.***>
fake time 只适用于使用 libext2fs 的程序,文件系统挂载用的是内核的 ext2 实现当然没用,所以大概要自己造车轮了。
用 mount 的话底层 vfs 会更新 super->s_mtime 为 time(0) 即设置上次挂载的时间。
fuse2fs 里是这样实现的。
fs->super->s_mtime = time(NULL);
linux kernel 里的实现估计也差不多。
所以大概要基于 libext2fs 对 .img 进行写操作才能实现 .img 的 repro。
p.s. 理论上 smtime 和 i{a,c,m}time 需要设置为 fs->now 而非 time(0) 才能使时间戳一致,但是 vfs 中的 mkdir 等操作都不考虑 fs->now。
p.p.s. 这里随机设备名不可复现。
拿 fuse2fs
改了改实现了可复现的写操作。
这是用 fuse2fs
挂载后不做任何改动直接 umount
的结果,仅 fs->super->s_kbytes_written
有改动。
$ radiff2 -x a.img b.img
offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00000000 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
0x00000010 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
...
0x00000570! 000000000000000085b9020000000000 ................ 00000000000000008db9020000000000 ................
0x00000580 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
0x00000590 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
...
不做冗余操作的情况下 fs->super->s_kbytes_written
对最终文件系统的 hash 没有影响。
放一个 e2fsprogs
的 patch 在这里。
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -435,26 +435,15 @@
static void get_now(struct timespec *now)
{
-#ifdef CLOCK_REALTIME
- if (!clock_gettime(CLOCK_REALTIME, now))
- return;
-#endif
-
- now->tv_sec = time(NULL);
+ now->tv_sec = 1230768000;
now->tv_nsec = 0;
}
static void increment_version(struct ext2_inode_large *inode)
{
- __u64 ver;
-
- ver = inode->osd1.linux1.l_i_version;
+ inode->osd1.linux1.l_i_version = 0;
if (EXT4_FITS_IN_INODE(inode, i_version_hi))
- ver |= (__u64)inode->i_version_hi << 32;
- ver++;
- inode->osd1.linux1.l_i_version = ver;
- if (EXT4_FITS_IN_INODE(inode, i_version_hi))
- inode->i_version_hi = ver >> 32;
+ inode->i_version_hi = 0;
}
static void init_times(struct ext2_inode_large *inode)
@@ -744,8 +733,6 @@
conn->want |= FUSE_CAP_IOCTL_DIR;
#endif
if (fs->flags & EXT2_FLAG_RW) {
- fs->super->s_mnt_count++;
- fs->super->s_mtime = time(NULL);
fs->super->s_state &= ~EXT2_VALID_FS;
ext2fs_mark_super_dirty(fs);
err = ext2fs_flush2(fs, 0);
@@ -1009,7 +996,7 @@
goto out2;
}
- inode.i_generation = ff->next_generation++;
+ inode.i_generation = 0;
init_times(&inode);
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -1130,7 +1117,7 @@
ext2fs_set_i_gid_high(inode, ctxt->gid >> 16);
inode.i_mode = LINUX_S_IFDIR | (mode & ~(S_ISUID | fs->umask)) |
parent_sgid;
- inode.i_generation = ff->next_generation++;
+ inode.i_generation = 0;
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -1503,7 +1490,7 @@
ext2fs_set_i_uid_high(inode, ctxt->uid >> 16);
inode.i_gid = ctxt->gid;
ext2fs_set_i_gid_high(inode, ctxt->gid >> 16);
- inode.i_generation = ff->next_generation++;
+ inode.i_generation = 0;
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -2928,7 +2915,7 @@
goto out2;
}
- inode.i_generation = ff->next_generation++;
+ inode.i_generation = 0;
init_times(&inode);
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
好麻烦,要改的地方很多 这个改动对这个项目没有很明显的改进 如果可以的话你PR
Best regards
, Howard
From: A2uria @.> Sent: Tuesday, January 17, 2023 11:17:26 AM To: LSPosed/MagiskOnWSALocal @.> Cc: Howard Wu @.>; Comment @.> Subject: Re: [LSPosed/MagiskOnWSALocal] [Feature Request] Reproducibly produce modified images. (e.g. system_ext.img) (Issue #348)
拿 fuse2fs 改了改实现了可复现的写操作。
这是用 fuse2fs 挂载后不做任何改动直接 umount 的结果,仅 fs->super->s_kbytes_written 有改动。
$ radiff2 -x a.img b.img
offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00000000 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
0x00000010 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
...
0x00000570! 000000000000000085b9020000000000 ................ 00000000000000008db9020000000000 ................
0x00000580 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
0x00000590 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
...
不做冗余操作的情况下 fs->super->s_kbytes_written 对最终文件系统的 hash 没有影响。
放一个 e2fsprogs 的 patch 在这里。
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -435,26 +435,15 @@
static void get_now(struct timespec *now)
{
-#ifdef CLOCK_REALTIME
if (!clock_gettime(CLOCK_REALTIME, now))
return;
-#endif
-
now->tv_sec = time(NULL);
now->tv_sec = 1230768000;
now->tv_nsec = 0;
}
static void increment_version(struct ext2_inode_large *inode)
{
__u64 ver;
ver = inode->osd1.linux1.l_i_version;
inode->osd1.linux1.l_i_version = 0;
if (EXT4_FITS_IN_INODE(inode, i_version_hi))
ver |= (__u64)inode->i_version_hi << 32;
ver++;
inode->osd1.linux1.l_i_version = ver;
if (EXT4_FITS_IN_INODE(inode, i_version_hi))
inode->i_version_hi = ver >> 32;
inode->i_version_hi = 0;
}
static void init_times(struct ext2_inode_large *inode)
@@ -744,8 +733,6 @@
conn->want |= FUSE_CAP_IOCTL_DIR;
if (fs->flags & EXT2_FLAG_RW) {
fs->super->s_mnt_count++;
fs->super->s_mtime = time(NULL);
fs->super->s_state &= ~EXT2_VALID_FS;
ext2fs_mark_super_dirty(fs);
err = ext2fs_flush2(fs, 0);
@@ -1009,7 +996,7 @@
goto out2;
}
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
init_times(&inode);
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -1130,7 +1117,7 @@
ext2fs_set_i_gid_high(inode, ctxt->gid >> 16);
inode.i_mode = LINUX_S_IFDIR | (mode & ~(S_ISUID | fs->umask)) |
parent_sgid;
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -1503,7 +1490,7 @@
ext2fs_set_i_uid_high(inode, ctxt->uid >> 16);
inode.i_gid = ctxt->gid;
ext2fs_set_i_gid_high(inode, ctxt->gid >> 16);
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -2928,7 +2915,7 @@
goto out2;
}
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
init_times(&inode);
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
― Reply to this email directly, view it on GitHubhttps://github.com/LSPosed/MagiskOnWSALocal/issues/348#issuecomment-1384783007, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJRNWKY5NOHDRSO34Z7JQW3WSYFMNANCNFSM6AAAAAATZKLNMQ. You are receiving this because you commented.Message ID: @.***>
把这个项目换成C++的或许就比较好改
Best regards
, Howard
From: Wu Howard @.> Sent: Tuesday, January 17, 2023 11:19:52 AM To: LSPosed/MagiskOnWSALocal @.>; LSPosed/MagiskOnWSALocal @.> Cc: Comment @.> Subject: Re: [LSPosed/MagiskOnWSALocal] [Feature Request] Reproducibly produce modified images. (e.g. system_ext.img) (Issue #348)
好麻烦,要改的地方很多 这个改动对这个项目没有很明显的改进 如果可以的话你PR
Best regards
, Howard
From: A2uria @.> Sent: Tuesday, January 17, 2023 11:17:26 AM To: LSPosed/MagiskOnWSALocal @.> Cc: Howard Wu @.>; Comment @.> Subject: Re: [LSPosed/MagiskOnWSALocal] [Feature Request] Reproducibly produce modified images. (e.g. system_ext.img) (Issue #348)
拿 fuse2fs 改了改实现了可复现的写操作。
这是用 fuse2fs 挂载后不做任何改动直接 umount 的结果,仅 fs->super->s_kbytes_written 有改动。
$ radiff2 -x a.img b.img
offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00000000 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
0x00000010 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
...
0x00000570! 000000000000000085b9020000000000 ................ 00000000000000008db9020000000000 ................
0x00000580 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
0x00000590 00000000000000000000000000000000 ................ 00000000000000000000000000000000 ................
...
不做冗余操作的情况下 fs->super->s_kbytes_written 对最终文件系统的 hash 没有影响。
放一个 e2fsprogs 的 patch 在这里。
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -435,26 +435,15 @@
static void get_now(struct timespec *now)
{
-#ifdef CLOCK_REALTIME
if (!clock_gettime(CLOCK_REALTIME, now))
return;
-#endif
-
now->tv_sec = time(NULL);
now->tv_sec = 1230768000;
now->tv_nsec = 0;
}
static void increment_version(struct ext2_inode_large *inode)
{
__u64 ver;
ver = inode->osd1.linux1.l_i_version;
inode->osd1.linux1.l_i_version = 0;
if (EXT4_FITS_IN_INODE(inode, i_version_hi))
ver |= (__u64)inode->i_version_hi << 32;
ver++;
inode->osd1.linux1.l_i_version = ver;
if (EXT4_FITS_IN_INODE(inode, i_version_hi))
inode->i_version_hi = ver >> 32;
inode->i_version_hi = 0;
}
static void init_times(struct ext2_inode_large *inode)
@@ -744,8 +733,6 @@
conn->want |= FUSE_CAP_IOCTL_DIR;
if (fs->flags & EXT2_FLAG_RW) {
fs->super->s_mnt_count++;
fs->super->s_mtime = time(NULL);
fs->super->s_state &= ~EXT2_VALID_FS;
ext2fs_mark_super_dirty(fs);
err = ext2fs_flush2(fs, 0);
@@ -1009,7 +996,7 @@
goto out2;
}
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
init_times(&inode);
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -1130,7 +1117,7 @@
ext2fs_set_i_gid_high(inode, ctxt->gid >> 16);
inode.i_mode = LINUX_S_IFDIR | (mode & ~(S_ISUID | fs->umask)) |
parent_sgid;
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -1503,7 +1490,7 @@
ext2fs_set_i_uid_high(inode, ctxt->uid >> 16);
inode.i_gid = ctxt->gid;
ext2fs_set_i_gid_high(inode, ctxt->gid >> 16);
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
@@ -2928,7 +2915,7 @@
goto out2;
}
inode.i_generation = ff->next_generation++;
inode.i_generation = 0;
init_times(&inode);
err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
sizeof(inode));
― Reply to this email directly, view it on GitHubhttps://github.com/LSPosed/MagiskOnWSALocal/issues/348#issuecomment-1384783007, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJRNWKY5NOHDRSO34Z7JQW3WSYFMNANCNFSM6AAAAAATZKLNMQ. You are receiving this because you commented.Message ID: @.***>
编译还需要引入 build-essenial
和 libfuse-dev
等包,确实有点麻烦,要是有预编译 bin 的话会简单点。
有可能会自己写一遍,不过毕竟对 magisk 接触的比较少,估计还得看一看 magisk 的实现。
magisk/native/src/init/rootdir.cpp
关于 init.rc
的处理还得研究一下。
Is your feature request related to a problem?/你的请求是否与某个问题相关?
No.
Describe the solution you'd like/描述你想要的解决方案
Reproducibly produce patched raw ext2 images. (
product.img
,system_ext.img
, etc.)Additional context/其他信息
e2fsprogs provided environment variable E2FSPROGS_FAKE_TIME to produce reproducible ext2 images. Also, with environment variable E2FSCK_TIME, we can shrink the size of ext2 images while keep reproducibility.
Here is an example. I use debugfs to delete (inodes of) preinstalled amazon and shrink the fs. The hash of modified modified system_ext.img is always
6cfa7fb0805c69d6af2949eab4356ac9c06e8c36c0304e344a2ce420580ba85a
. (originalebcc4c707ba97ea8855064231bbe045bcc6023a3f18aa9c024f6c334d0635ab2
, fromMicrosoftCorporationII.WindowsSubsystemForAndroid_2211.40000.11.0_neutral_~_8wekyb3d8bbwe.msixbundle
)Note that the major version should be greater than 2211, otherwise replace
system_ext.img
withproduct.img
Note that time_t 1230768000 is equivalent to timestamp 200901010000 (UTC).
Here's
system_ext.txt
.As far as I know, in MagiskOnWSALocal/scripts/build.sh#L739, you use
find . -exec touch -hamt <timestamp> {} ';'
to set every timestamp to 200901010000, but there are{a,c,m}time
for each file, so just use-ht <timestamp>
instead of-hamt <timestamp>
.Another important thing is that the timestamp is localized, so in China, timestamp
200901010000
would be shown as200901010800
, but when setting it to200901010000
, it would be shown as200901010000
, not200901010800
.p.s. We may need
e2fsprogs>=1.46.6-rc1
to do so. However,e2fsprogs=1.46.5
works fine for the example.p.p.s. 用中文也行但是 repro 不好形容。