SePolicy for Vendor to access device binder - android

The problem that i face is I have a vendor domain which is accessing hwservice manager, and when i compile for user build i get the following denial.
11-11 11:13:28.126 5228 5228 W vps : type=1400 audit(0.0:248): avc: denied { read write } for name="binder" dev="tmpfs" ino=11419 scontext=u:r:vpsd:s0 tcontext=u:object_r:binder_device:s0 tclass=chr_file permissive=0
After running audit2allow tool i get the suggestion to add policy like below.
allow vpsd binder_device:chr_file { ioctl open read write };
But as per the treble architecture its not allowed and build fails.
Error as below :
Compilation error.
neverallow check failed at out/target/product/titan_r1_base/obj/ETC/nonplat_sepolicy.cil_intermediates/nonplat_sepolicy.cil:2633
(neverallow base_typeattr_38_26_0 binder_device_26_0 (chr_file (ioctl read write getattr lock append open)))
<root>
allow at out/target/product/titan_r1_base/obj/ETC/nonplat_sepolicy.cil_intermediates/nonplat_sepolicy.cil:5998
(allow vpsd binder_device_26_0 (chr_file (read write)))
Can someone please advise me what to add policy for the above .
I have tried
allow vpsd hwbinder_device:chr_file { ioctl open read write };
and
allow vpsd vndbinder_device:chr_file { ioctl open read write };
Please suggest.

