I want witch /dev/i2c-1 device to be outside the SELinux security policy on Android 10.
I have the source code for Android 10. I tried creating a .te file in /device/thales/mt8768q/sepolicy/edgelab.te
In foo.te, I added a similar example to the site: https://source.android.com/security/selinux/customize.
allow domain i2c-1_device:chr_file rw_file_perms
But, in compilation, this line generates an error.
UPDATE:
I add new line on /device/manufacturer/device-name/BoardConfig.mk:
BOARD_SEPOLICY_DIRS += device/thales/mt8768q/sepolicy
The error is:
#line 206
device/mediatek/mt6765/sepolicy/bsp/mnld.te:8:ERROR 'syntax error' at token 'role' on line 97225:
#line 2 "device/thales/mt8768q/sepolicy/edgelab.te"
allow domain i2c-1_device:chr_file { { getattr open read ioctl lock map } { open append write lock map } }role r;
checkpolicy: error(s) encountered while parsing configuration
Maybe i2c-1_device is not a valid name, but I don't know how to refer to /dev/i2c-1 in .te file.
Your should define your domain and label.
Define your dev_type (device/"manufacturer"/"device-name"/sepolicy/"your-filename".te):
type i2c-1_device, dev_type;
Label file with your type (device/"manufacturer"/"device-name"/sepolicy/file_contexts):
/dev/i2c-1/* u:object_r:i2c-1_device:s0
Define your rule (device/"manufacturer"/"device-name"/"your-filename".te):
allow domain i2c-1_device:chr_file rw_file_perms
You'd better define your domain and restrict only your domain can access i2c-1_device. The example define an dhcp domain, it's an good example.
Related
Hi I am adding my koushikservice in aospCodebase/frameworks/base/services/java/com/android/server/SystemServer.java like this
KoushikService koushikservice = null;
try{
traceBeginAndSlog("KOUSHIK_SERVICE adding trace");
koushikservice = new KoushikService(mSystemContext);
ServiceManager.addService(Context.KOUSHIK_SERVICE,koushikservice);
}catch(Throwable e){
Slog.e(TAG, "Starting KOUSHIK_SERVICE failed!!! ", e);
}
traceEnd();
I am getting "KOUSHIK_SERVICE adding trace" log but then getting avc denied. Please let me know if you need further info.
You need to add SELinux rules to allow that service. By default SELinux is deny unless explicitly allowed.
Your easiest way forward to do this would be to compare to an existing service and rules for that.
Otherise based on what I added for a service on my case, and assuming that value of Context.KOUSHIK_SERVICE = "koushik" here's roughly what should be added :
File: koushik.te
type koushik, domain;
In file service_contexts, add:
koushik u:object_r:koushik_service:s0
In file service.te add:
type koushik_service, service_manager_type;
In file system_server.te, add:
add_service(system_server,koushik_service)
Lastly, if you want to allow a domain to find and use your service, for example from platform_app, you add in platform_app.te:
allow platform_app koushik_service:service_manager find;
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'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.
I'm implementing schema validation using libxml2. The schema I'm validating against imports two other schemas with lines like:
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.somewebsite.com/xsd/xml.xsd"/>
All three schema files are located in the same directory on the device.
This works well when the device has internet access, but fails when it does not, as libxml2 still attempts to download the imported schemas from the schemaLocation even though I'm passing in XML_PARSE_NONET.
I tried getting libxml2 to load the files locally by editing the schemaLocation attribute to xml.xsd, ./xml.xsd, and file:///data/data/com.company.appname/files/xml.xsd, but all three resulted in the same libxml2 error:
domain: 16
code: 3069 (XML_SCHEMAP_INTERNAL)
message: Internal error: xmlSchemaParse, An internal error occurred.
I also tried removing the schemaLocation attribute entirely, on the off-chance that libxml2 might search for the imported schemas alongside the original schema, but that resulted in the following error when the schema parser hit a line that referenced the imported entities:
<xs:attribute ref="xml:lang" use="required"/>
domain: 16
code: 3004 (XML_SCHEMAP_SRC_RESOLVE)
message: attribute use (unknown), attribute 'ref': The QName value '{http://www.w3.org/XML/1998/namespace}lang' does not resolve to a(n) attribute declaration.
I also looked into manually merging the three schemas into a single file, but as they use different namespaces, this is not possible.
The standard solution for this seems to be the XML catalog, but I've read through libxml2's catalog documentation, and I can't figure out how (or even whether it's possible) to add mappings that will be used by my app when deployed to a device. I think I might need to implement an xmlExternalEntityLoader, but the documentation for that is quite slim.
How can I get libxml2 to import these schemas without network access? Obviously I'd ideally like a robust solution that works with the unedited schema, but I've be content with something quick-and-dirty that involves editing the schema, like my original attempts described above.
The errors described above are from an Android device (using JNI), but I'm having similar problems on iOS, where the solution will also need to work.
One way to do this is to intercept libxml2's call to open the imported URL with a custom xmlExternalEntityLoader.
The basic code for doing this is as follows:
#include <libxml/xmlIO.h>
#include <libxml/parserinternals.h>
xmlExternalEntityLoader defaultLoader = NULL;
xmlParserInputPtr
xmlMyExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret;
const char *fileID = NULL;
/* lookup for the fileID
* The documentation suggests using the ID, but for me this was
* always NULL so I had to lookup by URL instead.
*/
ret = xmlNewInputFromFile(ctxt, fileID);
if (ret != NULL)
return(ret);
if (defaultLoader != NULL)
ret = defaultLoader(URL, ID, ctxt);
return(ret);
}
int main(..) {
...
/*
* Install our own entity loader
*/
defaultLoader = xmlGetExternalEntityLoader();
xmlSetExternalEntityLoader(xmlMyExternalEntityLoader);
...
}
(Slightly adjusted from the sample code in The entities loader section of libxml2's I/O Interfaces documentation.)