I've been looking on SEAndroid, and i've been trying to understand how is a process domain given.
So far what i got is that in the init.rc file, under some of the services declaration, there is a token called seclabel:
service adbd /sbin/adbd --root_seclabel=u:r:su:s0
class core
socket adbd stream 660 system system
disabled
seclabel u:r:adbd:s0
Which later in init.c is being set by setexeccon to the context that was written:
if (svc->seclabel) {
if (is_selinux_enabled() > 0 && setexeccon(svc->seclabel) < 0) {
ERROR("cannot setexeccon('%s'): %s\n", svc->seclabel, strerror(errno));
_exit(127);
}
}
In the example above the domain will be adbd.
But i didnt get to find what happens when there is no seclabel token in the service declaration. The thing that happens in init.c is that it will not call setexeccon, Meaning.. keep the parents domain?
A call to:
ps -Z
in adb shell, which shows all the processes and their domains, shows otherwise.
For example, the servicemanager in init.rc:
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
but call to ps -Z shows:
u:r:servicemanager:s0 system 53 1 /system/bin/servicemanager
Whats going on?!
Ok, i looked at the code and finally got the answer!
The file: /external/sepolicy/seapp_contexts found on the root file system in the android image includes the following content:
isSystemServer=true domain=system_server
user=system domain=system_app type=system_app_data_file
user=bluetooth domain=bluetooth type=bluetooth_data_file
user=nfc domain=nfc type=nfc_data_file
user=radio domain=radio type=radio_data_file
user=shared_relro domain=shared_relro
user=shell domain=shell type=shell_data_file
user=_isolated domain=isolated_app levelFrom=user
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app domain=untrusted_app type=app_data_file levelFrom=user
This defines the security settings (outputs) for each process according to some inputs. We can see in this example in the first line:
If its the system server, its domain will be system_server
Or in the last line:
The _app keyword stands for every app which doesn't have a rule associated to it. So by default, applications domain will be untrusted_app and the files belongs to it label will be app_data_file.
More documentation on the syntax of the file is found inside the file.
Related
when i add a new service, and find the error as follow:
SELinux : avc: denied { add } for service=xxxManagerService pid=3798 uid=1000 scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0
then i add allow in system_server.te:
allow system_server default_android_service:service_manager { add };
but build error happened:
libsepol.report_failure: neverallow on line 517 of system/sepolicy/public/domain.te (or line 10355 of policy.conf) violated by allow system_server default_android_service:service_manager { add };
libsepol.check_assertions: 1 neverallow failures occurred
Error while expanding policy
out/host/linux-x86/bin/checkpolicy: loading policy configuration from out/target/product/sti6030d111/obj/ETC/sepolicy_neverallows_intermediates/policy.conf
[ 11% 22/200] target thumb C++: libpqcontrol <= vendor/amlogic/common/frameworks/services/systemcontrol/PQ/SSMAction.cpp
what should i do to make it, and pass cts.
Android comes with a long list of neverallow rules that make sure you don't give permissions which break the security of your device. Fortunately, these neverallow rules are well documented in the code. If you look up line 517 in system/sepolicy/public/domain.te you'll find this:
Do not allow service_manager add for default service labels.
Instead domains should use a more specific type such as
system_app_service rather than the generic type.
New service_types are defined in {,hw,vnd}service.te and new mappings
from service name to service_type are defined in {,hw,vnd}service_contexts.
You probably used the audit2allow to create the rule. This seems to be an easy solution at first, but it will almost always result in rule set that is hard to read. In the end there is no other way than understanding the basics of SELinux in Android.
See here for more information.
I cannot give you an example of what to do now as the things you need to do depend on the type of service you want to add.
Note: I am beginner in SELinux policy and followed vndservicemanager by Android
I have a java service(MyService) that starts on the BootComplete receiver.
Now i am adding myservice to ServiceManager in onCreate of MyService.java.
ServiceManager.addService(mysystemservice, mybinder);
As per treble architecture,
I moved my application to vendor image partition by adding below in Android.mk of application.
LOCAL_VENDOR_MODULE := true
I made below changes in OEM SELinux policy, earlier it was written for system service now as i moved application to vendor so made changes for vendor service, providing both old and current SE policy.
Created Context "my_service"
OLD
In private/service_contexts
mysystemservice u:object_r:my_service:s0
NOW
In vendor/common/vndservice_contexts
mysystemservice u:object_r:my_service:s0
Defined Service Type
OLD
In public/service.te
type my_service, service_manager_type;
NOW
In vendor/common/vndservice.te
type my_service, vndservice_manager_type;
Now giving add permission
OLD
In public/servicemanager.te
allow system_app my_service:service_manager add;
NOW
In abc.te
type abc, domain;
type abc_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(abc)
vndbinder_use(abc)
binder_call(abc, system_app)
add_service(abc, my_service)
allow abc my_service:service_manager find;
allow abc my_service:service_manager add;
After above changes and giving full build I can see my service context is part of out/product/target/vendor/etc/selinux/vndservice_contexts..inplace of out/product/target/system.
But once Myservice.java try to add "mysystemservice" in ServiceManager by
ServiceManager.addService(mysystemservice, mybinder);
I get below **avc denied ** error
E/SELinux: avc: denied { add } for service=mysystemservice pid=7588 uid=1000 scontext=u:r:system_app:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0
2019-11-14 12:44:39.613 592-592/? E/ServiceManager: add_service('mysystemservice',b0) uid=1000 - PERMISSION DENIED
As we can see in log above Target context is taking default "tcontext=u:object_r:default_android_service:s0" inplace of "my_service"
Note: If i keep changes for system image everything works fine only issue is when i move SE policy changes to vendor.
Please let me know if i missed something or any other way is to add Service.
One problem I can see is that you are using abc.te, but you have not defined this in your seapp_context inside vendor/common/.
You should define something like below:
user=system
seinfo=platform
name=your.package.name
domain=adbc
type=system_app_data_file
After this change avc error will point to abc app domain.
I need to watch a directory on an android device(e.g /sdcard). I need to log any actions occurred at /sdcard. For example, if an app creates file or directory at /sdcard, I would like to log a name of application and event, that occurred, into a file.
I searched on google about the command to watch a directory. I found that I can use "inotifyd" command. I really do not know how I can use it. I don't find clear an example of how to use this command
Does anyone helps me to understand this command, how does work?
On my phone, inotifyd spits out this usage:
usage: inotifyd PROG FILE[:MASK] ...
When a filesystem event matching MASK occurs to a FILE, run PROG as:
PROG EVENTS FILE [DIRFILE]
If PROG is "-" events are sent to stdout.
This file is:
a accessed c modified e metadata change w closed (writable)
r opened D deleted M moved 0 closed (unwritable)
u unmounted o overflow x unwatchable
A file in this directory is:
m moved in y moved out n created d deleted
When x event happens for all FILEs, inotifyd exits (after waiting for PROG).
With some testing, I found this to works for me:
inotifyd - /sdcard/myfile.txt
This will then, for example, spit out e /sdcard/myfile.txt if I run touch /sdcard/myfile.txt.
If you want to log the changes to a file instead, you can use:
inotifyd - /sdcard/myfile.txt >/sdcard/changes.log 2>&1
To instead call a script when changes occur, you can use:
inotifyd myscript.sh /sdcard/myfile.txt
I would like to get an adb command with a response of a code that map to current call state
the call state I mean are those in following link
https://developer.android.com/reference/android/telecom/Call.html#STATE_ACTIVE
those values are more representative and getting those values in command shell upon executing the adb command will be very helpful for me
I have only managed to get them on a log as per following command
adb logcat -d | findstr -i InCallFragment.setCallState
but I couldnot get the state value as a response of any adb command
Any help will be much appreciated
Thanks
for more illustration
please connect a phone to the PC , do a phone call and end it
use the above command to dump the buffer
refer to the state value
You can use adb shell service call telecom [code] command. The codes for getCallState() will be different depending on the Android version:
6.0.1: 26
7.0.0: 27
7.1.0: 27
7.1.2: 27
8.0.0: 29
8.1.0: 29
I have achieved what you want to do by modifying a custom ROM (LineageOS) and adding an android.util.Log line to print every state.
In my case I modified class:
Call
frameworks/opt/telephony/src/java/com/android/internal/telephony/Call.java
And what I did is inside getState(...) method, adding this line:
Log.i(myTAG, "getState state->" + mState.name());
With this what I have to do is search for myTAG in adb logcat.
I think otherwise you wont be able to do it...
You can dumpsys telecomm service:
adb shell dumpsys telecom
CallsManager:
mCalls:
[TC#7, ACTIVE, com.android.phone/com.android.services.telephony.TelephonyConnectionService, tel:***, A, childs(0), has_parent(false), [Capabilities: CAPABILITY_HOLD CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO], [Properties:]]
mCallAudioManager:
All calls:
TC#7
Active dialing, or connecting calls:
TC#7
Ringing calls:
Holding calls:
Foreground call:
[TC#7, ACTIVE, com.android.phone/com.android.services.telephony.TelephonyConnectionService, tel:***, A, childs(0), has_parent(false), [Capabilities: CAPABILITY_HOLD CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO], [Properties:]]
mTtyManager:
mCurrentTtyMode: 0
mInCallController:
mInCallServices (InCalls registered):
.
.
Call TC#7 [2018-06-05 14:38:41.505](MO - outgoing)
To address: tel:***
14:38:41.508 - CREATED:PCR.oR#DMA
14:38:41.511 - SET_CONNECTING (ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, [8c3d1caa626a79d75b154221ea94852a62fee7b3], UserHandle{0}):PCR.oR#DMA
14:38:41.847 - AUDIO_ROUTE (Leaving state QuiescentEarpieceRoute):PCR.oR->CAMSM.pM_2001->CARSM.pM_SWITCH_FOCUS#DMA_2_2
14:38:41.847 - AUDIO_ROUTE (Entering state ActiveEarpieceRoute):PCR.oR->CAMSM.pM_2001->CARSM.pM_SWITCH_FOCUS#DMA_2_2
14:38:43.442 - BIND_CS (ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}):NOCBIR.oR#DMU
14:38:43.519 - CS_BOUND (ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}):SBC.oSC#DMY
14:38:43.519 - START_CONNECTION (tel:***):SBC.oSC#DMY
14:38:43.703 - CAPABILITY_CHANGE (Current: [[ sup_hld mut !v2a]], Removed [[]], Added [[ sup_hld mut !v2a]]):CSW.hCCC#DMg
14:38:43.706 - SET_DIALING (successful outgoing call):CSW.hCCC#DMg
14:38:47.560 - SET_ACTIVE (active set explicitly):CSW.sA#DNM
14:38:47.639 - CAPABILITY_CHANGE (Current: [[ hld sup_hld mut !v2a]], Removed [[]], Added [[ hld]]):CSW.sCC#DNY
Timings (average for this call, milliseconds):
bind_cs: 77.00
outgoing_time_to_dialing: 187.00
I'm studying the android kernel as a beginner. I can read the messages thrown from the macro ERROR() inside the function main() at system/core/init/init.c using dmesg command through adb. I observed that after calling the function open_devnull_stdio() inside main(), dmesg no longer displays the messages thrown by ERROR().
To find the reason, I started digging into the declaration of open_devnull_stdio() inside system/core/init/util.c and I found this line I can't understand
static const char *name = "/dev/__null__";
Actually there was no file named __null__ inside /dev/ in the device, but there was a file named null and I was able to grab it using adb pull and it was a 0 byte (empty) file.
So why is a file name wrapped with double underscore (__) ?
Here is the link for the util.c
There is no special purpose of using double underscore before the start, after the end or both in C. From the point of view of C the file name is just a string, the operating system is free to interpret in whatever way it chooses. From the point of view of Linux, the same applies. Underscores in file names are just characters. They are not treated differently from the letters b and t.
If I guessed right and I'm reading the same file as you (it might be a good idea to link to the source code you're reading) then it should be pretty obvious what the code does on the lines after the one you mentioned. The next lines are:
if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
fd = open(name, O_RDWR);
unlink(name);
Which creates the null device which is then opened and immediately deleted again.
I suspect this is done so that programs can run without access to the root filesystem and still be able to open the equivalent of /dev/null.
I don't know the answer but I have an idea:
The following page shows an "strace" output where /dev/__null__ is used:
https://gist.github.com/tetsu-koba/1522515
Under Linux device files have a 33-bit (?) number which identifies the device. (At least under old Linux versions) you could delete some file in /dev and you could restore it or even create it in another directory (!) when you know the 33-bit number! (So you can delete the device /dev/sda2 and create the device (not file!) /home/myuser/sda2 instead.)
The trace in the link above shows the following three lines:
mknod("/dev/__null__", S_IFCHR|0600, makedev(1, 3)) = 0
open("/dev/__null__", O_RDWR|O_LARGEFILE) = 3
unlink("/dev/__null__") = 0
These lines will create the device file /dev/__null__ (with the 33-bit number identifying /dev/null). Then it opens that file and then it removes the file again.
Maybe this is done because the tool shall be able to run both on Linux installations where the device file "/dev/null" is present (in this case the file should not be overwritten) and on installations where that file is missing (in this case a replacement file must be created using the known 33-bit number).
As other people have pointed out this just tells it's the "null device", not a regular file called "null". null is supposed to act like an information sink, not like a normal file where you dump your data to. Hope this helps.