By Seth


2019-03-07 22:03:33 8 Comments

I am on a bootloader locked Sprint Samsung Galaxy S7, eng boot.img flashed to phone with SELinux permissive, which gives root adb shell from where I can change system partitions, debloat, install Xposed etc. But the kernel is very bad and has RAM leak, and eventually, the phone slows to a crawl. So I unrooted by installing the stock kernel and disabling DM verity to allow a modified system to boot up.

Now, SELinux is enforcing, but I want it to be permissive which will never happen with the stock kernel. I realize that secontext is defined at kernel build times and allows certain things to run.

Another option is to have a higher context to do things like supolicy --live to patch SELinux policy and get full root access with stock kernel. I'm trying to execute a script in the data directory created by my app, but unless seenforcing=false, it doesn't get executed.

I know by using root you can chcon a file/directory. So what is the (source) context that will allow to:

  • Set mode to permissive, or
  • Modify the SELinux policy, or
  • Execute a script on boot without avc denials

Or what is the (target) context that will allow any other (source) context to execute the script?

1 comments

@Irfan Latif 2019-03-23 22:02:43

ROOT USER AND SELINUX:

User root (with UID 0) is the super user in Discretionary Access Control (DAC) implementation of *NIX operating systems. DAC is allowed by-default i.e. anyone can access anything unless UIDs, GIDs and permission mode restrict something. So root can do anything because it's the kernel's SUPER USER who isn't denied anything.

SELinux is Mandatory Access Control (MAC) which is denied by-default i.e. no one can access anything unless a policy rule is defined to allow the access. So there is no SUPER CONTEXT which is allowed to do anything, whatever the UID is. You have to define a rule to allow any operation you want to perform on your device.

Please note that Access Controls (DAC or MAC) are enforced by kernel at back end, who is the actual operating system.

HOW SELINUX IS ENFORCED ON ANDROID?

SELinux policy rules are defined when building ROM and saved as a binary file /sepolicy (or as split-policy). This policy is loaded by init (the very first process started in kernel's SELinux domain) before starting any services/daemons/processes on boot. Kernel starts with SELinux permissive if built with option SECURITY_SELINUX_DEVELOP=y (which is the default as discussed here and here). After loading policy, init - when still running with kernel's context - sets SELinux enforcing (depending on ROM build type and kernel parameter androidboot.selinux (0)) and then switches to init's own context. From here afterwards, even init isn't allowed by policy to revert back to permissive mode (1, 2). Neither the policy can be modified even by root user (3).

However there is one exception to above said rules. On userdebug or eng builds, u:r:su:s0 - which is the context adb shell gets when adbd is run as root (4) or when /system/xbin/su is executed (5) - is allowed to do anything, including setting SELinux permissive (6).

But on a final production (user) build of ROM, the only way to setenforce 0 or to modify policy is to take control of booting process before SELinux is set enforcing by init. That's what rooting solutions like Magisk do by replacing/patching /init and /sepolicy in RAM disk (boot.img). Magisk runs root processes with context u:r:magisk:s0 which is allowed by patched policy to do anything.

Once you have rights (granted by DAC and MAC) to play with SELinux policy, you can define new SELinux policy rules as explained here.

Coming to your question:

selinux is enforcing but I want it to be permissive which will never happen with stock kernel

No. SELinux is set enforcing by init, not by kernel, except if built with SECURITY_SELINUX_ENFORCING=y option (7).

a higher context to do things like supolicy --live to patch selinux policy

There is no higher context that is allowed to do anything. You can't set mode to permissive and can't patch policy on user builds.

what is the (target) context that will allow any other (source) context to execute the script?

As said, there is no higher source context that can do anything to others. Likewise there is no lower target context that lets others do anything.
Also when executing a script, there isn't necessarily a single target context. Every file that the script uses (binaries, configurations, logs etc.) may have its different context label. And typetransitions can change source contexts too.
If you want to modify policy, you can get all avc denials from kernel log and then define new SELinux rules accordingly:

~# dmesg -w | grep avc:

Solution:

Since you are already on eng build, only replace kernel binary (zImage) in your boot.img if you want to replace kernel. Otherwise you get stuck by using init and sepolicy from boot.img of a user build.
On eng build:

  • /init doesn't set SELinux enforcing on boot (8)
  • /sepolicy allows root adb shell to do anything including setenforce and load_policy as explained above

If your kernel is built with SECURITY_SELINUX_ALWAYS_ENFORCE, you can't set SELinux permissive once set enforcing (9).

RELATED:

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] SELinux and chroot system call

1 Answered Questions

[SOLVED] How does SuperSu provide root privilege?

1 Answered Questions

Adding custom bootup script to Android-x86 Nougat

5 Answered Questions

[SOLVED] Examine android (v30) selinux policy

  • 2015-11-15 20:51:54
  • user3188445
  • 8116 View
  • 12 Score
  • 5 Answer
  • Tags:   selinux

1 Answered Questions

1 Answered Questions

[SOLVED] How SElinux protects android from rooting

Sponsored Content