Possible to run as unprivileged app with compatibility layer? #274

Closed
opened 2025-12-03 16:52:01 +01:00 by hl-fsfe · 4 comments

Hi there, exciting project!

I just tried installing the app unprivileged from the iodeOS F-Droid repo onto a GrapheneOS phone.

The app immediately crashed:

type: crash
osVersion: google/bluejay/bluejay:16/BP3A.250905.014/2025112101:user/release-keys
flags: dev options enabled
package: im.angry.openeuicc:716, targetSdk 35
process: im.angry.openeuicc
processUptime: 45 + 50 ms
installer: org.fdroid.basic

java.lang.RuntimeException: Unable to create application im.angry.openeuicc.PrivilegedOpenEuiccApplication
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7949)
	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2568)
	at android.os.Handler.dispatchMessage(Handler.java:110)
	at android.os.Looper.dispatchMessage(Looper.java:315)
	at android.os.Looper.loopOnce(Looper.java:251)
	at android.os.Looper.loop(Looper.java:349)
	at android.app.ActivityThread.main(ActivityThread.java:9085)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:945)
Caused by: java.lang.SecurityException: Caller does not have permission.
	at android.os.Parcel.createExceptionOrNull(Parcel.java:3364)
	at android.os.Parcel.createException(Parcel.java:3348)
	at android.os.Parcel.readException(Parcel.java:3324)
	at android.os.Parcel.readException(Parcel.java:3266)
	at com.android.internal.telephony.ITelephony$Stub$Proxy.getUiccCardsInfo(ITelephony.java:13711)
	at android.telephony.TelephonyManager.getUiccCardsInfo(TelephonyManager.java:4498)
	at im.angry.openeuicc.core.PrivilegedEuiccChannelManager.closeAllStaleChannels(PrivilegedEuiccChannelManager.kt:20)
	at im.angry.openeuicc.PrivilegedOpenEuiccApplication.onCreate(PrivilegedOpenEuiccApplication.kt:15)
	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1394)
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7944)
	... 10 more

would it be possible to run with a compatibility layer handing it certain privileges?

In that case, it could be possible that a compatibility layer like GrapheneOS' gmscompat could do that, while the app would be a user app and nonessential component.

GrapheneOS currently allows installing Google's proprietary eSIM management software as a user app, so this should be possible.

I see that these permissions are required

android.permission.READ_PRIVILEGED_PHONE_STATE
android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
android.permission.MODIFY_PHONE_STATE
android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION
android.permission.FOREGROUND_SERVICE
android.permission.POST_NOTIFICATIONS

Best regards :)

Hi there, exciting project! I just tried installing the app unprivileged from the iodeOS F-Droid repo onto a GrapheneOS phone. The app immediately crashed: ``` type: crash osVersion: google/bluejay/bluejay:16/BP3A.250905.014/2025112101:user/release-keys flags: dev options enabled package: im.angry.openeuicc:716, targetSdk 35 process: im.angry.openeuicc processUptime: 45 + 50 ms installer: org.fdroid.basic java.lang.RuntimeException: Unable to create application im.angry.openeuicc.PrivilegedOpenEuiccApplication at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7949) at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2568) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.dispatchMessage(Looper.java:315) at android.os.Looper.loopOnce(Looper.java:251) at android.os.Looper.loop(Looper.java:349) at android.app.ActivityThread.main(ActivityThread.java:9085) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:945) Caused by: java.lang.SecurityException: Caller does not have permission. at android.os.Parcel.createExceptionOrNull(Parcel.java:3364) at android.os.Parcel.createException(Parcel.java:3348) at android.os.Parcel.readException(Parcel.java:3324) at android.os.Parcel.readException(Parcel.java:3266) at com.android.internal.telephony.ITelephony$Stub$Proxy.getUiccCardsInfo(ITelephony.java:13711) at android.telephony.TelephonyManager.getUiccCardsInfo(TelephonyManager.java:4498) at im.angry.openeuicc.core.PrivilegedEuiccChannelManager.closeAllStaleChannels(PrivilegedEuiccChannelManager.kt:20) at im.angry.openeuicc.PrivilegedOpenEuiccApplication.onCreate(PrivilegedOpenEuiccApplication.kt:15) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1394) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7944) ... 10 more ``` would it be possible to run with a compatibility layer handing it certain privileges? In that case, it could be possible that a compatibility layer like GrapheneOS' gmscompat could do that, while the app would be a user app and nonessential component. GrapheneOS currently allows installing Google's proprietary eSIM management software as a user app, so this should be possible. I see that these permissions are required ``` android.permission.READ_PRIVILEGED_PHONE_STATE android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS android.permission.MODIFY_PHONE_STATE android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION android.permission.FOREGROUND_SERVICE android.permission.POST_NOTIFICATIONS ``` Best regards :)
Collaborator

unprivileged, please use EasyEUICC

unprivileged, please use EasyEUICC
septs closed this issue 2025-12-03 18:02:25 +01:00
Owner

Just for more context: this isn't how it works. A "compatibility layer" in this case basically means granting unrestricted OMAPI privilege to OpenEUICC without it being a system app (yes, technically you only need the ISD-R channel, but that's still a LOT of privilege to grant to an untrusted app). Good luck getting any custom ROM whatsoever to accept that. If GrapheneOS does that for Google, then it means they have some kind of privilege escape hatch enabled, in which case they can decide if they want to enable the same for OpenEUICC as well (my personal opinion is that at that point you are basically allowing the app to run privileged as system app, it's not a compatibility layer, it's just a backdoor for Google).

