As part of a training course I need to declare a service in AOSP and call it at boot. The thing is the training is outdated, I'm working on a physical machine and the project is different.
Specs:
Android Version: 12
Android SDK: 31
Anyway I've built a module in C called "exd", it's stored in /system/bin/ and it works properly when called manually. Next I want to declare it as a service.
I've added to init.product.rc file:
service exd /system/bin/exd
oneshot
on boot
start exd
But when I build and download it to the device, service list doesn't display it. And it doesn't start on boot.
Next I've added exd.te file to sepolicy folder:
type exd, domain;
type exd_exec, domain;
init_daemon_domain(exd)
And added this line to file_contexts:
/system/bin/exd u:object_r:exd_exec:s0
When I call build it fails with the following message:
Error while expanding policy
[ 39% 60/151] //system/sepolicy:sepolicy.recovery Compiling cil files for sepolicy.recovery [common]
FAILED: out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy
out/host/linux-x86/bin/secilc -m -M true -G -c 30 out/soong/.intermediates/system/sepolicy/recovery_sepolicy.cil/android_common/recovery_sepolicy.cil -o out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy_policy -f /dev/null && cp -f out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy_policy out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy && rm -f out/soong/.intermediates/system/sepolicy/sepolicy.recovery/android_common/sepolicy_policy # hash of input list: 187605db6ee3f7580bafd9adbd0101d2c2a0d02f423bb7efa74ee537c43d35ce
neverallow check failed at out/soong/.intermediates/system/sepolicy/recovery_sepolicy.cil/android_common/recovery_sepolicy.cil:8770 from system/sepolicy/public/domain.te:1240
(neverallow base_typeattr_197 domain (file (execute execute_no_trans entrypoint)))
<root>
allow at out/soong/.intermediates/system/sepolicy/recovery_sepolicy.cil/android_common/recovery_sepolicy.cil:28846
(allow init exd_exec (file (read getattr map execute open)))
<root>
allow at out/soong/.intermediates/system/sepolicy/recovery_sepolicy.cil/android_common/recovery_sepolicy.cil:28848
(allow exd exd_exec (file (read getattr map execute open entrypoint)))
Failed to generate binary
Failed to build policydb
10:35:34 ninja failed with: exit status 1
I've tried everything I've found on the internet to no avail. The weird thing is that there is another service called "bugreport" which is declared almost indetically as mine, but it is listed after "service list" command.
At this point even pointing a good direction would be great for me.
You are getting neverallow, which is basically Android saying you are trying to do something that is not allowed in the SEPolicy definition. You need to create a .te file that consists of SEPolicy rules for your service.
An example SEPolicy file can be as follows:
type myservice_exec, exec_type, file_type, system_file_type;
typeattribute myservice coredomain;
# myservice servicemanager and binder access
allow shell myservice:binder { call transfer };
allow servicemanager myservice:dir search;
allow servicemanager myservice:file { open read };
allow servicemanager myservice:process getattr;
allow myservice servicemanager:binder { call transfer};
allow myservice system_server:binder call;
init_daemon_domain(myservice)
Notice the second line. You are missing that and it is most probably why you are getting a neverallow problem.
Related
I'm writing Android Native programs and setting their SEPolicy
I want to know how to set the process context for non-init program, it seems that the domain transition doesn't work
I wrote 2 programs and put the built executable in /vendor/bin
One program, my_service is running as init daemon service;
While the other one, my_client is a non-init program, which has to be executed manually
These 2 programs use Binder IPC to communicate.
But I have trouble when trying to set the process context for my_client, which is a non-init program
For my_service, it's selinux context is set in mainly 2 files
my_service.te
file_context
# In file_context
/vendor/bin/my_service u:object_r:my_service_exec:s0
# In my_service.te
type my_service, domain;
type my_service_exec, exec_type, file_type, vendor_file_type;
init_daemon_domain(my_service)
And I also use seclabel in init.rc files
# In init.rc
service my_service /vendor/bin/my_service
class main
console
seclabel u:r:my_service:s0
I checked both file context and process context for my_service, and they're set as what I expected
For the SEPolicy of my_client, everything is similar to my_service except that it is not written in the init.rc file since it's not an init program
# In file_context
/vendor/bin/my_client u:object_r:my_client_exec:s0
# In my_client.te
type my_client, domain;
type my_client_exec, exec_type, file_type, vendor_file_type;
init_daemon_domain(my_client)
For my_client, however, only file context is set to my_client_exec
I tried to run my_client and viewed the process context:
> # Executing my_client manually
> /vendor/bin/my_client
> ps -AZ | grep my_client
> u:r:su:s0 root 5838 5514 5948 1688 0 0 R my_client
The process context is su, while I expected it to be my_client
Furthermore, I get information about init_daemon_domain(XX) in te_macros
I think that It will do domain transition: When init runs file with XX_exec context, it will transit its process context to XX!
So I change the rule to be :
# init_daemon_domain(my_client)
domain_auto_trans(su, my_client_exec, my_client);
But this violate some pre-defined policy.
By the way, the binder IPC between these 2 programs seems working.
What's confusing is that the following rules still works even the process context is not my_client ?
binder_call(my_client, my_service)
binder_call(my_service, my_service)
Is there any way to do domain transition for non-init program ?
Or I misunderstand anything about SEPolicy? Because all the resources I found are about setting SEPolicy for init program
I'm a beginner and I'm trying to understand the Kernel-Android interface.
In the system/core/init/init.c, the initial part has the following code.
if (!strcmp(basename(argv[0]), "ueventd"))
return ueventd_main(argc, argv);
if (!strcmp(basename(argv[0]), "watchdogd"))
return watchdogd_main(argc, argv);
This is followed by the parsing of the board specific init.rc files.
The ueventd_main parses the board specific uevent.rc files.
The watchdogd_main tries to set the timeout & then keeps writing an empty character to the /dev/watchdog in an infinite loop.
In the book 'Embedded Android' by Karim Yaghmour, it is mentioned as,
One of the first things init does is check whether it was invoked as
ueventd. init includes an implementation of the udev hotplug events
handler. Because this code is compiled within init’s own code, init
checks the command-line that was used to invoke it, and if it was
invoked through the /sbin/ueventd symbolic link to /init, then init
immediately runs as ueventd.
My questions are
1) I believe that the arguments to this main function are received from kernel bootcmd parameters "init=". Am I right?
2) Under what scenario one would invoke an init to be run only as ueventd or watchdogd?
3) What do they mean by symbolically linked to /init?
1) I believe that the arguments to this main function are received
from kernel bootcmd parameters "init=". Am I right?
No, not bootcmd arguments. argv[0] is the name of the executable being launched.
If you look at the Android.mk for init, you will see:
# Create symlinks.
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
Here you can see that two extra symbolic links are created, both pointing to init. These will be included in the final Android boot image in /sbin/
2) Under what scenario one would invoke an init to be run only as
ueventd or watchdogd?
In init.rc, you can see:
## Daemon processes to be run by init.
##
service ueventd /sbin/ueventd
class core
critical
seclabel u:r:ueventd:s0
shutdown critical
This is declaring the service ueventd and specifying a path to the ueventd path. So when the ueventd service is started, it will the the init executable but the argv[0] argument will be ueventd.
watchdogd is done the same way.
So it is the same executable called with three different names init, ueventd, or watchdogd. Depending on which name it is called with, one of three different code paths are executed (as in the code you referenced).
This is often done when different commands are substantially the same in implementation. On my Ubuntu system:
$ ls -l /usr/bin/unxz
lrwxrwxrwx 1 root root 2 Oct 3 11:04 /usr/bin/unxz -> xz
You can see that unxz is linked to xz
From the man page for xz: unxz is equivalent to xz --decompress.
So here, there was only one executable, but depending on which executable name is used to launch it, the behavior is different.
3) What do they mean by symbolically linked to /init?
Answered in previous two answers.
I currently work on an application with XposedBridge and I have a lot of questions. I will start with the simple ones.
How can I get the debug.log file?
I cannot find the debug.log file. I have tried the phone shell as well as two adb ways :
A. adb shell data/data/de.robv.android.xposed.installer/log/debug.log
B. adb shell "su -c 'cat data/data/de.robv.android.xposed.installer/log/debug.log'"
C. adb shell cat data/data/de.robv.android.xposed.installer/log/debug.log
adb says : " No such file or directory "
The phone shell can cd to /data and /data/data but not after. Cannot ls neither of the data's. Says access denied. So does adb when I try adb ls.
The phone, Moto E XT1023, is rooted. Despite, shell cannot read some directories. I have posted a question why here but no one seems to care to answer.
I had to go to ES File Explorer. Managed to get to /data. ES says folder empty. Managed to get to Emulator/0/de.robv.android.xposed.installer or something alike. There was a subdirectory called files. Inside was the installer. No debug.log.
Searched all directories with ES for debug.log. Nothing found.
Once I create the XposedBridge class in a separate file of the project and once I do whatever XposedBridge is supposed to do (override methods, insert code before and or after the methods, etcetera) the overridden methods or the methods with code run before and or after or the overridden data will continue to be overridden until the app exits. Is this true?
Is there any simple, yet powerful and comprehensive manual or reference or, the best, a tutorial?
Can I specify another directory for the debug.log.file?
In case I am able to make a directory \data\data manually, would this make the Xposed save debug.log there?
I am so happy I have managed to partially answer the first question which is not only related to XposedBridge but is a global root reach question for rooted phones, so I cannot even think of any other questions for now. I do not have a debug.log but I have error.log and I know how to read these. Here is how in case anyone is interested :
In order to be able to reed XposedBridge log files :
Go to the specialised Moto E adb ( may work with a standard one too ).
Type :
************
* adb root *
************
to ensure root access.
The Dollar Sign $ must appear as the sign before commands. $ means the adb shell environment has been entered.
After $, type :
******
* su *
******
The Sharp Sign # must appear as the sign before commands. # means root has been entered. Once root has been entered, there is a full access to the phone. Thus :
**************************************************
* cd /data/data/de.robv.android.xposed.installer *
**************************************************
can be executed and the directory /data/data/de.robv.android.xposed.installer will be entered.
Type :
******
* ls *
******
to see the contents of this directory.
In case error.log or debug.log files are there, type :
*****************
* cat error.log *
*****************
and or
*****************
* cat debug.log *
*****************
to view these files.
Type :
********
* exit *
********
to return to the safer $ prompt.
Type :
********
* exit *
********
to exit adb.
Note : adb root may not run while a project is developed. The rest works, though.
I still do not have any debug.log. May be the XposedBridge lines do not run. Will check with some simple method from the manual.
Here is what I have found out, though. I have created an empty text file called debug.log on the computer and transferred the file to the main root of the device, the /sdcard directory, themn copied the file to /data/data/de.robv.android.xposed.installer/log just to see what happens. Nothing happens. The file is empty.
Here is what I have found out which may be helpful:
COMMANDS TO READ THE LOG FILES :
adb shell
su
cd /data/data/de.robv.android.xposed.installer/log
cat error.log
USE cp SOURCE DESTINATION after su shell, the # prompt, to copy files from one
directory to another on the device.
IMPORTANT NOTES :
All Xposed classes must be put in xposed_init, otherwise Android Studio 1.2 reports them as never used.
In built.gradle, have :
/* SSB : Added manually so the gradle builds with the
XposedBridgeApi-54.jar which is in the app -> libs
but not to include the jar in the apk. */
dependencies {
provided fileTree(dir: 'libs', include: ['*.jar'])
}
THESE HAVE BEEN PUT MANUALLY.
Update : I have been able to clean the code and have managed to find why I do not have a debug.log. This is because the two XposedBridge classes I have ( one is initialisation of zygote and the other is the work file with hooks and replacements ) are not loaded. The error.log shows : Didn't find class " package ( strts without a com. ) NameOfThePackageWithoutComDot.NameOfTheExposedClass in the NameOfThePackageWithoutComDot-2.apk "
THIS IS SAID FOR THE TWO CLASSES.
Problem partially solved:
I have removed the string " package " from the xposed_init and this solved the problem. Thus, instead of :
package TheNameOfThePackage.TheNameOfTheClass
xposed_init contains :
TheNameOfThePackage.TheNameOfTheClass
without the word " package " in front of the names as Android Studio usually puts and requires.
Now, the custom class seems to load OK and XMain where zygote is init generates a novel.
Regardless, the custom class with the test code works OK. The debug.log file is generated. However, the application does not seem to write in the file and the debug.log only says :
d.xposed.installer/log/debug.log
inside.
how can i add files (add to source control) recursively using commandline in UCM Project.
last time i tried i've failed using the BaseClearcase's commandline ....
i use this command line:
clearfsimport -recurse -c [comment] [file location path] [vob path]
and then there was error message shown:
"must be in an activity UCM ..."
Rational ClearCase
- RCC v7.1.2
- Windows Server
please help.
thanks.
"must be in an activity UCM ..." (full message would be helpful) probably means that no activity has been set for the active view when trying to perform checkin/checkout/add to source control. You must set an activity first using the setactivity command.
See also https://www-01.ibm.com/support/knowledgecenter/#!/SSSH27_8.0.1/com.ibm.rational.clearcase.cc_ref.doc/topics/ct_setactivity.htm
I have just built Libgit2 (v0.20.0) for Android (target SDK version 18, debugging on a rooted device running Cyanogenmod 10.1.2, Android 4.2.2) and a simple function like getting the version number of Libgit2 works fine through the JNI. But when I use the git_clone function it stops right after the objects/info folder is created and returns this error:
Error -1 cloning repository - Failed to set permissions on '/storage/sdcard0/it/ptt/.git/objects/info': Operation not permitted
I have given the application the WRITE_EXTERNAL_STORAGE permission but I guess it still can't chmod unless owner of the file. When I use adb shell to check out the permission mode of the info folder I get:
d---rwxr-x system sdcard_rw 2014-05-15 09:31 info
And by using pwd.h functions I get the username that the c code (that is calling git_clone) is under to be u0_a92. How am I suppose to get pass this I suppose very Android related issue? Is there a simple way to stop Libgit2 from calling p_chmod or can I give it permissions to do so?
I ended up defining p_chmod as a method always returning true to get passed the error. In the bash script I use to build libgit2 I inserted the following lines that leaves the source files in an unmodified condition after building for android:
LIBGIT2_POSIX_PATH="$LIBGIT2_SOURCE_PATH/src/posix.h"
LIBGIT2_POSIX_BACKUP_PATH="$LIBGIT2_SOURCE_PATH/src/posix_original.h"
printf "#include \"always_success.h\"\nint always_success() { return 0; }" > "$LIBGIT2_SOURCE_PATH/src/always_success.c"
printf "int always_success();" > "$LIBGIT2_SOURCE_PATH/src/always_success.h"
cp $LIBGIT2_POSIX_PATH "$LIBGIT2_POSIX_BACKUP_PATH"
sed -i "s/^#define\sp_chmod(p, m).*$/#include \"always_success.h\"\n#define p_chmod(p, m) always_success()\nextern int always_success();\n/" $LIBGIT2_POSIX_PATH
# run the build process with cmake ...
# restore chmod manipulated source header
mv $LIBGIT2_POSIX_BACKUP_PATH $LIBGIT2_POSIX_PATH
There is probably a cleaner way to solve this but at least now I dont get that error anymore. Thanks to Carlos for his help!
UPDATE
Running adb shell mount | grep sdcard I could see that the sdcard which I am trying to clone the repository into uses the vfat file system which according to this forum thread doesn't support unix-style permissions.