Nexus 7 (2013) postmarketOS Install
The Nexus 7 (2012) was the first tablet I liked a tablet. The small size meant it was similar to a small book and easy to carry (and can fits in men’s jeans front and back pockets). The follow-up Nexus 7 (2013; a.k.a. 2nd gen) was the same but much better hardware (better screen, flash, RAM).
To this day I still use the device for e-book reading, but the OS is woefully out-of-date. I’ve been wanting to play with postmarketOS. The 2012 tablet is in pmOS’s community category (pmOS device asus-grouper) so it’d be the better candidate, but the one I quickly found wouldn’t turn on after charging. The screen just flashed garbage for a split-second. (Of course, trying now has it booting…) So I tried my hand with the 2013 tablet which is in pmOS’s testing category (pmOS device asus-flo). The pmOS chipset Qualcomm APQ8064 page also had some info.
I first installed TWRP using the “Fastboot install method” to backup the system. This worked well, as did using USB-OTG with a USB thumb drive for storing the backup itself.
For pmOS itself, I followed the Using pmbootstrap install method. That shouldn’t have been too bad, mostly:
# pacman -S pmbootstrap
$ pmbootstrap init # answer lots of questions
$ pmbootstrap install
$ pmbootstrap flasher flash_rootfs # to userdata; system is too small
$ pmbootstrap flasher flash_kernel
However, flash_rootfs
failed:
$ pmbootstrap flasher flash_rootfs
[14:42:27] (native) flash rootfs image
[14:42:28] (native) install android-tools
Sending 'userdata' (2060288 KB) FAILED (remote: 'data too large')
fastboot: error: Command failed
Using pmbootstrap export
I was able to try running fastboot myself, but it
failed in the same way. And the device didn’t understand sparse files (-S 512M
).
$ fastboot flash userdata /tmp/postmarketOS-export/asus-flo.img
Sending 'userdata' (2060288 KB) FAILED (remote: 'data too large')
fastboot: error: Command failed
$ fastboot flash userdata -S 512M /tmp/postmarketOS-export/asus-flo.img
Sending sparse 'userdata' 1/3 (523464 KB) OKAY [ 16.669s]
Writing 'userdata' FAILED (remote: 'Unknown chunk type')
fastboot: error: Command failed
The “userdata” partition is 13 GB, so it should have plenty of space. The “system” partition is indeed too small at 880 MB.
$ fastboot getvar all
(bootloader) version-bootloader: FLO-04.08
(bootloader) version-baseband: none
(bootloader) version-hardware: rev_e
(bootloader) version-cdma: N/A
(bootloader) variant: flo 16G
(bootloader) serialno: 07d38b3e
(bootloader) product: flo
(bootloader) secure_boot: enabled
(bootloader) lock_state: unlocked
(bootloader) project: flo
(bootloader) off-mode-charge: yes
(bootloader) uart-on: no
(bootloader) partition-type:bootloader: emmc
(bootloader) partition-size:bootloader: 0x0000000000aee000
(bootloader) partition-type:recovery: emmc
(bootloader) partition-size:recovery: 0x0000000000a00000
(bootloader) partition-type:boot: emmc
(bootloader) partition-size:boot: 0x0000000001000000
(bootloader) partition-type:system: ext4
(bootloader) partition-size:system: 0x0000000034800000
(bootloader) partition-type:cache: ext4
(bootloader) partition-size:cache: 0x0000000023000000
(bootloader) partition-type:userdata: ext4
(bootloader) partition-size:userdata: 0x000000031b3fbe00
all:
Finished. Total time: 0.025s
The problem seems to be the entire file is buffered in RAM before anything is
written, so anything near or larger than 2 GiB is out of the question. I tried
Installation from recovery
mode and
it failed on the device as well. I was able to use the pmOS console
UI, as it
was smaller. I also was able to write the larger image by copying it to a USB
flash stick, plugging that in with USB-OTG, going into TWRP’s shell and running
dd
. But as I was playing with the pmOS UI options and kernels, I wasn’t
willing to do that more than once.
I figured out the ideal workaround: Boot into recovery mode (TWRP) and use adb push
to write directly to the userdata partition.
$ adb push /tmp/postmarketOS-export/asus-flo.img /dev/block/mmcblk0p30
To see the partition ids, I looked at the by-name mapping in /dev:
$ adb shell
# ls -l /dev/block/platform/msm_sdcc.1/by-name/userdata
lrwxrwxrwx 1 root root 21 Oct 5 21:43 /dev/block/platform/msm_sdcc.1/by-name/userdata -> /dev/block/mmcblk0p30
However, I found fdisk was also available in TWRP, so that’s probably the easier option:
# fdisk -l /dev/block/mmcblk0
Found valid GPT with protective MBR; using GPT
Disk /dev/block/mmcblk0: 30777344 sectors, 2740M
Logical sector size: 512
Disk identifier (GUID): ...
Partition table holds up to 32 entries
First usable sector is 34, last usable sector is 30777310
Number Start (sector) End (sector) Size Code Name
1 131072 306143 85.4M 0700 radio
2 393216 399359 3072K 0700 modemst1
3 399360 405503 3072K 0700 modemst2
4 524288 554287 14.6M 0700 persist
5 655360 656919 780K 0700 m9kefs1
6 656920 658479 780K 0700 m9kefs2
7 786432 787991 780K 0700 m9kefs3
8 787992 794135 3072K 0700 fsg
9 917504 920503 1500K 0700 sbl1
10 920504 923503 1500K 0700 sbl2
11 923504 927599 2048K 0700 sbl3
12 927600 937839 5120K 0700 aboot
13 937840 938863 512K 0700 rpm
14 1048576 1081343 16.0M 0700 boot
15 1179648 1180671 512K 0700 tz
16 1180672 1180673 1024 0700 pad
17 1180674 1183673 1500K 0700 sbl2b
18 1183674 1187769 2048K 0700 sbl3b
19 1187770 1198009 5120K 0700 abootb
20 1198010 1199033 512K 0700 rpmb
21 1199034 1200057 512K 0700 tzb
22 1310720 3031039 840M 0700 system
23 3031040 4177919 560M 0700 cache
24 4194304 4196351 1024K 0700 misc
25 4325376 4345855 10.0M 0700 recovery
26 4456448 4456463 8192 0700 DDR
27 4456464 4456479 8192 0700 ssd
28 4456480 4456481 1024 0700 m9kefsc
29 4587520 4587583 32768 0700 metadata
30 4718592 30777310 12.4G 0700 userdata
I ended up avoiding Full Disk Encryption (FDE) because unl0kr made the boot
image too large. It sounds like this could be fixed by using
deviceinfo_create_initfs_extra
,
but I didn’t test it.
Using USB Internet worked great, but the device needed to be plugged into my host when it booted.
$ ssh 172.16.42.1 # connect to device
$ sudo ip route add default via 172.16.42.2 dev usb0
$ echo nameserver 1.1.1.1 > /etc/resolv.conf # only needed first boot
When the screen turned off after going idle, I couldn’t figure out how to turn it back on. So SSH was pretty useful.
You can apparently get UART access through the headphone jack, which looks relatively easy. The page it references for the Nexus 4 UART is available on archive.org. But I didn’t have trouble booting into the kernels, so SSH was sufficient.
The 4.11 kernel won’t work well with systemd, so while I did at one point try it, I was hoping the newer kernel would work better. Most of my testing was with 5.10.98-postmarketos-qcom-apq8064.
While the screen worked for the plain terminal, there was no DRM device for
Phosh. dmesg
showed it didn’t have the firmware:
[ 2.798974] [drm] Initialized msm 1.6.0 20130625 for 5100000.mdp on minor 0
[ 2.799480] msm 5100000.mdp: Direct firmware load for qcom/a300_pm4.fw failed with error -2
[ 2.804866] msm 5100000.mdp: Falling back to sysfs fallback for: qcom/a300_pm4.fw
[ 64.470868] msm 5100000.mdp: [drm:adreno_request_fw] *ERROR* failed to load a300_pm4.fw
I found the file in my backup at system.ext4/vendor/firmware/
, but I also
found it was already available on the root disk at
/usr/lib/firmware/postmarketos/
. lsmod
showed no modules, so I couldn’t
reload the module for it to re-probe for the firmware.
I was glad it is so easy to add files to the
initrd. I created
50-asus-flo.files (with sudo
), and then updated the boot partition with
fastboot.
$ cat ~/.local/var/pmbootstrap/chroot_rootfs_asus-flo/usr/share/mkinitfs/files/50-asus-flo.files
/usr/lib/firmware/postmarketos/a300_pm4.fw:/usr/lib/firmware/qcom/a300_pm4.fw
/usr/lib/firmware/postmarketos/a300_pfp.fw:/usr/lib/firmware/qcom/a300_pfp.fw
$ pmbootstrap initfs # Not necessary, as the next command does this
$ pmbootstrap flasher flash_kernel
Using mkinitfs
on the device wasn’t enough, because that just updated /boot
(which lives as a subpartition of “userdata”). I didn’t see instructions for
how to make the Android boot image to write to the “boot” partition. But
writing it using pmbootstrap from the host was easy.
That then allows DRM to load, but the card hangs on initialization:
Oct 05 15:55:48 asus-flo phoc[522]: [backend/drm/backend.c:225] Initializing DRM backend for /dev/dri/card0 (msm)
Oct 05 15:55:48 asus-flo phoc[522]: [backend/drm/drm.c:310] Found 2 DRM CRTCs
Oct 05 15:55:48 asus-flo phoc[522]: [backend/drm/drm.c:268] Found 4 DRM planes
Oct 05 15:55:48 asus-flo phoc[522]: [render/egl.c:205] Supported EGL client extensions: EGL_EXT_client_extensions EGL_EXT_device_base EGL_EXT_device_enumeration EGL_EXT_device_query EGL_EXT_platform_base EGL_KHR_client_get_all_proc_addresses EGL_KHR_debug EGL_EXT_platform_device EGL_EXT_explicit_device EGL_EXT_platform_wayland EGL_KHR_platform_wayland EGL_EXT_platform_x11 EGL_KHR_platform_x11 EGL_EXT_platform_xcb EGL_MESA_platform_gbm EGL_KHR_platform_gbm EGL_MESA_platform_surfaceless
Oct 05 15:55:49 asus-flo phoc[522]: [render/egl.c:369] Using EGL 1.5
Oct 05 15:55:49 asus-flo phoc[522]: [render/egl.c:370] Supported EGL display extensions: EGL_ANDROID_blob_cache EGL_ANDROID_native_fence_sync EGL_EXT_config_select_group EGL_EXT_create_context_robustness EGL_EXT_image_dma_buf_import EGL_EXT_image_dma_buf_import_modifiers EGL_EXT_query_reset_notification_strategy EGL_EXT_surface_compression EGL_IMG_context_priority EGL_KHR_cl_event2 EGL_KHR_config_attribs EGL_KHR_context_flush_control EGL_KHR_create_context EGL_KHR_create_context_no_error EGL_KHR_fence_sync EGL_KHR_get_all_proc_addresses EGL_KHR_gl_colorspace EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_3D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image_base EGL_KHR_no_config_context EGL_KHR_reusable_sync EGL_KHR_surfaceless_context EGL_EXT_pixel_format_float EGL_KHR_wait_sync EGL_MESA_configless_context EGL_MESA_gl_interop EGL_MESA_image_dma_buf_export EGL_MESA_query_driver EGL_MESA_x11_native_visual_id
Oct 05 15:55:49 asus-flo phoc[522]: [render/egl.c:372] Supported EGL device extensions: EGL_EXT_device_drm EGL_EXT_device_drm_render_node EGL_EXT_device_query_name EGL_EXT_device_persistent_id
Oct 05 15:55:49 asus-flo phoc[522]: [render/egl.c:374] EGL vendor: Mesa Project
Oct 05 15:55:49 asus-flo phoc[522]: [render/egl.c:376] EGL driver name: msm
Oct 05 15:55:49 asus-flo phoc[522]: [render/egl.c:447] Failed to obtain a high priority context
Oct 05 15:55:49 asus-flo phoc[522]: [render/gles2/renderer.c:538] Creating GLES2 renderer
Oct 05 15:55:49 asus-flo phoc[522]: [render/gles2/renderer.c:539] Using OpenGL ES 3.0 Mesa 25.2.4
Oct 05 15:55:49 asus-flo phoc[522]: [render/gles2/renderer.c:540] GL vendor: freedreno
Oct 05 15:55:49 asus-flo phoc[522]: [render/gles2/renderer.c:541] GL renderer: FD320
Oct 05 15:55:49 asus-flo phoc[522]: [render/gles2/renderer.c:542] Supported GLES2 extensions: GL_EXT_blend_minmax GL_EXT_multi_draw_arrays GL_EXT_texture_filter_anisotropic GL_EXT_texture_compression_s3tc GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_rgtc GL_EXT_texture_format_BGRA8888 GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth24 GL_OES_element_index_uint GL_OES_fbo_render_mipmap GL_OES_mapbuffer GL_OES_rgb8_rgba8 GL_OES_standard_derivatives GL_OES_stencil8 GL_OES_texture_3D GL_OES_texture_float GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_texture_npot GL_OES_vertex_half_float GL_EXT_draw_instanced GL_EXT_texture_sRGB_decode GL_OES_EGL_image GL_OES_depth_texture GL_OES_packed_depth_stencil GL_AMD_compressed_ATC_texture GL_EXT_texture_type_2_10_10_10_REV GL_NV_conditional_render GL_OES_get_program_binary GL_APPLE_texture_max_level GL_EXT_discard_framebuffer GL_EXT_read_format_bgra GL_EXT_texture_storage GL_NV_pack_subimage GL_NV_texture_barrier GL_EXT_frag_depth GL_NV_fbo_color_attachments GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_vertex_array_object GL_ANGLE_pack_reverse_row_order GL_ANGLE_texture_compression_dxt3 GL_ANGLE_texture_compression_dxt5 GL_EXT_occlusion_query_boolean GL_EXT_robustness GL_EXT_texture_rg GL_EXT_unpack_subimage GL_NV_draw_buffers GL_NV_read_buffer GL_NV_read_depth GL_NV_read_depth_stencil GL_NV_read_stencil GL_APPLE_sync GL_EXT_draw_buffers GL_EXT_instanced_arrays GL_EXT_map_buffer_range GL_EXT_shadow_samplers GL_KHR_debug GL_KHR_robustness GL_KHR_texture_compression_astc_ldr GL_NV_generate_mipmap_sRGB GL_NV_pixel_buffer_object GL_OES_depth_texture_cube_map GL_OES_required_internalformat GL_OES_surfaceless_context GL_EXT_color_buffer_float GL_EXT_debug_label GL_EXT_sRGB_write_control GL_EXT_separate_shader_objects GL_EXT_shader_integer_mix GL_EXT_compressed_ETC1_RGB8_sub_texture GL_EXT_draw_buffers_indexed GL_EXT_draw_elements_base_vertex GL_EXT_texture_border_clamp GL_KHR_context_flush_control GL_KHR_robust_buffer_access_behavior GL_NV_shader_noperspective_interpolation GL_OES_draw_buffers_indexed GL_OES_draw_elements_base_vertex GL_OES_texture_border_clamp GL_EXT_blend_func_extended GL_EXT_float_blend GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_RG8 GL_KHR_no_error GL_KHR_texture_compression_astc_sliced_3d GL_OES_EGL_image_external_essl3 GL_EXT_conservative_depth GL_EXT_texture_compression_s3tc_srgb GL_MESA_shader_integer_functions GL_EXT_clip_control GL_EXT_color_buffer_half_float GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_semaphore GL_EXT_semaphore_fd GL_EXT_texture_compression_bptc GL_EXT_texture_mirror_clamp_to_edge GL_KHR_parallel_shader_compile GL_EXT_EGL_image_storage GL_MESA_framebuffer_flip_y GL_EXT_depth_clamp GL_MESA_sampler_objects GL_EXT_EGL_image_storage_compression GL_EXT_texture_storage_compression GL_MESA_bgra GL_MESA_texture_const_bandwidth
Oct 05 15:55:50 asus-flo phoc[522]: Running compositor on wayland display 'wayland-0'
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:1741] Scanning DRM connectors on /dev/dri/card0
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:1796] Found connector 'DSI-1'
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:1821] 'DSI-1' connected
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:1610] Detected modes:
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:1634] 1200x1920 @ 60.000 Hz
Oct 05 15:55:50 asus-flo phoc[522]: MESA: warning: Failed to set BO metadata with DRM_MSM_GEM_INFO: -22
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:1671] Physical size: 95x151
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/util.c:65] Failed to parse EDID
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:1855] connector DSI-1: Requesting modeset
Oct 05 15:55:50 asus-flo phoc[522]: [backend/drm/drm.c:944] connector DSI-1: Modesetting with 1200x1920 @ 60.000 Hz
Oct 05 15:55:52 asus-flo phoc[522]: Output 'DSI-1' added ('(null)'/'(null)'/'(null)'), 95mm x 151mm
Oct 05 15:55:54 asus-flo phoc[522]: Enabling shell mode
Oct 05 15:55:56 asus-flo kernel: [drm:a3xx_hw_init] *ERROR* A320: timeout waiting for GPU to idle!
Oct 05 15:55:57 asus-flo kernel: msm 5100000.mdp: [drm:hangcheck_handler] *ERROR* A320: hangcheck detected gpu lockup rb 0!
Oct 05 15:55:57 asus-flo kernel: msm 5100000.mdp: [drm:hangcheck_handler] *ERROR* A320: completed fence: 2
Oct 05 15:55:57 asus-flo kernel: msm 5100000.mdp: [drm:hangcheck_handler] *ERROR* A320: submitted fence: 3
Oct 05 15:55:57 asus-flo kernel: msm 5100000.mdp: [drm:recover_worker] *ERROR* A320: hangcheck recover!
Oct 05 15:55:57 asus-flo kernel: msm 5100000.mdp: [drm:recover_worker] *ERROR* A320: offending task: phoc (/usr/bin/phoc -v -S -C /usr/share/phosh/phoc.ini -E bash -lc 'exec gnome-session --disable-acceleration-check --session=phosh')
Oct 05 15:55:57 asus-flo kernel: revision: 320 (3.2.0.2)
Oct 05 15:55:57 asus-flo kernel: rb 0: fence: 2/3
Oct 05 15:55:57 asus-flo kernel: rptr: 32
Oct 05 15:55:57 asus-flo kernel: rb wptr: 32
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG0: 0
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG1: 0
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG2: 2
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG3: 0
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG4: 0
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG5: 0
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG6: 0
Oct 05 15:55:57 asus-flo kernel: CP_SCRATCH_REG7: 0
Oct 05 15:55:57 asus-flo phoc[522]: [render/gles2/pass.c:306] GPU reset (guilty)
Oct 05 15:55:57 asus-flo phoc[522]: [render/gles2/pass.c:306] GPU reset (guilty)
Oct 05 15:55:57 asus-flo phoc[522]: [GLES2] GL_CONTEXT_LOST in context lost
... LOTS more GL_CONTEXT_LOST...
Apparently, this is a long-standing problem. And others also suffer from the display not turning back on, although I don’t see a kernel dump.
I feel like I now know how to find my way around postmarketOS and pmbootstrap. pmbootstrap is fast and relatively easy. I wish it didn’t remove my regular binfmt configuration, but I know why, so I can forgive it. There’s some other times it uses sudo which I wish it was able to avoid, like mkosi apparently can but most operations seem to run as my regular user, which is good. I keep getting the sense I’m aligned with their goals, like supporting lots of devices with UEFI and systemd-boot, the push to use unified /usr, getting systemd, and now this image building system. It isn’t Arch, but I’ve warmed up to this version of Alpine.
The most painful part of this was trying to write the 2 GB image to userdata, as it wasn’t clear what the problem was and the workarounds initially weren’t great. But apparently that is just an issue with this device.
Using GPT on eMMC with ODROID-C2
I wanted to use UEFI with ODROID-C2 and while that is possible with U-Boot on
MBR, bootctl install
doesn’t work and I lose out on
systemd-gpt-auto-generator
figuring out the partitions for the specific
install. Unfortunately, the bootloader on ODROID-C2 is written to sector
1 which conflicts with the GPT header.
Some other boards include SPI flash or the SoC supports eMMC boot0. But testing showed that boot0 didn’t work on the Amlogic S905/GXBB (and this is confirmed by U-Boot’s Amlogic docs). (It’s also not fun/interesting to mix two of eMMC, SD, or USB for booting.)
Introduction
A normal GPT disk has an MBR on sector 0, GPT header on sector 1, and the GPT table entries on sectors 2-33. The MBR and GPT header can’t be adjusted, but the GPT table entries can be moved or changed in size. The specification says “A minimum of 16,384 bytes of space must be reserved for the GPT Partition Entry Array,” which is why 32 sectors are used when the sector size is 512. In practice, smaller sizes work fine. Each entry is 128 bytes, so each sector can hold 4 entries.
For ODROID-C2, a bootloader header is actually written to both sector 0 and sector 1. This is because the Amlogic S905 boot ROM reads from sector 0 for eMMC and sector 1 for SD. eMMC had been a problem for other Amlogic S905 boards, but @chewitt mentions that apparently HardKernel got a different bootloader that only stores a small amount on sector 0 to leave space for the MBR. An old commit by @Kwiboo describes how a single disk image can boot both SD and eMMC. It also points out that the bootloader was previously open source. And it created the potentially-convenient aml_chksum (available now also in a LibreELEC repo).
The commit description is pretty helpful to understanding the Amlogic boot and our options, so let’s look at it:
Create u-boot.bin.hardkernel that can be booted from both SD and eMMC
SD: bl1 uses a 512 offset and expects header+checksum at 528-623 and bl2 at 4608+
eMMC: bl1 expects header+checksum at 16-111 and bl2 at 4096+
u-boot.bin.hardkernel layout:
16-111: eMMC header+checksum (start addr set to 1024)
528-623: SD header+checksum
1024-1315: code that copies bl2 from 4608 to 4096
4608-49151: bl2+bl21
49152+: bl30+bl301, bl31 and bl33(u-boot)
bl2.bin is modified to remove +512 image offset used when sd-booting by replacing
934: 91080273 add x19, x19, #0x200 // src += 512;
with
934: d503201f nop
aml_chksum is a small tool that writes new headers with updated offsets and checksums
The boot configuration uses the same payload for both eMCC and SD, but SD is missing sector 0 when read into memory, so the data in memory is shifted forward 512 bytes (eMMC sees 4608 while SD sees 4096). There’s some code that moves the bootloader in memory so that afterward it is in the same memory location for both SD and eMMC. Then there’s the part about rewriting the assembly. That implies the code is not signed; only a checksum is used. If we are willing to write or modify boot code, then we should have a lot of freedom.
Based on that commit message, SD has no hope of GPT, because the SD header is at the same location as the GPT header. But it would seem eMCC doesn’t need the SD header to boot. However, testing showed that eMMC wouldn’t boot without the SD header. To clear out the SD header:
dd conv=fsync if=/dev/zero of=$DEV seek=1 count=1
Investigation
Let’s investigate bl1.bin.hardkernel
as needed by U-Boot (as mentioned by
chewitt, the file name is misleading; it is the second-stage bootloader). The
U-Boot ODROID-C2 documentation (and Arch Linux
ARM) shows that BL2 should still be gotten from
HardKernel’s U-Boot fork:
git clone --depth 1 https://github.com/hardkernel/u-boot.git -b odroidc2-v2015.01 $DIR
...
BL1=$DIR/sd_fuse/bl1.bin.hardkernel
dd if=$BL1 of=$DEV conv=fsync bs=1 count=442
dd if=$BL1 of=$DEV conv=fsync bs=512 skip=1 seek=1
Looking at the contents of bl1.bin.hardkernel
(sha256:
15cf3aa6c6bd1f296de6f1e08de68c200f95f80197765a587743d6b4edf06435):
00000000: 24c8 161a a92c f048 24d3 5124 4fff 2776 $....,.H$.Q$O.'v
00000010: 4041 4d4c f0bf 0000 4000 0100 0000 0000 @AML....@.......
00000020: 0000 0000 4000 0000 0002 0000 0002 0000 ....@...........
00000030: 0000 0000 4002 0000 b00f 0000 f0bd 0000 ....@...........
00000040: 0000 0000 0004 0000 00b0 0000 0000 0000 ................
00000050: fac5 de05 6593 8ad9 43aa 478c 26f5 08ca ....e...C.G.&...
00000060: 05fa 2208 1353 fc59 41be c276 c814 f690 .."..S.YA..v....
... zeros
00000200: 24c8 161a a92c f048 24d3 5124 4fff 2776 $....,.H$.Q$O.'v
00000210: 4041 4d4c f0bf 0000 4000 0100 0000 0000 @AML....@.......
00000220: 0000 0000 4000 0000 0002 0000 0002 0000 ....@...........
00000230: 0000 0000 4002 0000 b00f 0000 f0bb 0000 ....@...........
00000240: 0000 0000 0010 0000 00b0 0000 0000 0000 ................
00000250: 7255 e49c a599 09dc 45e8 51e3 a35c ce59 rU......E.Q..\.Y
00000260: e0e9 7275 b287 cddf 8b7c f9fb f9c7 50ca ..ru.....|....P.
... zeros
00000400: f403 00aa f503 01aa a000 38d5 3500 0094 ..........8.5...
00000410: 4001 00b4 0010 38d5 0000 74b2 0010 18d5 @.....8...t.....
00000420: df3f 03d5 a000 38d5 2200 0094 a000 38d5 .?....8.".....8.
00000430: 2600 0094 1200 0094 0000 0014 fd7b bfa9 &............{..
00000440: 0140 82d2 0000 82d2 fd03 0091 0200 96d2 .@..............
00000450: 0120 bbf2 0020 bbf2 0d00 0094 0000 82d2 . ... ..........
00000460: 0100 96d2 0020 bbf2 2200 0094 0000 82d2 ..... ..".......
00000470: fd7b c1a8 0020 bbf2 0000 1fd6 fd7b bfa9 .{... .......{..
00000480: fd03 0091 eeff ff97 0000 0014 0300 80d2 ................
00000490: 7f00 02eb a000 0054 2468 6338 0468 2338 .......T$hc8.h#8
000004a0: 6304 0091 fbff ff17 c003 5fd6 0000 0000 c........._.....
000004b0: 8000 0058 1f00 0091 c003 5fd6 0000 0000 ...X......_.....
000004c0: 400c 00d9 0000 0000 8000 0058 1f00 0091 @..........X....
000004d0: c003 5fd6 0000 0000 4009 00d9 0000 0000 .._.....@.......
000004e0: 003c 4092 1f00 00f1 e017 9f9a c003 5fd6 .<@..........._.
000004f0: 2300 3bd5 634c 50d3 8200 80d2 4220 c39a #.;.cLP.....B ..
00000500: 0100 018b 4304 00d1 0000 238a 207e 0bd5 ....C.....#. ~..
00000510: 0000 028b 1f00 01eb a3ff ff54 9f3f 03d5 ...........T.?..
00000520: c003 5fd6 0000 0000 0000 0000 0000 0000 .._.............
... zeros
00001200: 0200 0014 10aa 00d9 f403 00aa f503 01aa ................
00001210: a000 38d5 3d21 0094 a002 00b4 207f 0410 ..8.=!...... ...
00001220: 00c0 18d5 0010 38d5 0000 74b2 0010 18d5 ......8...t.....
... lots more
We see the same layout:
- 0x0000 (sector 0): eMMC header
- 0x0200 (sector 1): SD header
- 0x0400 (sector 2): eMCC adjustment code
- 0x1200 (sector 6+): the actual bootloader code
Comparing the two headers show they are very similar. Byte 0x3d is 0xbd vs 0xbb, and byte 0x45 is 0x04 vs 0x10. Why is the SD header necessary for eMMC boot?
Looking at the HardKernel U-Boot before the bl2 deletion, secureboot.c is the most interesting:
typedef enum{
AML_SIG_TYPE_NONE=0,
AML_SIG_TYPE_RSA_PKCS_V15,
AML_SIG_TYPE_RSA_PKCS_V21, //??
AML_SIG_TYPE_RSA_PKCS_V15_AES,
}e_aml_sig_type;
typedef enum{
AML_DATA_TYPE_NONE=0,
AML_DATA_TYPE_RSA_KEY,
AML_DATA_TYPE_AES_KEY,
AML_DATA_TYPE_PROGRAM_GO, //need this?
AML_DATA_TYPE_PROGRAM_CALL, //need this?
}e_aml_data_type;
#define AML_BLK_ID (0x4C4D4140)
#define AML_BLK_VER_MJR (1)
#define AML_BLK_VER_MIN (0)
typedef struct __st_aml_block_header{
//16
unsigned int dwMagic; //"@AML"
unsigned int nTotalSize; //total size: sizeof(hdr)+
// nSigLen + nDataLen
unsigned char bySizeHdr; //sizeof(st_aml_block)
unsigned char byRootKeyIndex;//root key index; only romcode
// will use it, others just skip
unsigned char byVerMajor; //major version
unsigned char byVerMinor; //minor version
unsigned char szPadding1[4]; //padding???
//16+16
unsigned int nSigType; //e_aml_sig_type : AML_SIG_TYPE_NONE...
unsigned int nSigOffset; //sig data offset, include header
unsigned int nSigLen; //sig data length
//unsigned char szPadding2[4]; //padding???
unsigned int nCHKStart; //begin to be protected with SHA2
//32+16
unsigned int nPUKType; //e_aml_data_type : AML_DATA_TYPE_PROGRAM
unsigned int nPUKOffset; //raw data offset, include header
unsigned int nPUKDataLen; //raw data length
//unsigned char szPadding4[4]; //padding???
unsigned int nCHKSize; //size to be protected with SHA2
//48+16
unsigned int nDataType; //e_aml_data_type : AML_DATA_TYPE_PROGRAM
unsigned int nDataOffset; //raw data offset, include header
unsigned int nDataLen; //raw data length
unsigned char szPadding3[4]; //padding???
//64
} st_aml_block_header;
// ...
/**
* pBuffer : st_aml_block_header + signature data + st_aml_block_header(mirror) + [PUK] + raw data
* 1. st_aml_block_header will have offset, length, type for signature data, PUK and raw data
* 2. signature data is a PKCS #1 v1.5 RSA signature of SHA256 (st_aml_block_header(mirror) + [PUK] + raw data)
* signed with the PUK's corresponding private key.
* 3. st_aml_block_header(mirror) is a mirror copy of st_aml_block_header for data consistency
* 4. PUK is a RSA Public Key to be used for signature check (PKCSv15 format)
* 5. raw data: has two types for romcode
* 5.1 1st stage: two keymax : the first is for 4 root key SHA256 and the second is for 4 user key SHA256
* 5.2 2nd stage: BL2 raw data
* ...
*/
st_aml_block_header
has some general values, then three regions (SIG, PUK,
DATA) along with a CHK region. The later comment shows PUK as being optional.
Let’s decode sector 0 (for eMMC). Note that bl1.bin.hardkernel
is 0xc200
bytes long. The @AML
magic starts at 0x10 as mentioned earlier (I assume
bytes 0-15 are magic), so decoding from there:
// SECTOR 0
dwMagic = "@AML"
nTotalSize = 0xbff0;
bySizeHdr = 0x40
byRootKeyIndex = 0;
byVerMajor = 1;
byVerMinor = 0;
szPadding1[4] = {0};
//16+16 (0x10 struct offset, 0x20 file offset)
nSigType = 0;
nSigOffset = 0x40;
nSigLen = 0x200;
nCHKStart = 0x200;
//32+16 (0x20 struct offset, 0x30 file offset)
nPUKType = 0;
nPUKOffset = 0x240;
nPUKDataLen = 0xfb0;
nCHKSize = 0xbdf0; // SECTOR 1: 0xbbf0
//48+16 (0x30 struct offset, 0x40 file offset)
nDataType = 0;
nDataOffset = 0x400; // SECTOR 1: 0x1000
nDataLen = 0xb000;
szPadding3[4] = {0};
Offsets appear to be relative to the start of the header (so are offset by 0x10). SIG starts at 0x40, immediately after the 0x40 byte header. PUK is next, after the 0x200 byte SIG. PUK ends at 0x11F0 and DATA overlaps it, but the SD header looks better. Decoding sector 1 (for SD) shows DATA starts at 0x1200 (since the SD header is offset by 0x200 from eMCC header). The assembly on-disk starts at 0x400 and 0x1200, so nDataOffset must ignore the 0x10 offset, which makes DATA immediately after PUK.
And we also see CHK starts at 0x200, which includes the SD header! So zeroing out the SD header causes the eMMC checksum to fail, even though it isn’t used.
I modified aml_chksum.c to only update the SHA256 checksum. I then used a hex editor to set nCHKSize=0 for eMMC, recalculated the checksum, and eMMC totally worked with GPT!
Testing out GPT
I have my (further) modified bl1.bin.hardkernel-fixedheaders. It just contains the two headers, and the SD header changes don’t really matter. To write only the eMMC header:
dd conv=fsync if=bl1.bin.hardkernel-fixedheaders of=$DEV bs=1 count=442
Since we only freed up space for the GPT header, we need to move the main GPT
table away from the bootloader. There’s unused space between U-Boot and the
first partition. Using gdisk
, after creating the partitions, type x
to
enter Expert mode (m
to go back), then j
to “move the main partition
table”. For the starting location, choose the last available starting sector
(generally 2016) before the first partition.
Command (? for help): x
Expert command (? for help): j
Currently, main partition table begins at sector 2 and ends at sector 33
Enter new starting location (2 to 2016; default is 2; 1 to abort): 2016
Expert command (? for help): m
Command (? for help):
p
shows “Main partition table begins at sector” to confirm where it is
positioned.
Command (? for help): p
Disk /dev/mmcblk0: 16777216 sectors, 8.0 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): D43FD65D-717C-43D5-B0F2-A821C3946118
Partition table holds up to 128 entries
Main partition table begins at sector 2016 and ends at sector 2047
First usable sector is 2048, last usable sector is 16777182
Partitions will be aligned on 2048-sector boundaries
Total free space is 2015 sectors (1007.5 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00 EFI system partition
2 1050624 16775167 7.5 GiB 8305 Linux ARM64 root (/)
Further changes
Other modifications that looked interesting:
- Set nCHKStart/nCHKSize to just cover functional bytes
- Set nSigLen=0x20. SHA256 is not 0x200 in size. Has no real effect, but it would make the values more obvious
- Set nPUKOffset=0/nPUKDataLen=0. It isn’t used; don’t act like it is there
- Set eMMC nDataOffset=0xE00 and move the relocation code. This would free up 5 sectors for the main GPT table
- Set eMMC nDataOffset=0x70 if we are fine with the relocation code not being part of CHK. This would free up 2 more sectors relative to using 0xE00
- (Failed) Set eMCC nDataOffset=0x40 and put the relocation code before SIG and still checksumed. Unfortunately, based on testing we can’t increase the header size. Moving SIG to start later didn’t work either
- Use modified relocation code for both SD and eMCC to free up another 9 sectors. 0xae00-0xc000 is empty, so we can shift the main BL2 code backward 9 sectors on-disk
Pushing much beyond 0xc000 would be annoying as that’s getting to where
BL3/U-Boot is stored. It also doesn’t sound feasible as aml_chksum.c,
HardKernel’s arch-gxb/cpu_config.h’s BL2_SIZE, and
firmware/plat/gxb/include/platform_def.h’s BL2_LIMIT mention 48 KiB as the BL2
size limit. Since we can’t get the 32 sectors necessary for a spec-compliant
GPT table, options 4-7 don’t seem too valuable. Even though gdisk
has the
expert command s
to resize the partition table, moving it is just as easy and
remains spec-compliant.
I made modifications 1, 2, and 3 in bl1.bin.hardkernel-fixedheaders.
Tying up loose ends
Why did Kwiboo strip out the +512 offset but we no longer need to? Because in our version of bl1.bin.hardkernel both SD and eMMC have the +512 disk offset (see assembly at 0x1890 for eMCC and 0x18b8 for SD). So our BL3 is on-disk at 0xc200 instead of 0xc000.
HardKernel U-Boot’s bl2_main.c has the comment: “Since arm standard c libraries are not PIC, printf et al are not available. We rely on assertions to signal error conditions”. Don’t let that confuse you; the BL2 binary is not fully PIC. The code assumes it runs at 0xd9001000 (bl1 loads bl2 starting at 0xd9000000, and the code is at the offset 0x1000 for SD), and there are absolute addresses. Although the relocation code is position-independent, it is hard-coded to memcpy 0xb000 bytes from 0xd9001200 to 0xd9001000.
Windows 98 SE on QEMU
I had Journeyman Project Turbo working on Windows XP and Windows 3.1. I wanted to continue the effort with Windows 98 SE. I used QEMU with pc-i440fx, AC97 audio, RTL8139 network, and VGA video. Steps that worked:
- Install Windows 98 SE from the ISO
- Configure “Plug and Play BIOS” to use PCI bus driver as documented by SoftGPU
- When the network device is found, use the RTL8139 floppy image from archive.org
- Continuing the SoftGPU documentation:
- Turn on DMA for HDD and CD-ROM
- Change Network Logon to Windows Login
- Download and install 7zip
- Open 7zip then in “Tools > Options” associate it with the zip extension
- Download and configure the sound card with AC97 drivers
- Copy “D:\Win98” from Windows CD to “C:\Windows\Options\Cabs”. In regedit, navigate to “HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup” and change “SourcePath” to the new path.
- Install SoftGPU via its ISO. You can disable the DirectX 9 install
Sharing files with WebDAV
The Internet is essentially limited to HTTP (no HTTPS). Any file-sharing needs to be unencrypted. WebDAV is a pretty reasonable tool for the circumstance. To access from Windows 98, it’s as easy as My Computer > Web Folders > Add Web Folder, including “http://” in its location.
For the host, I’m running Linux and chezdav from phodav proved pretty easy (even if it has very permissive defaults). For a publically writable directory:
chezdav --no-mdns -P path/to/folder
To protect it with a password, use htdigest from apache:
htdigest -c webdav.digest myrealm myusername
# enter password
chezdav --no-mdns -P path/to/folder -d webdav.digest
I’ve good experience with the webdav server in Go, and a minimal Go webdav
server works well. davserver
from PyWebDAV3 also looks
promising, but I didn’t try it out.
Journeyman Project Turbo on Windows 3.1
I was interested in playing Journeyman Project Turbo, which was difficult to play as a kid because Packard Bell provided the game with our Pentium 133, but didn’t include a manual with the disk.
It doesn’t work under Wine 9.12 with DOSBox installed, with winevdm crashing. It runs pretty easily on 32-bin Windows XP. But I hadn’t ever installed Windows 3.1 before, so I figured I’d see what it takes.
My Journeyman Project disk image is in a CUE+BIN form, so I converted it to an ISO with bchunk:
bchunk jman.bin jman.cue jman.iso
Journeyman Project Turbo requires Video for Windows 1.1e, but didn’t include it
on the disk I was using. I found a copy on WinWorld. After
extracting, I named the image vm1.1e.img
for easier typing in DOS.
For the Windows 3.1 install, I found the Medium post Let’s Install Windows 3.1 in Dosbox helpful.
I have Windows 3.1 as 6 disk img files. Dosbox can mount such a disk via
imgmount a disk1.img -t floppy
, but won’t let you change the mounted disk
while running Windows setup. So instead, you have to use a folder, mount the
folder (e.g., mount a curdisk
), exchange the contents of the folder when
needed during the setup, and press Ctrl+F3 for dosbox to reload the directory.
Easier though, is to copy all the contents of all the disks into the directory
up-front.
# Mount all the images, then
mkdir win31
cp WIN31DISK*/* win31/
I used S3 drivers for video and SB16 drivers for audio. I downloaded S3DRIVERS.ZIP and SB16W3X.ZIP and extracted them their own directories.
With the Journeyman Project software dependencies ready, the install:
pacman -S dosbox
# installed 0.74.3
mkdir c
dosbox
mount c c
mount a win31
a:setup
# Enter (Continue)
# Enter (Express Setup)
# -- Figure it out -- (e.g., no printer)
# Return to MS-DOS
mount -u a
mount a SB16W3X
a:install
# Enter (Continue)
# Enter (Full Installation)
# Press down to select Windows path. Enter to select. Enter to accept C:\Windows
# Enter (Continue)
# Press down to select Interrupt setting. Change it to 7, since
# `~/.dosbox/dosbox-0.74-3.conf` has an `[sblaster]` section with `irq=7`
> Enter (Continue)
> -- Install is much, much slower than Windows 3.1 --
> Backup MIDIMAP.CFG
> Enter (Exit)
mount -u a
mount a S3DRIVERS
# Current directory must be c:\WINDOWS directory
setup
# "Accept the configuration shown above." should be selected. If it is trying
# to install, you weren't in the WINDOWS directory
# Move up to Display, Enter. Go to bottom and select "Other". Enter for A:\
# Select third: 640x480 64K colors. Prevents graphical glitches in-game
# Enter to "Accept the configuration shown above."
exit
dosbox
mount c c
imgmount a mv1.1e.img -t floppy
c:
cd windows
a:setup
# You should hear "tada" startup sound as Windows starts
# Go through install
# "Restart Now". Quit dosbox
dosbox
mount c c
# Use z:imgmount if copied to autoexec.bat
imgmount d jm.iso -t cdrom
c:\windows\win
# File Manager. Select drive D
# Run jman.exe. Tell it to find the files in D:\ if it asks
You can add the last two commands to c/AUTOEXEC.BAT and then run with dosbox c/AUTOEXEC.BAT
.
Flatpak Permission Survey
When working through yesterday’s post, half-way through I found the 2020 flatkill.org post and the TheEvilSkeleton response. The response was early 2021 and felt hopeful for the future.
One very different take is they were both focused on popular applications. I
was focused more on productivity applications and those that I could choose
between my distro and Flatpak to get a feel of Flatpak, apples to apples. But
the biggest concern is the statistics about 27 out of 50 popular applications
not having --filesystem=host
or --filesystem=home
. As I saw yesterday,
there are other ways to break out of the sandbox. I figured I’d take a look
myself, but unfortunately the popular apps today are mostly emulators and
Blink-based, so things look pretty bleak with that set. I think it is a skewed
set due to the Steam Deck, and worse than the majority of packages.
Popular
The following is from the first page of
popular on Flathub, sorted
hopefully by popularity. It is the top 30 items, because the pages hold 30. The
first three columns are straight from Flatpak’s website. “Verified” is whether
the packager has a blue check. “Security” is the sandbox permission badge
color. “Concerning permissions” is my own selection of permissions that are
concerning. I made some arbitrary decisions on what to include, mostly focusing
on sandbox escapes and unfortunate mixes of permissions. In particular, it
includes --device=all
but not pulseaudio, as access to all devices might have
more implications than just webcam access.
Name | Verified | Security | Concerning permissions |
---|---|---|---|
Google Chrome | 0 | Red | –device=all –socket=x11 –share=network –talk-name=org.freedesktop.secrets –filesystem=xdg-run/dconf Why so much file access? |
Firefox | 1 | Red | –device=all –share=network |
VLC | 0 | Red | –filesystem=host –device=all –socket=x11 –share=network –talk-name=org.freedesktop.secrets |
Discord | 1 | Red | –device=all –socket=x11 –share=network |
Dolphin Emulator | 0 | Red | –filesystem=host:ro –device=all –socket=x11 –share=network |
RPCS3 | 0 | Red | –filesystem=home:ro –device=all –share=network –filesystem=/media |
PPSSPP | 1 | Red | –device=all –socket=x11 –share=network |
DuckStation | 1 | Red | –device=all –socket=x11 –share=network |
Citra | 1 | Red | –filesystem=host:ro –device=all –socket=x11 –share=network |
Brave Browser | 0 | Red | –device=all –socket=x11 –share=network –talk-name=org.freedesktop.secrets –filesystem=xdg-run/dconf |
RetroArch | 1 | Red | –filesystem=host –share=network |
xemu | 0 | Red | –filesystem=host:ro –device=all –share=network |
melonDS | 1 | Red | –filesystem=home –device=all –socket=x11 –share=network |
PrimeHack | 1 | Red | –filesystem=host:ro –device=all –socket=x11 –share=network |
Telegram Desktop | 1 | Red | –device=all –share=network |
Spotify | 0 | Red | –device=all –share=network |
Visual Studio Code | 0 | Red | –filesystem=host –device=all –socket=x11 –share=network –socket=ssh-auth –talk-name=org.freedesktop.secrets |
Steam | 0 | Red | –device=all –socket=x11 –share=network |
ProtonUp-Qt | 1 | Red | –filesystem=~/.bashrc –device=all –socket=x11 –share=network |
Microsoft Edge | 0 | Red | –device=all –socket=x11 –share=network –talk-name=org.freedesktop.secrets –filesystem=xdg-run/dconf |
Flatseal | 1 | Red | –filesystem=xdg-data/flatpak/overrides:create |
Bottles | 1 | Red | –device=all –socket=x11 –share=network –system-talk-name=org.freedesktop.UDisks2 |
ScummVM | 1 | Red | –filesystem=home –device=all –socket=x11 –share=network |
Protontricks | 1 | Red | –device=all –socket=x11 –share=network –system-talk-name=org.freedesktop.UDisks2 |
Extension Manager | 1 | Yellow | –share=network |
GIMP | 1 | Red | –filesystem=host –socket=x11 –share=network |
OBS Studio | 1 | Red | –filesystem=host –device=all –socket=x11 –share=network |
Heroic Games Launcher | 1 | Red | –device=all –filesystem=mnt/media –filesystem=~/.local/share/applications –socket=x11 –share=network |
LibreOffice | 1 | Red | –filesystem=host –share=network –filesystem=xdg-run/gvfsd |
qBittorrent | 1 | Red | –filesystem=host –share=network |
Some comments:
- 2/3 have a verified packager
- The security badge is normally red
- Every top app has
--share=network
- Every top app, except for Extension Manager, has
--device=all
or--filesystem=host
- 2/3 have
--socket=x11
While going through the manifests, I noticed that --talk-name
doesn’t show up
in the listed permissions on the Flatpak website. That is very serious, as
--talk-name=org.freedesktop.secrets
seems important and access to the systemd
service provides a trivial sandbox escape. I tried to guess which dbus services
are “dangerous”, and some I looked up their definiton to make a judgement.
Strangely, I couldn’t find the definition of org.gnome.Software
.
Some permission combinations are a problem without sandbox escape.
As examples, there’s little need to escape from the sandbox with
--filesystem=home:ro --share=network
or --talk-name=org.freedesktop.secrets --share=network
.
Only a minor concern, but I noticed that --metadata=X-DConf=migrate-path=
isn’t listed on the Flatpak website. This is a very good feature that avoids
sharing write access to all settings. But I’d have to investigate more to see
if just read-only access to settings can be a problem. It won’t contain
secrets, but there’s so many options it makes me wonder.
My programs of interest
These are the programs that I was looking at when making yesterday’s post, with a few additions. They are mostly GNOME/GTK, but with some oddballs mixed in. There are both very old GNOME programs (Videos, a.k.a. Totem) and some more recent remakes (Image Viewer, a.k.a. Loupe). I chose these as an “interesting” set. They are sorted by name.
Name | Verified | Security | Concerning permissions |
---|---|---|---|
Boxes | 1 | Red | –filesystem=host –device=all –share=network –talk-name=org.gnome.Settings –filesystem=xdg-run/dconf |
Calculator | 1 | Yellow | –share=network |
Characters | 1 | Green | |
Connections | 1 | Yellow | –share=network |
Disk Usage Analyzer | 1 | Red | –filesystem=host –filesystem=xdg-run/gvfs |
Document Scanner | 0 | Red | –device=all –share=network |
Document Viewer | 1 | Red | –filesystem=home:ro –filesystem=xdg-run/gvfsd |
Ear Tag | 1 | Red | –share=network |
File Roller | 1 | Red | –filesystem=home |
Flips | 0 | Red | –filesystem=home |
Foliate | 1 | Red | –share=network |
gedit | 0 | Red | –filesystem=host –filesystem=xdg-run/gvfsd |
GHex | 0 | Red | –filesystem=host –filesystem=xdg-run/gvfsd |
GnuCash | 0 | Red | –filesystem=host –share=network |
gThumb Image Viewer | 0 | Red | –talk-name=org.freedesktop.secrets –filesystem=xdg-run/gvfs |
HxC Floppy Emulator | 0 | Red | –socket=x11 |
Image Viewer | 1 | Red | –filesystem=host –filesystem=xdg-run/gvfs |
KiCad | 1 | Red | –filesystem=home –socket=x11 –share=network |
Meld | 0 | Red | –filesystem=host |
Piper | 0 | Red | –socket=x11 |
Remmina | 1 | Red | –filesystem=home –device=all –share=network –socket=ssh-auth –talk-name=ca.desrt.dconf –filesystem=xdg-run/gvfsd |
Rhythmbox | 0 | Red | –share=network –filesystem=xdg-run/gvfsd |
Videos | 1 | Red | –device=all –share=network –talk-name=org.gnome.OnlineAccounts –filesystem=/run/media –filesystem=xdg-run/gvfs |
Some comments:
- 1/2 have a verified packager
- The security badge is normally red, but greens aren’t entirely mythical
- Four have
--share=network
without other relatively problematic permissions - Most that are missing
--share=network
have a trivial sandbox escape - Foliate is only red only because it has
--filesystem=xdg-run/speech-dispatcher:ro
.
With this set of apps, we are in the murky sandbox territory that I was
wrestling with yesterday. A sandbox might help some of these. But the
permission list exposed to users is insufficient for determining if the app is
sandboxed more than in name. It also doesn’t really matter, because with almost
universal red security badges, the user is required ignore it. If
--share=network
allows access to the session bus on my distro, then only
Characters is safe, ignoring upgrades adding permissions and assuming I trust
Flatpak after all this.