You'd have much better luck just convincing people to integrate OpenEUICC directly (we do have some hurdles, such as the partner eSIM download API which is not implemented yet, because I have no good way of testing / debugging that).

Just for more context: this isn't how it works. A "compatibility layer" in this case basically means granting unrestricted OMAPI privilege to OpenEUICC without it being a system app (yes, technically you only need the ISD-R channel, but that's still a LOT of privilege to grant to an untrusted app). Good luck getting _any_ custom ROM whatsoever to accept that. If GrapheneOS does that for Google, then it means they have some kind of privilege escape hatch enabled, in which case they can decide if they want to enable the same for OpenEUICC as well (my personal opinion is that at that point you are basically allowing the app to run privileged as system app, it's not a compatibility layer, it's just a backdoor for Google). You'd have much better luck just convincing people to integrate OpenEUICC directly (we do have some hurdles, such as the partner eSIM download API which is not implemented yet, because I have no good way of testing / debugging that).
Author

thanks for the reply!

I am not sure about GrapheneOS' implementation, but a benefit is that it can be installed on demand. In case of the proprietary Google module there are many benefits, for OpenEUICC well less trust in you ;D

So it is likely possible, but would grant the app a lot of privileges (that it needs). GrapheneOS has following issue open which they understand as their own implementation, with very low or no priority.

Seems like they are waiting for it to be complete, but I think adding it the same well as the current proprietary implementation could be done.

Mentioned the issue here

But the use of C is criticized, compared to Googles implementation which is supposedly more secure

Edit: Daniel Micay removed both my comment and his comment, in which he explicitely said that the restrictive License is an no-go for GrapheneOS (known but unfortunate).

thanks for the reply! I am not sure about GrapheneOS' implementation, but a benefit is that it can be installed on demand. In case of the proprietary Google module there are many benefits, for OpenEUICC well less trust in you ;D So it is likely possible, but would grant the app a lot of privileges (that it needs). GrapheneOS has [following issue open](https://github.com/GrapheneOS/os-issue-tracker/issues/1079) which they understand as their own implementation, with very low or no priority. Seems like they are waiting for it to be complete, but I think adding it the same well as the current proprietary implementation could be done. Mentioned the issue [here](https://github.com/GrapheneOS/os-issue-tracker/issues/1079#issuecomment-3631653299) But the use of C is criticized, compared to Googles implementation which is [supposedly more secure](https://github.com/GrapheneOS/os-issue-tracker/issues/6275#issuecomment-3376953408) Edit: Daniel Micay removed both my comment and his comment, in which he explicitely said that the restrictive License is an no-go for GrapheneOS (known but unfortunate).
Owner

This project used to be licensed with GPLv2 for the explicit purpose of eventual GrapheneOS integration. Since that no longer looked possible, and I personally no longer have any interest in engaging with their community for various reasons that I will not get into here, it was relicensed to GPLv3 because that aligns with my goal of providing a FOSS implementation of LPA better.

But, the licensing is completely irrelevant to whether the "compatibility layer" mode of operation can be used. Google's LPA never authorized third-party distribution either. The whole question is whether you want to give a backdoor to Google or OpenEUICC (and I want to make it super clear here, it is not a compatibility layer when the whole point is to grant more privileges than a user app should ever have. It is a backdoor for Google.), and I will not make the judgement for you or for GrapheneOS here.

On the point about memory safety, I don't like the use of C either, but unless anyone comes up with a better implementation of SGP.22 under a memory-safe language that does not also depend on BouncyCastle and asn1bean (which, mind you, also used to be the case when we used Truphone's LPA library, which is a whole other nightmare to deal with, not to mention that they are also basically unmaintained), this is the way it is going to be. I'm probably going to explore running the C side on WASM or just rewrite it in Rust at some point, if I ever find the time and motivation (financial support welcome :-) I am happy to charge 50% of my hourly rate at my day job to work on a memory-safe FOSS SGP.22 implementation).

This project used to be licensed with GPLv2 for the explicit purpose of eventual GrapheneOS integration. Since that no longer looked possible, and I personally no longer have any interest in engaging with their community for various reasons that I will not get into here, it was relicensed to GPLv3 because that aligns with my goal of providing a FOSS implementation of LPA better. But, the licensing is completely irrelevant to whether the "compatibility layer" mode of operation can be used. Google's LPA never authorized third-party distribution either. The whole question is whether you want to give a backdoor to Google or OpenEUICC (and I want to make it super clear here, it is __not a compatibility layer__ when the whole point is to grant more privileges than a user app should ever have. It __is a backdoor for Google__.), and I will not make the judgement for you or for GrapheneOS here. On the point about memory safety, I don't like the use of C either, but unless anyone comes up with a better implementation of SGP.22 under a memory-safe language that does not _also_ depend on BouncyCastle and asn1bean (which, mind you, also used to be the case when we used Truphone's LPA library, which is a whole other nightmare to deal with, not to mention that they are also basically unmaintained), this is the way it is going to be. I'm probably going to explore running the C side on WASM or just rewrite it in Rust at some point, if I ever find the time and motivation (_financial support welcome_ :-) I am happy to charge 50% of my hourly rate at my day job to work on a memory-safe FOSS SGP.22 implementation).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
PeterCxy/OpenEUICC#274
No description provided.