Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f54544f8 authored by Varun Shah's avatar Varun Shah Committed by Android Build Coastguard Worker
Browse files

Don't allow read truncation or appending for file operations.

If a caller attempts to read a file with the truncation or append
bits and doesn't specify the write bit as well, silently drop the
invalid bits to prevent unintended changes.

Bug: 414387646
Test: atest CtsContentProviderTestCases
Flag: EXEMPT security fix
(cherry picked from commit f8099b06)
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:85ad97d70e6639a4ab7ef5b24177d3f0d11cad1c
Merged-In: I1a8993d99d1f381e1122b304d223a5c10e4578ce
Change-Id: I1a8993d99d1f381e1122b304d223a5c10e4578ce
parent 66a76238
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -580,13 +580,14 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
                throws FileNotFoundException {
            uri = validateIncomingUri(uri);
            uri = maybeGetUriWithoutUserId(uri);
            enforceFilePermission(attributionSource, uri, mode);
            final String updatedMode = validateFileMode(mode);
            enforceFilePermission(attributionSource, uri, updatedMode);
            traceBegin(TRACE_TAG_DATABASE, "openFile: ", uri.getAuthority());
            final AttributionSource original = setCallingAttributionSource(
                    attributionSource);
            try {
                return mInterface.openFile(
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
                        uri, updatedMode, CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
@@ -601,13 +602,14 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
                throws FileNotFoundException {
            uri = validateIncomingUri(uri);
            uri = maybeGetUriWithoutUserId(uri);
            enforceFilePermission(attributionSource, uri, mode);
            final String updatedMode = validateFileMode(mode);
            enforceFilePermission(attributionSource, uri, updatedMode);
            traceBegin(TRACE_TAG_DATABASE, "openAssetFile: ", uri.getAuthority());
            final AttributionSource original = setCallingAttributionSource(
                    attributionSource);
            try {
                return mInterface.openAssetFile(
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
                        uri, updatedMode, CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
@@ -772,6 +774,25 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
            }
        }

        private String validateFileMode(String mode) {
            // We currently only support the following modes: r, w, wt, wa, rw, rwt
            // Note: ideally, we should check against the allowed modes and throw a
            // SecurityException if the mode doesn't match any of them but to avoid app compat
            // issues, we're silently dropping bits which allow modifying files when the write bit
            // is not specified.
            if (mode != null && mode.indexOf('w') == -1) {
                // Don't allow truncation without write
                if (mode.indexOf('t') != -1) {
                    mode = mode.replace("t", "");
                }
                // Don't allow appending without write
                if (mode.indexOf('a') != -1) {
                    mode = mode.replace("a", "");
                }
            }
            return mode;
        }

        @Override
        public int checkUriPermission(@NonNull AttributionSource attributionSource, Uri uri,
                int uid, int modeFlags) {