The new treble architecture aims to decouple vendor component's dependency on the framework. This in turn will allow to upgrade the framework without involving the vendor in the process (see Treble).
To achieve this, vendor components are restricted access to the framework binder, and should only use the vndbinder (vendor binder) to interact with other vendor components. Essentially, vendor components are expected not to interact directly with the framework.
On treble versions (8.0 +), the SE-Policy enforces this concept by defining 'coredomain' neverallow rules. Basically, most of the internal framework components and processes are associated with the coredomain attribute, while new vendor defined components are not associated with the coredomain attribute.
This means, that when you define a new type in your vendor SE-policy, this type will not be a coredomain, and will be restricted by neverallow rules.
Framework processes described in this section correspond to coredomain in sepolicies while vendor processes correspond to non-coredomain. For example, /dev/binder can be accessed only in coredomain and /dev/vndbinder can be accessed only in non-coredomain.
(Source: AOSP official documentation).
Concreatly, under the public domain.te file, you can see the neverallow rule that defines that only coredomain + appdomain can read/write the binder_device:
#On full TREBLE devices, only core components and apps can use Binder and servicemanager. Non-core domain apps need this because Android framework offers many of its services to apps as Binder services.
full_treble_only(` neverallow {
domain
-coredomain
-appdomain
-binder_in_vendor_violators # TODO(b/35870313): Remove once all violations are gone } binder_device:chr_file rw_file_perms;

Related

avc denied transition on deamon

i have a bespoke deamon i am adding to my android 8.1 source tree.
but i keep getting the error:
type=1400 audit(21.610:3): avc: denied { transition } for pid=217 comm="init" path="/system/bin/rfidmanagerd" dev="dm-1" ino=293 scontext=u:r:init:s0 tcontext=u:object_r:rfidmanager_exec:s0 tclass=process permissive=1
here is my rfidmanager.te file:
# RFID manager process
type rfidmanager, coredomain;
type rfidmanager_exec, exec_type, file_type;
init_daemon_domain(rfidmanager)
domain_auto_trans(init, rfidmanager_exec, rfidmanager)
# Access system/etc/rfid
allow rfidmanager sysfs:file rw_file_perms;
allow rfidmanager tmpfs:chr_file { read write };
allow rfidmanager sysfs:file write;
allow rfidmanager system_file:file r_file_perms;
# Access /data/misc/rfid.
allow rfidmanager misc_rfid_file:dir create_dir_perms;
allow rfidmanager misc_rfid_file:file create_file_perms;
allow rfidmanager misc_rfid_file:file rw_file_perms;
allow rfidmanager misc_rfid_file:file { read write setattr append unlink link rename };
allow rfidmanager misc_rfid_file:fifo_file { create open read write };
# Access /dev/circchar
allow rfidmanager rfidhal_device:chr_file r_file_perms;
allow rfidmanager rfidhal_device:chr_file { read write };
# Access serial ports
allow rfidmanager tty_device:chr_file r_file_perms;
here is my file_contexts:
/system/bin/rfidmanagerd u:object_r:rfidmanager_exec:s0
in my init.te file for the denial i have :
allow init rfidmanager_exec:process {transition};
the device needs to have SELinux on enforcing mode. and here is how i start my service in the init.rc file
service rfidmanagerd /system/bin/rfidmanagerd -c /system/etc/rfid/rfidmanagerd.conf
class core
seclabel u:object_r:rfidmanager_exec:s0
user root
group root system
oneshot
start rfidmanagerd
when i try and start the service manually i.e
su system
./system/bin/rfidmanagerd
it starts, but using ps -eZ i see the service is as follows:
u:r:su:s0 system 859 1 4524 360 poll_schedule_timeout 0 S rfidmanagerd
it should however be with the u:object_r:rfidmanager_exec:s0 as i have defined in my contexts.
it does not start automatically which is understandable via the SELinux denial error, however any combination of allow rules for this particular denial seem to be ignored.
when i try and do start rfidmanagerd (as root)in the terminal i get
[ 474.879385] init: starting service 'rfidmanagerd'...
[ 474.885868] init: property_set("ro.boottime.rfidmanagerd", "474879774055") failed: property already set
[ 474.915929] init: cannot execve('/system/bin/rfidmanagerd'): Permission denied
[ 474.925563] type=1400 audit(480.580:9): avc: denied { transition } for pid=998 comm="init" path="/system/bin/rfidmanagerd" dev="dm-1" ino=381 scontext=u:r:init:s0 tcontext=u:object_r:rfidmanager_exec:s0 tclass=process permissive=0
I understand the denial, but dont understand why my allow rule is not fixing this...
everything runs fine when i am in permissive mode, but as i said i cannot have it in permissive.
Any help would be greatly appreciated!
Thanks
UPDATE -- I HAVE HAD THIS MIGRATED FROM ANDROID ENTHUSIASTS TO STACKEXCHANGE BACK TO ANDROID ENTHUSIASTS - it keeps getting moved, can someone please help me!
for anyone who is having a similar issue....Android 8.1 needs the coredomain to not have a neverallow rule, when compiling the selinux!
However, this has some issues with selinux resolving the setexeccontext.
so the first line in my .te file should read -
type rfidmanager, coredomain, domain;
instead of just
type rfidmanager, coredomain;
i hope this helps anyone.
Hope this will help somebody to save time in future.
You should use this secable in service definition:
seclabel u:r:rfidmanager:s0

SELinux issue in Android 6

Im having an issue allowing an untrusted app in Android 6 to access the /dev/HSL1 serial interface. This is the error im getting:
[ 757.742286] type=1400 audit(156811.349:149): avc: denied { write } for pid=6422 comm="port_api.sample" name="ttyHSL1" dev="tmpfs" ino=7287 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:tty_device:s0 tclass=chr_file permissive=0
The file in question is /dev/ttyHSL1:
1|root#msm8909:/dev # ls -alZ ttyHSL1
crwxrwxrwx root root u:object_r:tty_device:s0 ttyHSL1
The external/sepolicy/untrusted_app.te has the following at the very end of the file:
allow untrusted_app tty_device:chr_file rw_file_perms;
allow untrusted_app device:dir r_dir_perms;
allow untrusted_app tty_device:chr_file write;
I would assume the rw_file_perms macro gives the rw access to the ttyHSL1 file, however its not so from the dmesg output (above). Also app fails with "You do not have r/w permissions on the serial port".
Additionally a snippet from global_macros:
#####################################
# Common groupings of permissions.
#
define(`x_file_perms', `{ getattr execute execute_no_trans }')
define(`r_file_perms', `{ getattr open read ioctl lock }')
define(`w_file_perms', `{ open append write }')
define(`rx_file_perms', `{ r_file_perms x_file_perms }')
define(`ra_file_perms', `{ r_file_perms append }')
define(`rw_file_perms', `{ r_file_perms w_file_perms }')
define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
define(`create_file_perms', `{ create rename setattr unlink rw_file_perms }')
Am I missing something very obvious here?
I have had a similiar issue and belief I have the solution to your problem.
Posting it here, even if your question is quiet old at this point so that others having the same problem may be helped.
The issue is that untrusted apps also have a MSL tag your avc error:
scontext=u:r:untrusted_app:s0:c512,c768
Notice that after the "normal" se-linux staff you have :c512,c768, this seems to be a MLS "tag".
Your untrusted_app.te/tty_device does not handle this - as usual in SELinux by default the app is not allowed to access objects, even though the rest of the rule is ok.
You have three options at this point:
Write rules which allows MLS tagged subjects to your device
Write rules which targets your app and strips the MLS tag
Write rules which leaves the MLS tag but allows access to the device. (Probably the most secure)
I went the first (1) way and added two files under device/manufacturer/device/sepolicy:
file_contexts
/dev/ttyHSL1 u:object_r:arendi_device:s0
serialports.te
type arendi_device, dev_type, mlstrustedobject;
allow untrusted_app_all arendi_device:chr_file rw_file_perms;
Notice the mlstrustedobject tag - this tells SEAndroid that it should ignore MLS tags from subjects wanting access to this label.
There's also mlstrustedsubject which you could add to your app by rules.
My BoardConfig.mk tells Android to look for these new files by adding this line:
BOARD_SEPOLICY_DIRS += device/manufacturer/device/sepolicy
This now allows me access to my serialport under Android Oreo 8.1.
This answer pointed me to this solution:
My custom selinux policies seem to be ignored by android system

Android Read file denied by SELinux

I recently tried to read a file /system/bin/debuggerd in Android.I can install app or use adb commands but this error:
Unfortunately I was denied by SELinux
[105336.331813] type=1400 audit(8732769.717:226): avc: denied { read } for pid=17773 comm="ServiceHandlerB" name="debuggerd" dev="dm-0" ino=279 scontext
=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:debuggerd_exec:s0 tclass=file permissive=0
I can't root this device by rule,so is it possible to read this file?
this troubles me for a whole day,thx for help.
If you can't 'root' the device, than no.
The details are as follows. debuggerd_exec file is declared as:
type debuggerd_exec, exec_type, file_type;
This means that a processes attempting to read the file would need read permission on either the type debuggerd_exec or on the attributes exec_type or file_type.
Using the current tip of AOSP master at the time of this reply and the lunch target aosp_x86_64-eng, we can see what "source domains" can actually read this file with the following sesearch command:
$ sesearch -A -t debuggerd_exec -c file -p read $OUT/root/sepolicy
allow debuggerd debuggerd_exec:file { read open getattr entrypoint execute };
allow debuggerd exec_type:file { read lock ioctl open getattr };
allow init debuggerd_exec:file { read getattr open execute };
allow perfprofd exec_type:file { read lock ioctl open getattr };
If you notice the source domains (the first thing after the allow), none of them are shell or untrusted_app. On non-rooted user builds, without an exploit, one can only run code in the untrusted_app or shell domains (that isn't exactly true, but the details are not really important).
Additionally, even if untrusted_app did have access, you need to be aware that MLS can sometimes prevent access even when sesearch shows that you have access. SE Linux on Android is using both Type Enforcement (allow rules) and MLS (mls_constrain rules) to provide isolation and sandbox reinforcement.

Why can't my Android app (has root privilege) access /dev/input?

My app aims the rooted Android devices, it has the root privilege and needs accessing the directory /dev/input, but why does it throw opendir failed, Permission denied even /dev/input has already been chmod to 777?
I use the code below to get the root privilege:
Process root = Runtime.getRuntime().exec("su");
And use the code below to change the permissions of /dev/input:
Shell.runCommand("chmod 777 /dev/input");
Both the two steps above are successful, but why can't it be accessed by my app still? From the searching, someone says the runtime permissions of an app is nothing to do with the permissions of the file in file system. What's the permissions system of Android runtime? How can I make the app be able to access /dev/input?
Addition:
My test environment is Android 5.1.1, main part of the code is:
jint Java_com_foo_funnyapp_Native_scanInputDevicesJNI(JNIEnv* env, jclass clazz)
{
const char *dirname = "/dev/input";
DIR *dir;
dir = opendir(dirname); // opendir failed, Permission denied
if(dir == NULL)
return -1;
......
return 0;
}
SELinux error from /prog/kmsg
<36>[19700411_05:32:43.957165]#0 type=1400 audit(8631163.939:1105): avc: denied { write } for pid=15706 comm="app_process64_o" name="system#framework#boot.art" dev="mmcblk0p43" ino=442379 scontext=u:r:shell:s0 tcontext=u:object_r:dalvikcache_data_file:s0 tclass=file permissive=0
<11>[19700411_05:32:44.118202]#0 init: untracked pid 15674 exited with status 0
<11>[19700411_05:32:44.202288]#0 init: untracked pid 15704 exited with status 224
<36>[19700411_05:32:44.225334]#0 type=1400 audit(8631164.209:1106): avc: denied { read } for pid=15734 comm="Thread-111" name="input" dev="tmpfs" ino=12525 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:input_device:s0 tclass=dir permissive=0
<36>[19700411_05:32:44.332135]#0 type=1400 audit(8631164.319:1107): avc: denied { write } for pid=15742 comm="app_process64_o" name="system#framework#boot.art" dev="mmcblk0p43" ino=442379 scontext=u:r:shell:s0 tcontext=u:object_r:dalvikcache_data_file:s0 tclass=file permissive=0
As was pointed out in comments, modern Android has many additional defensive layers besides Linux file permissions. One of them is SELinux.
Even with elevated privileges, working around SELinux is rather complex — it is designed specifically to prevent that. All Android SELinux settings are stored in a single file of modified sepolicy format. That file is a part of read-only system image, and patching it basically equals to rooting a device. Pretty much only people working on that are developers of Superuser apps, such as author of SuperSu or this one.
Instead of trying to overcome SELinux yourself, I recommend you to leverage whatever was already done by installed su app. For example, SuperSu runs commands, passed to it, in unrestricted SELinux context (see link to Chainfire's site above), essentially as if SELinux didn't exist for it. This allows you to overcome SELinux by running specialized binaries via su, which do the dirty job for you.
Sadly, there are very few public high-level APIs, available to such pure native binaries. You can use Linux kernel syscalls and some C library functions... and that is it. Fortunately, if all you want is opening a bunch of protected files, there is no need to move lots of logic in native helper binary. Instead you can use an "open server" library, such as this one:
Context context = ...
try (FileDescriptorFactory factory = FileDescriptorFactory.create(context);
ParcelFileDescriptor fd = factory.open("/dev/input", 2))
{
// the file descriptor is yours, as if you have gotten it by
// calling ParcelFileDescriptor#open
// You can use it from Java or pass to native code to read/write/ioctl on it
...
} catch (FactoryBrokenException oups) {
// most likely the root access being denied
...
} catch (IOException ioerr) {
...
}
Disclaimer: I am the author of linked library.
The concept of "open server" is pretty simple:
Normal Android app creates a Linux domain socket
Normal Android app launches binary via system "su"
The binary connects to the socket
The binary reads names of files written by app to the socket and opens them
The binary sends file descriptors of said files to app via the same socket (the technique also known as "file descriptor passing")
This neat trick is going to work as long as installed "su" app successfully overcomes SELinux and provides unrestricted context to commands being run via it. All modern ones I know about do.
EDIT: This answer has been written a while ago. The latest Android sepolicy format is no longer considered "modified", their changes has been successfully upstreamed (humorously leading to creation of yet another backward-incompatible sepolicy format). The library, linked above, still works fine in general, but it's functioning has been further restricted by modern SEAndroid policies, so you may be interested in it's new iteration. Due to the fact, that SELinux policies enforce additional checks on each individual read/write in addition to standard Unix checks during open, it might be wiser to use shared memory and Linux pipes to carefully work around the policy, rather then passing the original descriptors to caller.

insmod in android lollipop with SE Linux enforced

I am trying to perform insmod abc.ko with a few module params,
However these module params need to be dynamically computed. So I am launching an app /system/bin/my_app to compute these params and then perform insmod within my_app.
Issue:
When my_app is launched at bootup using init.hammerhead.rc script, it is unable to perform insmod and give following error
type=1400 audit(0.0.4): avc: denided {sys_module} for path="system/bin/my_app" dev="mmcblk0p25" ino=170 scontext=u:r:init:s0 tcontext=u:r:init.s0 tclass=file
How can i enable my_app to be able to insmod ?
Would appreciate any pointers to resolve this
The ability to insmod a module is linked with the permissions of the code running do_insmod(). In your case, the issue is that there is no policy described that allow your sw to access the module.
I am not expert in sepolicy but there is a why to generate the appropriate policy file from the logs : here is a good article about that : https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/Security-Enhanced_Linux-The-sepolicy-Suite-sepolicy_generate.html
Hope that helps.
Aymen.
Finally found a solution.
my_app should be given new policies which allow it to perform insmod.
[1] Create my_app.te in ///sepolicy/my_app.te
[2] Add the following policies to my_app.te .
type my_app, domain;
type my_app_exec, exec_type, file_type;
allow my_app self:capability sys_module;
allow my_app self:capability { setuid setgid };
allow my_app self:capability sys_admin;
allow my_app shell_exec:file rx_file_perms;;
init_daemon_domain(my_app)
permissive_or_unconfined(my_app)
[3] Add my_app.te to BOARD_SEPOLICY_UNION in BoardConfig.mk file.
[4] Add following to sepolicy/file_contexts
/system/bin/my_app u:object_r:my_app_exec:s0
For further info or issue : subscribe to seandroid-list-join#tycho.nsa.gov

Categories

Resources