init warning: Service myservice needs a SELinux domain defined. Please fix - android

I want to excute an executable on boot On a target board with Android 5.1 so I add this in init.rc:
on boot
start myservice
service myservice /system/bin/myservice
#class main
user root
group root
#oneshot
I did the unpack and repack job.
When changes are made, however, the screen keeps printing:
init warning: Service myservice needs a SELinux domain defined. Please fix.
type=1400 ... avc:denied ... scontext ... tcontext ... #some annoying warning messages like this
SELinux seems a huge project for me. I just want to avoid that. I tried two approaches:
1. setenv kernelargs 'console=ttyS0,115200n8 rootdelay=1 selinux=0' and saveenv
2. set enforce 0
For method 1, printenv gives the result:
kernelargs=console=ttyS0,115200n8 rootdelay=1 selinux=0
So you see, changes have been made. But the warning messages keeps printing after rebooting.
For method 2, it says:
Could not set enforce status. Permission denied.
So now I'm trapped in the dilema have no idea where to go. My questions:
Anyone knows how to disable or set permissive mode in android?
Which files should I modify if I want to define domain for the new service?
Besides, ls -Z /system/bin/myservice gives this:
u:object_r:system_file:s0

you need su to set permissive mode. Or you need source code to disable SELinux, such as disable SELinux in kernel config, or disable SELinux in BOARD_KERNEL_CMDLINE in device/vendor_name/product_name/BoardConfig.mk.
if you have the source code, you can define the new domain as you wish.
Please refer to the Android official documents: https://source.android.com/security/selinux/device-policy
section: Label new services and address denials

You have to add the seclabel attribute to the service in your init.rc file, but I don't know if your context will work. I just implemented it myself with the init_exec context:
$ grep yourservice system/sepolicy/file_contexts
/system/bin/vpd u:object_r:init_exec:s0
$ ls -Z path/to/system/bin/yourservice
u:object_r:init_exec:s0 path/to/system/bin/yourservice
$ grep yourservice device/brand/product/init.rc -A 5
service yourservice /system/bin/yourservice
seclabel u:r:init:s0
user root
group root
oneshot
Disabling SELinux on Android isn't hard and there are many threads treating the question. Just add either one of the following to your kernel command line parameters (i.e bootargs in U-Boot):
androidboot.selinux=permissive
androidboot.selinux=disabled

Run into a very similar problem myself, and here's what I've found:
When you run ls -Z /system/bin/myservice and get this:
u:object_r:system_file:s0
it means that your file is in the system_file domain. Now that's not good, as system files are not supposed to be executed, or at last not during init (you may still be able to execute it later from terminal the usual way).
In my case I was lucky, 'cause I was replacing an existing system service with a customised one that I've compiled from source. This means I was able to check the security context of the original file I was replacing and that was from ls -Z /system/bin/myservice.bak :
u:object_r:myservice_exec:s0
So I updated my new file to the same using chcon u:object_r:myservice_exec:s0 /system/bin/myservice
After that it was working fine.
If you want to create a brand new service you may need to use a domain that exists in your sepolicies already, as simply setting it to myservice_exec, won't help, as that would be a non-existing domain in your case.
If I were in your shoes and wanted to avoid defining custom policy I might try to find a service with similar security, check the domain on that and try to set the same to my service. init_exec may be a good candidate, but your mileage may vary...

Related

How to give an Android app its own SE (Android) context

We roll our own Android dist. We'd like to give some non-system apps heightened privileges.
I understand using the typebounds rule I can create a new type that is bounded by some other type. So I did like:
typebounds system_app my_app;
To give my_app the same access control as system_app. Later I can add rules to deny my_app certain things but that's not my immediate concern.
What I'm unclear about is how to define the type my_app and associate it with a particular app. I found some examples that looked like this,
user=system seinfo=platform name=com.qualcomm.qti.auth.fidocryptoservice domain=qsee_svc_app type=qsee_svc_app_data_file
So in my case I tried this:
user=_app seinfo=platform name=com.myapp type=my_app domain=my_app levelFrom=user
but after boot, ps -aZ still shows my app (com.myapp) running in the context untrusted app:
u:r:untrusted_app:s0:c512,c768 u0_a93 4154 2339 1726288 68944 SyS_epoll_ 7f99f257b8 S com.myapp
Why is this?

