Closed Bug 1759760 Opened 4 years ago Closed 4 years ago

Parcelable encountered ClassNotFoundException reading a Serializable object (name = <random name>)

Categories

(Firefox for Android :: General, defect)

defect

Tracking

()

RESOLVED FIXED
Tracking Status
firefox99 --- wontfix
firefox100 --- fixed

People

(Reporter: agi, Unassigned)

Details

(Keywords: crash)

Crash Data

Crash report: https://crash-stats.mozilla.org/report/index/0e1a9389-a198-4281-807b-d27720220312

This looks pretty fishy, not 100% sure what's going on.

Java stack trace:

java.lang.RuntimeException: Unable to start activity ComponentInfo{org.mozilla.fenix/org.mozilla.fenix.IntentReceiverActivity}: java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = o.zzbhf)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4037)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4203)
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2440)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:226)
	at android.os.Looper.loop(Looper.java:313)
	at android.app.ActivityThread.main(ActivityThread.java:8641)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1133)
Caused by: java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = o.zzbhf)
	at android.os.Parcel.readSerializable(Parcel.java:3525)
	at android.os.Parcel.readValue(Parcel.java:3289)
	at android.os.Parcel.readArrayMapInternal(Parcel.java:3635)
	at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:292)
	at android.os.BaseBundle.unparcel(BaseBundle.java:236)
	at android.os.BaseBundle.putBoolean(BaseBundle.java:610)
	at android.content.Intent.putExtra(Intent.java:10076)
	at org.mozilla.fenix.IntentReceiverActivity.onCreate(IntentReceiverActivity.kt:9)
	at android.app.Activity.performCreate(Activity.java:8282)
	at android.app.Activity.performCreate(Activity.java:8262)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4011)
	... 12 more
Caused by: java.lang.ClassNotFoundException: o.zzbhf
	at java.lang.Class.classForName(Native Method)
	at java.lang.Class.forName(Class.java:454)
	at android.os.Parcel$2.resolveClass(Parcel.java:3511)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1703)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1594)
	at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1824)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1409)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
	at android.os.Parcel.readSerializable(Parcel.java:3519)
	... 23 more
Caused by: java.lang.ClassNotFoundException: o.zzbhf
	... 32 more

There is a bunch of older crash data that we should ignore, Fenix v7 etc.

The most common version of this crash in v97/98 is Java.lang.RuntimeException: Unable to start activity ComponentInfo{org.mozilla.firefox/org.mozilla.fenix.IntentReceiverActivity}: java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = f30.c)

If you have raw Java crash access this search will return all the crashes mentioning name = f30.c https://crash-stats.mozilla.org/signature/?java_stack_trace_raw=~name%20%3D%20f30.c&product=Fenix&signature=java.lang.RuntimeException%3A%20at%20android.app.ActivityThread.performLaunchActivity%28ActivityThread.java%29&_columns=date&_columns=product&_columns=version&_columns=build_id&_columns=platform&_columns=reason&_columns=address&_columns=install_time&_columns=startup_crash&_sort=-date&page=1

Locale breakdown is interesting

1	fi_fi	288	26.23 %
2	de_de	259	23.59 %
3	ro_ro	188	17.12 %
4	sk_sk	128	11.66 %
5	pt_pt	77	7.01 %
6	en_us	34	3.10 %
7	en_gb	24	2.19 %
8	fr_fr	21	1.91 %
9	de	11	1.00 %
10	bg_bg	10	0.91 %

Looking for some popular app for Finland, Germany, Romania, Sweden... that uses a file called f30.c?

Yeah for this crash I'm more worried about whether it's exploitable rather than how often it occurs. It looks like we're looking up an arbitrary class which could be exploitable.

OK so here's my understanding.

As Christian mentioned somewhere in slack, any call to putExtra will trigger a unparcel call which will try to de-serialize the extras for the intent. In particular for the crash of this bug, I believe this is the call site: https://searchfox.org/mozilla-mobile/rev/a351ac688572593698d62a7e42feb9992a205412/focus-android/app/src/main/java/org/mozilla/focus/activity/IntentReceiverActivity.kt#51

The documentation mentions this:

Sending data between processes is similar to doing so between activities. However, when sending between processes, we recommend that you do not use custom parcelables. If you send a custom Parcelable object from one app to another, you need to be certain that the exact same version of the custom class is present on both the sending and receiving apps. Typically this could be a common library used across both apps. An error can occur if your app tries to send a custom parcelable to the system, because the system cannot unmarshal a class that it has no knowledge of.

https://developer.android.com/guide/components/activities/parcelables-and-bundles

Chrome handles this by requesting a non-existent key and catching the exception:

    public static Intent sanitizeIntent(final Intent incomingIntent) {
        if (incomingIntent == null) return null;
        try {
            incomingIntent.getBooleanExtra("TriggerUnparcel", false);
            return incomingIntent;
        } catch (BadParcelableException e) {
            return logInvalidIntent(incomingIntent, e);
        } catch (RuntimeException e) {
            if (e.getCause() instanceof ClassNotFoundException) {
                return logInvalidIntent(incomingIntent, e);
            }
            throw e;
        }
    }

https://source.chromium.org/chromium/chromium/src/+/main:base/android/java/src/org/chromium/base/IntentUtils.java;l=481-494;drc=48a3eaf6f8ae83f7c99851f0b9088365e3edf6e6

We should probably do the same but otherwise I don't think this bug is exploitable so I'm gonna open it up.

Group: mobile-core-security
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Component: Stability → General
You need to log in before you can comment on or make changes to this bug.