Skip to content
This repository has been archived by the owner on Feb 13, 2024. It is now read-only.

Compatibility with kernels >= 5.7 #76

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4af9d5d
Fix compilation of binder and ashmem on kernel 5.7 and later
choff Mar 8, 2021
443f984
Compile fixes for kernel >= 5.8
choff Mar 8, 2021
6ddae19
Another compile fix for kernel >= 5.8
choff Mar 8, 2021
0338a34
Update binder to the latest version
choff Sep 26, 2021
516144c
Compile fixes for kernels 5.11, 5.12 & 5.13
choff Oct 29, 2021
b0c3c5a
compilation fix for kernel 5.15.2
modscleo4 Nov 13, 2021
8148a16
sync with android binder.c
modscleo4 Nov 23, 2021
2699623
patches for 5.18 kernel
Etaash-mathamsetty May 25, 2022
6844495
Patches for kernel 5.19
Thesola10 Aug 8, 2022
2325d6f
Fixed page fault by matching in-tree binder behavior
Thesola10 Aug 9, 2022
cd66055
Fix build on 6.0 kernel
arenekosreal Oct 15, 2022
42335c6
Fix build on 6.1 kernel
arenekosreal Dec 24, 2022
ab8278c
Add TASK_FREEZABLE
arenekosreal Jan 29, 2023
a961389
fix for kernel 6.1
munix9 Jan 30, 2023
ae26ba2
Create UNINSTALL.sh script and update README.md
SonarBeserk Oct 30, 2022
44dc351
Update README.md
Krishnakumar59 Apr 18, 2023
abead1d
Fixes for kernel 6.3+
Thesola10 May 5, 2023
205c803
Fix build for kernel 6.6
arenekosreal Nov 1, 2023
41fe6db
Fix build for 6.6
Nov 23, 2023
084d199
Added conditional matching for kernels >= 6.3.0
Dec 3, 2023
13a93a4
Fix for kernel 6.7+
ssfdust Jan 6, 2024
44e5ba7
Fixes for kernel 6.8
ssfdust Jan 24, 2024
b558310
removed obsolete name="%k", added binder symlink (#1)
PuspenduBanerjee Apr 1, 2024
dcd52bf
Added packaging guide and compat fix
PuspenduBanerjee Apr 2, 2024
2c06452
updated doc to update changelog from git commits
PuspenduBanerjee Apr 2, 2024
ee4c25f
fix creation of all 3 anbox modules symlinks: anbox-binder anbox-hwbi…
May 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.ko
*.mod
*.mod.c
*.o
*.order
*.symvers
*.swp
.*.cmd
.tmp_versions
4 changes: 2 additions & 2 deletions 99-anbox.rules
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
KERNEL=="ashmem", NAME="%k", MODE="0666"
KERNEL=="binder*", NAME="%k", MODE="0666"
KERNEL=="ashmem", MODE="0666"
KERNEL=="*binder", MODE="0666", SYMLINK+="anbox-%k"
74 changes: 63 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,31 @@ You can either run `./INSTALL.sh` script to automate the installation steps or f
* First install the configuration files:

```
$ sudo cp anbox.conf /etc/modules-load.d/
$ sudo cp 99-anbox.rules /lib/udev/rules.d/
sudo cp anbox.conf /etc/modules-load.d/
sudo cp 99-anbox.rules /lib/udev/rules.d/
```

* Then copy the module sources to `/usr/src/`:

```
$ sudo cp -rT ashmem /usr/src/anbox-ashmem-1
$ sudo cp -rT binder /usr/src/anbox-binder-1
sudo cp -rT ashmem /usr/src/anbox-ashmem-1
sudo cp -rT binder /usr/src/anbox-binder-1
```

* Finally use `dkms` to build and install:

```
$ sudo dkms install anbox-ashmem/1
$ sudo dkms install anbox-binder/1
sudo dkms install anbox-ashmem/1
sudo dkms install anbox-binder/1
```

You can verify by loading these modules and checking the created devices:

```
$ sudo modprobe ashmem_linux
$ sudo modprobe binder_linux
$ lsmod | grep -e ashmem_linux -e binder_linux
$ ls -alh /dev/binder /dev/ashmem
sudo modprobe ashmem_linux
sudo modprobe binder_linux
lsmod | grep -e ashmem_linux -e binder_linux
ls -alh /dev/binder /dev/ashmem
```

You are expected to see output like:
Expand All @@ -56,4 +56,56 @@ binder_linux 114688 0
ashmem_linux 16384 0
crw-rw-rw- 1 root root 10, 55 Jun 19 16:30 /dev/ashmem
crw-rw-rw- 1 root root 511, 0 Jun 19 16:30 /dev/binder
```
```

# Uninstall Instructions

ou can either run `./UNINSTALL.sh` script to automate the installation steps or follow them manually below:

* First use dkms to remove the modules:

```
sudo dkms remove anbox-ashmem/1
sudo dkms remove anbox-binder/1
```

* Then remove the module sources from /usr/src/:

```
sudo rm -rf /usr/src/anbox-ashmem-1
sudo rm -rf /usr/src/anbox-binder-1
```

* Finally remove the configuration files:

```
sudo rm -f /etc/modules-load.d/anbox.conf
sudo rm -f /lib/udev/rules.d/99-anbox.rules
```

You must then restart your device. You can then verify modules were removed by trying to load the modules and checking the created devices:

```
sudo modprobe ashmem_linux
sudo modprobe binder_linux
lsmod | grep -e ashmem_linux -e binder_linux
ls -alh /dev/binder /dev/ashmem
```

You are expected to see output like:

```
modprobe: FATAL: Module ashmem_linux not found in directory /lib/modules/6.0.2-76060002-generic
modprobe: FATAL: Module binder_linux not found in directory /lib/modules/6.0.2-76060002-generic
ls: cannot access '/dev/binder': No such file or directory
ls: cannot access '/dev/ashmem': No such file or directory
```

# Packaging:
## Debian/Ubuntu:
```
sudo apt-get install devscripts dh-dkms -y
git log --pretty=" -%an<%ae>:%aI - %s" > ./debian/changelog
debuild -i -us -uc -b
ls -lrt ../anbox-modules-dkms_*.deb
```
45 changes: 45 additions & 0 deletions UNINSTALL.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

# First use dkms to remove the modules:
sudo dkms remove anbox-ashmem/1
sudo dkms remove anbox-binder/1

# Then remove the module sources from /usr/src/:
sudo rm -rf /usr/src/anbox-ashmem-1
sudo rm -rf /usr/src/anbox-binder-1

# Finally remove the configuration files:
sudo rm -f /etc/modules-load.d/anbox.conf
sudo rm -f /lib/udev/rules.d/99-anbox.rules

# Verify remove by trying to load the modules and checking the created devices:
failed_checks=0
if sudo modprobe ashmem_linux > /dev/null 2>&1; then
failed_checks=1
else
failed_checks=0
fi

if sudo modprobe binder_linux > /dev/null 2>&1; then
failed_checks=1
else
failed_checks=0
fi

if lsmod | grep -e ashmem_linux -e binder_linux > /dev/null 2>&1; then
failed_checks=1
else
failed_checks=0
fi

if ls -alh /dev/binder /dev/ashmem > /dev/null 2>&1; then
failed_checks=1
else
failed_checks=0
fi

if [ $failed_checks == 1 ]; then
echo "Please restart your device and rerun this script to verify changes"
else
echo "Modules not installed"
fi
33 changes: 32 additions & 1 deletion ashmem/ashmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,11 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
ret = -EPERM;
goto out;
}
vma->vm_flags &= ~calc_vm_may_flags(~asma->prot_mask);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
vm_flags_clear(vma, calc_vm_may_flags(~asma->prot_mask));
#else
vma->vm_flags &= ~calc_vm_may_flags(~asma->prot_mask);
#endif