How would I stop something that was started by an app for itself without stopping the app?

Note: I'm fairly new to linux/android when it comes to using the shell and commands/scripting, so if I've given some unrelevant information, or I'm trying to do something not possible, please tell me what's not relevant and why something is not possible and explain anything else to help me become better at this.
I'm trying to make a script that stop's Orbot's Tor network automatically when I exit from the Orfox app. So far, I have most of the coding down except for the stopping part for Tor. I believe there is something I can use in a shell script that would stop the Tor network right?
Currently, my script uses the command
# am force-stop org.torproject.android
to stop the app (to stop the Tor network), but I know that can't be the only way...
I know that when I press the Start button (within the Orbot app) or open up Orfox, it starts up the Tor network... When using
# ps | grep torproject
2 times (before and after starting Tor), I found that
u0_a291 11209 1 23092 15712 sys_epoll_ b68ecf18 S /data/data/org.torproject.android/app_bin/tor
shows up only when Tor is on.
I also found that after using
# ps | grep u0_a291
(the same way as the last command) that two shell's are started:
u0_a291 11150 8783 3780 1336 pipe_wait b6d9d0ac S sh
u0_a291 11212 8783 3780 1340 pipe_wait b6dec0ac S sh
only when tor is on.
I'm assuming some of the commands running through one or both of the shell's will give me a hint as to what commands I may need in order to stop the tor network in my script, but I have no idea how to view them or if I can. Is there a way to view them, or maybe I'm going about trying to find out how to stop Tor in the wrong way? So help me out guys, please.
I figured out what it was after all, and I didn't need any of the information that I provided... facepalm
I found out what the service and intent action I needed by looking at the base.apk (in /data/app/org.torproject.android) as an archive. I looked at the AndroidManifest.xml like a text file and found the service and it's intent action to be
.service.TorService
org.torproject.android.intent.action.Start
I concluded my script by using this to stop the tor service... I bet this might help someone else out in the future.
# am stopservice -n org.torproject.android/.service.TorService -a org.torproject.android.intent.action.START

SELinux policy definition for Android system service: how to setup?

I had earlier written a standalone daemon to access a custom device (/dev/mydev0). Looking at AOSP source, I figured I needed setup policies in following files to make it work:
new file device.te containing:
type mydev_device, dev_type;
new file mydevsrvc.te containing
# service flash_recovery in init.rc
type mydevsrvc_type, domain;
type mydevsrvc_type_exec, exec_type, file_type;
init_daemon_domain(mydevsrvc_type)
allow mydevsrvc_type mydev_device:chr_file rw_file_perms;
edited file_contexts to add:
/dev/mydev[0-9]* u:object_r:mydev_device:s0
edited service_contexts to add:
mydevsrvc u:object_r:mydevsrvc_type:s0
And started the daemon by editing init.flo.rc to include these lines:
service mydevsrvc /system/bin/mydevsrvc
class main
user system
group system
seclabel u:r:mydevsrvc_type:s0
oneshot
Now, I need to access the device in android apps, so I must change the daemon into an android system service.
I can startup the service (thread) using BOOT_COMPLETED intent as explained in a previous question
I am not able to figure out how to setup SELinux policies so that this java service is also able to access the dev file.
[Update] I have continued using privileged daemon for this purpose. My java service connects to daemon through sockets. I don't have a better solution.
I finally figured out the answer. Posting it here, because there sure will be SEPolicy noobs like me looking for similar answers.
For this work, I needed to be able to access my device file from my java app that implements my service.
I needed to add following rule in my sepolicy directory, in a new file:
allow system_app mydev_device:chr_file rw_file_perms;
Also, needed to make my service app run in system_app domain. For this, I need to:
Install in priv_app during Android build.
Sign it with platform key
Declare shared user id in manifest: android.uid.system. I found that without this, app runs in platform-app domain and wasn't able to access my device file even with corresponding change in SEPolicy rule. Not sure why though, I didn't bother to debug.
It might also be possible to run my Service app in mydevsrvc_type domain. I didn't find out how to do that, or whether that will work.
Here is a brief summary of the steps needed to implement SELinux on your Android device:
Add SELinux support in the kernel and configuration.
Grant each service (process or daemon) started from init its own domain.
Identify these services by:
Reviewing the init..rc file and finding all services.
Examining warnings of the form init: Warning! Service name needs a SELinux domain defined; please fix! in dmesg output.
Checking ps -Z | grep init output to see which services are running in the init domain.
Label all new processes, drivers, sockets, etc. All objects need to be labeled properly to ensure they interact properly with the policies you apply. See the labels used in AOSP for examples to follow in label name creation.
Institute security policies that fully cover all labels and restrict permissions to their absolute minimum.
Ideally, OEMs start with the policies in the AOSP and then build upon them for their own customizations.
for more https://source.android.com/security/selinux/implement.html
In response of your question to start service from init rc
you can just write one rc file like below. Where it will start your service on receiving of boot_completed
on property:sys.boot_completed=1
start mydevsrvc
for reference http://androidxref.com/9.0.0_r3/xref/device/generic/qemu/init.ranchu.rc#60
Possibly add a line in your ueventd.rc file or project specific to give the permission

