✨ Discover this insightful post from Hacker News 📖
📂 **Category**:
📌 **What You’ll Learn**:
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 💬 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 🔥 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 ⚡ 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 ⚡ 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:
- https://source.android.com/docs/core/architecture/aidl/aidl-hals#sepolicy
- https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/master/public/te_macros
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.
{💬|⚡|🔥} **What’s your take?**
Share your thoughts in the comments below!
#️⃣ **#install #start #LineageOS #phone**
🕒 **Posted on**: 1772770578
🌟 **Want more?** Click here for more info! 🌟
