
Making the camera work with SELinux set to “Enforcing” was the last part of my debugging process. Setting SELinux to “Enforcing” produced quite a few denial errors in the dmesg, but fixing all of them…
Making the camera work with SELinux set to “Enforcing” was the last part of my debugging process.
Setting SELinux to “Enforcing” produced quite a few denial errors in the dmesg, but fixing all of them with sepolicy-inject and chcon did not really make the camera work, or even start.
02-15 20:16:53.495 8722 8722 I PreviewReceived: type=1400 audit(0.0:287): avc: denied { open } for path="/dev/__properties__/u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=464 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=1 app=com.oplus.camera
02-15 20:16:53.495 8722 8722 I PreviewReceived: type=1400 audit(0.0:288): avc: denied { getattr } for path="/dev/__properties__/u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=464 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=1 app=com.oplus.camera
02-15 20:16:53.495 8722 8722 I PreviewReceived: type=1400 audit(0.0:289): avc: denied { map } for path="/dev/__properties__/u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=464 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=1 app=com.oplus.camera
and
06-10 00:05:59.224 1026 1026 E SELinux : avc: denied { find } for interface=vendor.qti.hardware.camera.postproc::IPostProcService sid=u:r:platform_app:s0:c512,c768 pid=8558 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:vendor_hal_camera_postproc_hwservice:s0 tclass=hwservice_manager permissive=0
06-10 00:05:59.264 0 0 E [T201019] SELinux: avc: denied { find } for pid=11375 uid=10184 name=oiface scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0
06-10 00:05:59.265 0 0 E [T201019] SELinux: avc: denied { find } for pid=11375 uid=10184 name=oiface scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0
audit2allow was always meeting “neverallow” failures, and all of this stuff is so terribly documented that I was almost in despair.
However, two ideas came to my mind.
The first one is that it does make a lot of sense to give the app process its own SELinux context (domain, label).
It took me a while to find out how to do that, as doing it in a naive way (just adding a type opluscamera_app and adding a line to seapp_contexts) was causing a boot-loop.
However, at the end of the day I did something, and this something satisfies me.
I added a type opluscamera_app, and literally copied the definition of this type from platform_app.te.
This made sure that my app has all the same permissions as a normal “platform app”, but is running at a different label, and I can filter the logs by this label.
It also meant that I can add permissions to this label, without interfering with the main SELinux policy.
The drawback is that I had to declare this type not in the camera module but in the main sepolicy module (so my could would not be taken upstream), and add exceptions to the neverallow rules, which I do not mind, as there is only a single app running as this label, mine, and I do not intend to upstream it anyway.
I had to add neverallow exceptions like this:
system/sepolicy:
diff --git a/private/app.te b/private/app.te
index e4ac05b9c..441fb1889 100644
--- a/private/app.te
+++ b/private/app.te
@@ -521,7 +521,7 @@ allow appdomain zygote_tmpfs:file { map read };
# Superuser capabilities.
# bluetooth requires net_admin and wake_alarm. network stack app requires net_admin.
-neverallow { appdomain -bluetooth -network_stack } self:capability_class_set *;
+neverallow { appdomain -bluetooth -network_stack -opluscamera_app } self:capability_class_set *;
# Block device access.
neverallow appdomain dev_type:blk_file { read write };
@@ -746,7 +746,7 @@ neverallow {
}:file no_x_file_perms;
# Don't allow apps access to any of the following character devices.
-neverallow appdomain {
+neverallow {appdomain -opluscamera_app} {
audio_device
camera_device
dm_device
@@ -758,6 +758,7 @@ neverallow appdomain {
# needs access to /dev/video* for interfacing with the host
neverallow {
appdomain
+ -opluscamera_app
-device_as_webcam
} video_device:chr_file { read write };
device/qcom/sepolicy_vndr/sm8550/:
diff --git a/generic/vendor/common/domain.te b/generic/vendor/common/domain.te
index 0f4f0539e..2e256d693 100644
--- a/generic/vendor/common/domain.te
+++ b/generic/vendor/common/domain.te
@@ -85,6 +85,7 @@ neverallow { domain
- hal_contexthub_default
- hal_sensors_default
- hal_camera_default
+- opluscamera_app
userdebug_or_eng(` -vendor_usta_app')
userdebug_or_eng(` -vendor_ustaservice_app')
userdebug_or_eng(` -vendor_sysmonapp_app_test')
@@ -111,6 +112,6 @@ neverallow { domain
userdebug_or_eng(` -vendor_sysmonapp_app_test')
} vendor_qdsp_device:chr_file *;
neverallow { domain -init -vendor_init - ueventd } vendor_qdsp_device:chr_file ~{r_file_perms};
-neverallow { appdomain - shell userdebug_or_eng(`-vendor_sysmonapp_app_test') } vendor_qdsp_device:chr_file ~{ioctl read};
+neverallow { appdomain - shell userdebug_or_eng(`-vendor_sysmonapp_app_test') -opluscamera_app } vendor_qdsp_device:chr_file ~{ioctl read};
neverallow mediacodec vendor_qdsp_device:chr_file ~{ioctl read};
This allowed me to study the behaviour of the camera app without interfering with the workings of the “platform_app” label.
Another revelation, and I cannot call it by anything else, came when I was painfully and hopelessly staring through these two documents:
The first one is written so badly that having it written in Swahili and read by a non-Swahili speaker would not hurt much. The second is just “the source”, you cannot expect much from it.
In any case, some of my SELinux denials were about vendor_hal_camera_postproc_hwservice, and none of the statements like hal_client_domain(opluscamera_app, hal_camera_postproc_hwservice), or hal_client_domain(opluscamera_app, hal_camera_postproc), or hal_hwclient_domain(opluscamera_app, hal_camera_postproc) were working.
Finally after spending a long time studying hardware/oplus/sepolicy/qti/vendor/, something clicked in my head and I wrote hal_client_domain(opluscamera_app, hal_camera).
This worked.
After looking once more at https://source.android.com/docs/core/architecture/aidl/aidl-hals#sepolicy , I decided that with a lot of mental gymnastics and imagination stretching, it is possible to see how the official document is claiming that this is actually what should be written, but, honestly, this approach to documentation is just horrible.
In any case, even though I had to add a type and edit the main tree, I am satisfied with this solution, because the app is running confined.
As a side-note, the camera app is actually requiring selinux_check_access(opluscamera_app), that is, its behaviour is different depending on whether SELinux is Enforcing, Permissive, or off.
Which is a bad coding practice.
I’m so confused by this submission. It’s not a guide but a collection of notes from someone (in china) customizing a oneplus build. There’s some useful info there but only if you’re already at a point where you’re comfortable running your own compiled full vanilla builds.
Go to https://wiki.lineageos.org if you want to install and/or compile for a phone.
I don't use lineage OS myself, but I thought the same as I read the first few sections of this article. This "guide", if anything will just confuse the less tech savvy users rather than help.
wiki.lineageos.org has specific install instructions for every phone/device they support, I have no idea why you would choose to follow anything else.
just as an example, for the Nintendo switch v2(devices built after the homebrew method was patched) can be found at:
https://wiki.lineageos.org/devices/nx_tab/install/variant2/
There's an install guide for almost every android capable device for the last decade on the wiki!
> wiki.lineageos.org has specific install instructions for every phone/device they support, I have no idea why you would choose to follow anything else.
Ironically, the Switch 2 page you linked on their wiki mentions a few different install methods and locations and goes on to say about one of those:
> if you wish to install Android to the eMMC, you will need to consult external resources
So it seems that there are indeed cases where you have to follow other things than the guides in the wiki, even for supported devices.
>Go to https://wiki.lineageos.org if you want to install and/or compile for a phone.
There are a lot of phones missing from there though.
None of the missing ones have proper, official, upstream LineageOS support. If you install LineageOS on these, you install somebody's own, personal fork of LineageOS. Which might be totally fine, of course. But because of the necessarily different signing keys alone, it's a (potentially) very different thing.
[flagged]
Seems like a typical blog post. Doesn't hurt to start with something like that, but they explicitly refuse to link to "official" site, stating it's garbage. Trash it all you want, but at least link to the trash so readers can judge for themselves, since the author is a self-proclaimed noob.
I personally had big problems doing an OTA update within LineageOS that required a factory reset afterwards. So yeah, don't do the OTA updates. Do full backups and full manual updates instead.
Another anecdote: I have not had problems with OTA updates.
> Android is one of the most popular operating systems in the world.
More accurately, "as of December 2025, Android, which uses the Linux kernel, is the world's most popular operating system with 38.94% of the global market, followed by Windows with 29.99%, iOS with 15.66%, macOS with 2.14%, and other operating systems with 10.78%."