How can I get root permissions through the Android SDK?

I'm learning Android programming, and I want to make an application which has to run as root. The logical thing would be to add a root permission in the Android Manifest.
I saw this link in the documentation, and especially noted the FACTORY_TEST permission:
public static final String FACTORY_TEST
Since: API Level 1
Run as a manufacturer test
application, running as the root user.
Only available when the device is
running in manufacturer test mode.
Constant Value:
"android.permission.FACTORY_TEST"
Is that the best way?
If it's not possible using the SDK, how can I make a "root" application work?
What you need to do is something like:
Process root = Runtime.getRuntime().exec("su");
That causes SuperUser to show, which lets you either Allow or Block it from root access. This approach might not work if the user is not rooted. Here is a way you can test it.
First lets us get the basics right. Android run Linux kernel underneath. Now if you have to run your process on it with super user privileges(run it as root) the only way is to execute your process is via command line because it is the only way you can directly interact with the kernel. Also you need to use su before running any command. Also as Chris has mentioned in his comment on the 1st answer
Process process = Runtime.getRuntime().exec("su");
will accomplish nearly nothing. It will just ask for super use privilege using dialog. What you can do is instead of just executing su you can execute your process with su as following
Process process = Runtime.getRuntime().exec(new String[] { "su", "-c", yourCommand});
The -c Option
Among the most commonly used of su's few options is -c, which tells su to execute the command that directly follows it on the same line. Such command is executed as the new user, and then the terminal window or console from which su was run immediately returns to the account of the former user after the command has completed execution or after any program that it has launched has been closed.(More details)
Alternate Option
Alternative to above method one another way that might work is to use command line to copy you app to /system/app/ directory. Then your application will run automatically with root privileges(same as System apps)
The SDK does not offer a way to run an app as root.

Issue running a script from init.rc on device boot up

I am trying to run a shell script, which copies a file to a specific location, on phone power up and I added the following to my init.rc file:
service test_copy /system/bin/sh /system/bin/test_copy.sh
class pre-zygote_services
oneshot
user system
group system
When the service name (test_copy) is same as the script name, test_copy in this case, it doesn't execute the script but if I change the service name to a different one, like start_test_copy, it works. I am just eager to know the reason on why when service name is same as script name it doesn't work or am I wrong?
Try this one in your init.rc:
service test_copy /system/bin/test_copy.sh
user root
oneshot
Your test_copy.sh script must begin with:
#!/system/bin/sh
Always make sure use a different name for your service which Android init recommends.
Also, you can make your test_copy.sh into the executable by defining the Android Make file.

Categories

Resources