Skip to content

Commit

Permalink
v3.0.0
Browse files Browse the repository at this point in the history
rework
  • Loading branch information
HuskyDG committed May 26, 2023
0 parents commit 37b39db
Show file tree
Hide file tree
Showing 29 changed files with 1,779 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
33 changes: 33 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Build Magisk module

on:
workflow_dispatch:
push:
pull_request:

jobs:
build:
runs-on: ubuntu-latest
if: ${{ !startsWith(github.event.head_commit.message, '[skip ci]') }}

steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: 'recursive'
fetch-depth: 0
- name: SetupNDK
uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r24
- name: Build
id: build
run: |
chmod 777 ./build.sh
./build.sh
- name: Upload release
uses: actions/upload-artifact@v3
with:
name: magisk-overlayfs-release
path: out/magisk-module
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.DS_Store
*.zip
*.so
*.dex

# VS Code Java Language Server
.settings/
.project
.classpath
*.iml
.gradle
/local.properties
/.idea
/build
/captures
.externalNativeBuild
.cxx
local.properties
*.sha256
119 changes: 119 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Magisk Overlayfs

On Android 10+, system partitions might no longer be able to remount as read-write. For devices use dynnamic partition, it is nearly impossible to modify system partiton as there is no space left. This module solves these problem by using OverlayFS. So what is OverlayFS? On [Wikipedia](https://en.m.wikipedia.org/wiki/OverlayFS):

> OverlayFS is a union mount filesystem implementation for Linux. It combines multiple different underlying mount points into one, resulting in single directory structure that contains underlying files and sub-directories from all sources. Common applications overlay a read/write partition over a read-only partition, such as with LiveCDs and IoT devices with limited flash memory write cycles.
Benefits of using overlayfs for system partitions:

- Make most parts of system partition (`/system`, `/vendor`, `/product`, `/system_ext`, `/odm`, `/odm_dlkm`, `/vendor_dlkm`, ...) become read-write.
- `/data` storage is used for `upperdir` of OverlayFS mount. However, on some kernel, f2fs is not supported by OverlayFS and cannot be used directly. The workaround is to create an ext4 loop image then mount it.
- All modifications to overlayfs partition will not be made directly, but will be stored in upperdir, so it is easy to revert. Just need to remove/disable module so your system will return to untouched stage.
- Support Magisk version 23.0+ and latest version of KernelSU

> If you are interested in OverlayFS, you can read documentation at <https://docs.kernel.org/filesystems/overlayfs.html>
## Build

There is two way:
- Fork this repo and run github actions
- Run `bash build.sh` (On Linux/WSL)

## KernelSU problem

- The KernelSU module is similar to Magisk in that it allows users to modify the system partition while maintaining system integrity. It does this through the implementation of overlayfs. However, it's important to note that KernelSU makes changes to the system partition by using read-only overlayfs, which also mounts on top of magic_overlayfs and prevent system from being remounted as read-write. If you want to remount your system partitions as read-write, you simply need to first unmount the KernelSU overlayfs using this command:

```
nsenter -t 1 -m overlayfs_system --unmount-ksu
```

- After that you will be able to remount system as read-write

## Change OverlayFS mode

- OverlayFS is mounted as read-only by default

- Configure overlayfs mode in `/data/adb/modules(_update)/magisk_overlayfs/mode.sh` to change mode of OverlayFS

> Read-write mode of overlayfs will cause baseband on some devices stop working
```
# 0 - read-only but can still remount as read-write
# 1 - read-write default
# 2 - read-only locked (cannot remount as read-write)
export OVERLAY_MODE=2
```

- OverlayFS upper loop device will be setup at `/dev/block/overlayfs_loop`
- On Magisk, OverlayFS upper loop are mounted at `$(magisk --path)/overlayfs_mnt`. You can make modifications through this path to make changes to overlayfs mounted in system.

## Modify system files with OverlayFS

- If you are lazy to remount, please modify `mode.sh` and set it to `OVERLAY_MODE=1` so overlayfs will be always read-write every boot.

- You can quickly remount all overlayfs to read-write by this command in terminal:
```bash
su -mm -c magic_remount_rw
```

- After that you can restore all system partitons back to read-only mode by this commamd in terminal:
```bash
su -mm -c magic_remount_ro
```


## Overlayfs-based Magisk module

- If you want to use overlayfs mount for your module, add these line to the end of `customize.sh`:

```bash
OVERLAY_IMAGE_EXTRA=0 # number of kb need to be added to overlay.img
OVERLAY_IMAGE_SHRINK=true # shrink overlay.img or not?
INCLUDE_MAGIC_MOUNT=false # enable legacy Magisk mount

# Only use OverlayFS if Magisk_OverlayFS is installed
if [ -f "/data/adb/modules/magisk_overlayfs/util_functions.sh" ] && \
/data/adb/modules/magisk_overlayfs/overlayfs_system --test; then
ui_print "- Add support for overlayfs"
. /data/adb/modules/magisk_overlayfs/util_functions.sh
support_overlayfs && rm -rf "$MODPATH"/system
fi
```

## Bugreport

- Please include `/cache/overlayfs.log`

## Reset overlayfs

- Remove `/data/adb/overlay` and reinstall module

## Without Magisk

- Simple configuration to test:

```bash
# - Create a writeable directory in ext4 (f2fs) /data
# which will be used for upperdir
# - On some Kernel, f2fs is not supported by OverlayFS
# and cannot be used directly
WRITEABLE=/data/overlayfs

mkdir -p "$WRITEABLE"

# - Export list of modules if you want to load mounts by overlayfs
# - If you have /vendor /product /system_ext as seperate partitons
# - Please move it out of "system" folder, overwise **BOOM**
export OVERLAYLIST=/data/adb/modules/module_a:/data/adb/modules/module_b

# - If there is Magisk, export this in post-fs-data.sh (before magic mount):
export MAGISKTMP="$(magisk --path)"

# - Load overlayfs
./overlayfs_system "$WRITEABLE"
```

## Source code

- <http://github.com/HuskyDG/Magisk_OverlayFS>
32 changes: 32 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash

set -euo pipefail

build_mode="${1:-release}"

cd "$(dirname "$0")"

plugin() {
rm -rf "$1"
git clone "$2" "$1"
}
# <DIRECTORY> <PLUG-IN LINK>
plugin ./native/jni/libcxx http://github.com/huskydg/libcxx || exit 1
plugin ./native/jni/external/selinux https://github.com/topjohnwu/selinux || exit 1
plugin ./native/jni/external/pcre https://android.googlesource.com/platform/external/pcre || exit 1

pushd native
rm -fr libs obj
debug_mode=1
if [[ "$build_mode" == "release" ]]; then
debug_mode=0
fi
ndk-build -j4 NDK_DEBUG=$debug_mode
popd

rm -rf out
mkdir -p out
cp -af magisk-module out
cp -af README.md out/magisk-module
cp -af native/libs out/magisk-module
zip -r9 out/magisk-module-release.zip out/magisk-module
33 changes: 33 additions & 0 deletions magisk-module/META-INF/com/google/android/update-binary
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/sbin/sh

#################
# Initialization
#################

umask 022

# echo before loading util_functions
ui_print() { echo "$1"; }

require_new_magisk() {
ui_print "*******************************"
ui_print " Please install Magisk v23.0+! "
ui_print "*******************************"
exit 1
}

#########################
# Load util_functions.sh
#########################

OUTFD=$2
ZIPFILE=$3

mount /data 2>/dev/null

[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
. /data/adb/magisk/util_functions.sh
[ $MAGISK_VER_CODE -lt 23000 ] && require_new_magisk

install_module
exit 0
1 change: 1 addition & 0 deletions magisk-module/META-INF/com/google/android/updater-script
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#MAGISK
133 changes: 133 additions & 0 deletions magisk-module/customize.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
SKIPUNZIP=1

if [ "$BOOTMODE" ] && [ "$KSU" ]; then
ui_print "- Installing from KernelSU app"
ui_print "- KernelSU version: $KSU_KERNEL_VER_CODE (kernel) + $KSU_VER_CODE (ksud)"
ui_print "- Please note that KernelSU modules mount will make"
ui_print " your system partitions unable to mount as rw"
ui_print "- If you are using KernelSU, "
ui_print " please unmount all ksu overlayfs"
ui_print " when you want to modify system partitions"
elif [ "$BOOTMODE" ] && [ "$MAGISK_VER_CODE" ]; then
ui_print "- Installing from Magisk app"
else
ui_print "*********************************************************"
ui_print "! Install from recovery is not supported"
ui_print "! Please install from KernelSU or Magisk app"
abort "*********************************************************"
fi

loop_setup() {
unset LOOPDEV
local LOOP
local MINORX=1
[ -e /dev/block/loop1 ] && MINORX=$(stat -Lc '%T' /dev/block/loop1)
local NUM=0
while [ $NUM -lt 1024 ]; do
LOOP=/dev/block/loop$NUM
[ -e $LOOP ] || mknod $LOOP b 7 $((NUM * MINORX))
if losetup $LOOP "$1" 2>/dev/null; then
LOOPDEV=$LOOP
break
fi
NUM=$((NUM + 1))
done
}

randdir="$TMPDIR/.$(head -c21 /dev/urandom | base64)"
mkdir -p "$randdir"

ABI="$(getprop ro.product.cpu.abi)"

# Fix ABI detection
if [ "$ABI" == "armeabi-v7a" ]; then
ABI32=armeabi-v7a
elif [ "$ABI" == "arm64" ]; then
ABI32=armeabi-v7a
elif [ "$ABI" == "x86" ]; then
ABI32=x86
elif [ "$ABI" == "x64" ] || [ "$ABI" == "x86_64" ]; then
ABI=x86_64
ABI32=x86
fi

unzip -oj "$ZIPFILE" "libs/$ABI/overlayfs_system" -d "$TMPDIR" 1>&2
chmod 777 "$TMPDIR/overlayfs_system"

if ! $TMPDIR/overlayfs_system --test; then
ui_print "! Kernel doesn't support overlayfs, are you sure?"
abort
fi


ui_print "- Extract files"

unzip -oj "$ZIPFILE" post-fs-data.sh \
service.sh \
util_functions.sh \
mode.sh \
mount.sh \
uninstall.sh \
module.prop \
"libs/$ABI/overlayfs_system" \
-d "$MODPATH"
unzip -oj "$ZIPFILE" util_functions.sh -d "/data/adb/modules/${MODPATH##*/}"

ui_print "- Setup module"

chmod 777 "$MODPATH/overlayfs_system"

resize_img() {
e2fsck -pf "$1" || return 1
if [ "$2" ]; then
resize2fs "$1" "$2" || return 1
else
resize2fs -M "$1" || return 1
fi
return 0
}

test_mount_image() {
loop_setup /data/adb/overlay
[ -z "$LOOPDEV" ] && return 1
result_mnt=1
mount -t ext4 -o rw "$LOOPDEV" "$randdir" && \
"$MODPATH/overlayfs_system" --test --check-ext4 "$randdir" && result_mnt=0
# ensure that uppderdir does not override my binary
rm -rf "$randdir/upper/system/bin/overlayfs_system" \
"$randdir/upper/system/bin/magic_remount_rw" \
"$randdir/upper/system/bin/magic_remount_ro"
umount -l "$randdir"
return $result_mnt
}

create_ext4_image() {
dd if=/dev/zero of="$1" bs=1024 count=100
/system/bin/mkfs.ext4 "$1" && return 0
return 1
}

if [ ! -f "/data/adb/overlay" ] || ! test_mount_image; then
rm -rf "/data/adb/overlay"
ui_print "- Setup 2GB ext4 image at /data/adb/overlay"
ui_print " Please wait..."
if ! create_ext4_image "/data/adb/overlay" || ! resize_img "/data/adb/overlay" 2000M || ! test_mount_image; then
rm -rf /data/adb/overlay
abort "! Setup ext4 image failed, abort"
fi
fi

mkdir -p "$MODPATH/system/bin"
chcon -R u:object_r:system_file:s0 "$MODPATH/system"
chmod -R 755 "$MODPATH/system"

cp -af "$MODPATH/overlayfs_system" "$MODPATH/system/bin"
ln -s "./overlayfs_system" "$MODPATH/system/bin/magic_remount_rw"
ln -s "./overlayfs_system" "$MODPATH/system/bin/magic_remount_ro"

if [ "$BOOTMODE" ] && [ -z "$KSU" ]; then
. "$MODPATH/util_functions.sh"
support_overlayfs && rm -rf "$MODPATH/system"
fi

ui_print
5 changes: 5 additions & 0 deletions magisk-module/mode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 0 - read-only but can still remount as read-write
# 1 - read-write default
# 2 - read-only locked (cannot remount as read-write)

export OVERLAY_MODE=0
6 changes: 6 additions & 0 deletions magisk-module/module.prop
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
id=magisk_overlayfs
name=Magical Overlayfs
author=HuskyDG
version=v3.0.0
versionCode=30000
description=Use OverlayFS to make read-only system partitions become read-write partitions. OverlayFS MUST be supported by kernel!
Loading

0 comments on commit 37b39db

Please sign in to comment.