if (!asma->file) {
char *name = ASHMEM_NAME_DEF;
Expand Down Expand Up @@ -490,6 +494,9 @@ ashmem_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
return lru_count;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0))
static struct shrinker *ashmem_shrinker;
#else
static struct shrinker ashmem_shrinker = {
.count_objects = ashmem_shrink_count,
.scan_objects = ashmem_shrink_scan,
Expand All @@ -499,6 +506,7 @@ static struct shrinker ashmem_shrinker = {
*/
.seeks = DEFAULT_SEEKS * 4,
};
#endif

static int set_prot_mask(struct ashmem_area *asma, unsigned long prot)
{
Expand Down Expand Up @@ -803,8 +811,13 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
.gfp_mask = GFP_KERNEL,
.nr_to_scan = LONG_MAX,
};
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0))
ret = ashmem_shrink_count(ashmem_shrinker, &sc);
ashmem_shrink_scan(ashmem_shrinker, &sc);
#else
ret = ashmem_shrink_count(&ashmem_shrinker, &sc);
ashmem_shrink_scan(&ashmem_shrinker, &sc);
#endif
}
break;
}
Expand Down Expand Up @@ -874,14 +887,32 @@ static int __init ashmem_init(void)
return ret;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0))
ashmem_shrinker = shrinker_alloc(0, "android-ashmem");
if (ashmem_shrinker) {
ashmem_shrinker->count_objects = ashmem_shrink_count;
ashmem_shrinker->scan_objects = ashmem_shrink_scan;
ashmem_shrinker->seeks = DEFAULT_SEEKS * 4;
shrinker_register(ashmem_shrinker);
} else {
return -ENOMEM;
}
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0))
register_shrinker(&ashmem_shrinker, "android-ashmem");
#else
register_shrinker(&ashmem_shrinker);
#endif

