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

Commit e28ee49c authored by Varun Shah's avatar Varun Shah Committed by mse1969
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:fc0dcc7ca0fd102d61bef8bd41d9a037bd49f6dd
Merged-In: I1a8993d99d1f381e1122b304d223a5c10e4578ce
Change-Id: I1a8993d99d1f381e1122b304d223a5c10e4578ce
parent 86f5cf14
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -469,13 +469,14 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
                throws FileNotFoundException {
            uri = validateIncomingUri(uri);
            uri = maybeGetUriWithoutUserId(uri);
            enforceFilePermission(callingPkg, attributionTag, uri, mode, callerToken);
            final String updatedMode = validateFileMode(mode);
            enforceFilePermission(callingPkg, attributionTag, uri, updatedMode, callerToken);
            Trace.traceBegin(TRACE_TAG_DATABASE, "openFile");
            final Pair<String, String> original = setCallingPackage(
                    new Pair<>(callingPkg, attributionTag));
            try {
                return mInterface.openFile(
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
                        uri, updatedMode, CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
@@ -490,13 +491,14 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
                throws FileNotFoundException {
            uri = validateIncomingUri(uri);
            uri = maybeGetUriWithoutUserId(uri);
            enforceFilePermission(callingPkg, attributionTag, uri, mode, null);
            final String updatedMode = validateFileMode(mode);
            enforceFilePermission(callingPkg, attributionTag, uri, updatedMode, null);
            Trace.traceBegin(TRACE_TAG_DATABASE, "openAssetFile");
            final Pair<String, String> original = setCallingPackage(
                    new Pair<>(callingPkg, attributionTag));
            try {
                return mInterface.openAssetFile(
                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
                        uri, updatedMode, CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
@@ -644,6 +646,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(String callingPkg, @Nullable String attributionTag, Uri uri,
                int uid, int modeFlags) {