return 0;
}

static void __exit ashmem_exit(void)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0))
shrinker_free(ashmem_shrinker);
#else
unregister_shrinker(&ashmem_shrinker);
#endif

misc_deregister(&ashmem_misc);

Expand Down
60 changes: 59 additions & 1 deletion ashmem/deps.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,69 @@
#include <linux/mm.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>
#include <linux/version.h>

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0))

#ifndef CONFIG_KPROBES
# error "Your kernel does not support KProbes, but this is required to compile ashmem as a kernel module on kernel 5.7 and later"
#endif

typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);

static int dummy_kprobe_handler(struct kprobe *p, struct pt_regs *regs)
{
return 0;
}

Comment on lines +14 to +18

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not need, just delete the initialization of pre_handler.

static kallsyms_lookup_name_t get_kallsyms_lookup_name_ptr(void)
{
struct kprobe probe;
int ret;
kallsyms_lookup_name_t addr;

memset(&probe, 0, sizeof(probe));
probe.pre_handler = dummy_kprobe_handler;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

probe.symbol_name = "kallsyms_lookup_name";
ret = register_kprobe(&probe);
if (ret)
return NULL;
addr = (kallsyms_lookup_name_t) probe.addr;
unregister_kprobe(&probe);

return addr;
}
#endif

/*
* On kernel 5.7 and later, kallsyms_lookup_name() can no longer be called from a kernel
* module for reasons described here: https://lwn.net/Articles/813350/
* As ashmem really needs to use kallsysms_lookup_name() to access some kernel
* functions that otherwise wouldn't be accessible, KProbes are used on later
* kernels to get the address of kallsysms_lookup_name(). The function is
* afterwards used just as before. This is a very dirty hack though and the much
* better solution would be if all the functions that are currently resolved
* with kallsysms_lookup_name() would get an EXPORT_SYMBOL() annotation to
* make them directly accessible to kernel modules.
*/
static unsigned long kallsyms_lookup_name_wrapper(const char *name)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0))
static kallsyms_lookup_name_t func_ptr = NULL;
if (!func_ptr)
func_ptr = get_kallsyms_lookup_name_ptr();

return func_ptr(name);
#else
return kallsyms_lookup_name(name);
#endif
}

static int (*shmem_zero_setup_ptr)(struct vm_area_struct *) = NULL;

int shmem_zero_setup(struct vm_area_struct *vma)
{
if (!shmem_zero_setup_ptr)
shmem_zero_setup_ptr = kallsyms_lookup_name("shmem_zero_setup");
shmem_zero_setup_ptr = kallsyms_lookup_name_wrapper("shmem_zero_setup");
return shmem_zero_setup_ptr(vma);
}
6 changes: 3 additions & 3 deletions binder/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ccflags-y += -I$(src) -Wno-int-conversion -DCONFIG_ANDROID_BINDER_DEVICES="\"binder\""
ccflags-y += -I$(src) -Wno-int-conversion -DCONFIG_ANDROID_BINDER_DEVICES="\"binder\"" -DCONFIG_ANDROID_BINDERFS="y"
obj-m := binder_linux.o
binder_linux-y := deps.o binder.o
binder_linux-y := deps.o binder.o binder_alloc.o binderfs.o

KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build

Expand All @@ -11,4 +11,4 @@ install:
cp binder_linux.ko $(DESTDIR)/

clean:
rm -rf deps.h *.o *.ko *.mod.c *.symvers *.order .*.cmd .tmp_versions
rm -rf *.o *.ko *.mod.c *.symvers *.order .*.cmd .tmp_versions
Loading