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

Unverified Commit d61e0cdb authored by spickl's avatar spickl Committed by Michael Bestas
Browse files

Fix Gallery2 path traversal bug

Fix a path traversal bug that allowed a malicious launcher app to access files in the private space of the Gallery2 app by injecting a bad path.
Fix: Check URI before passing the file out from SharedImageProvider and raise exception if it's not pointing to the relevant folder.
Bug: 198174170
Test: manual by following the reporters instructions

Change-Id: I74dce6c4794b3eafb922bb9a2f2516677cc5f4d8
parent 452229bf
Loading
Loading
Loading
Loading
+32 −3
Original line number Diff line number Diff line
@@ -29,16 +29,20 @@ import android.provider.OpenableColumns;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class SharedImageProvider extends ContentProvider {

    private static final String LOGTAG = "SharedImageProvider";

    public static final String MIME_TYPE = "image/jpeg";
    public static final String AUTHORITY = "com.android.gallery3d.filtershow.provider.SharedImageProvider";
    public static final String AUTHORITY =
            "com.android.gallery3d.filtershow.provider.SharedImageProvider";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/image");
    public static final String PREPARE = "prepare";

    public static String LOCAL_PATH = (new File(CONTENT_URI.getPath())).getAbsolutePath();

    private final String[] mMimeStreamType = {
            MIME_TYPE
    };
@@ -83,7 +87,8 @@ public class SharedImageProvider extends ContentProvider {
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        String uriPath = uri.getLastPathSegment();
        if (uriPath == null) {
            return null;
@@ -130,8 +135,32 @@ public class SharedImageProvider extends ContentProvider {
        // Here we need to block until the image is ready
        mImageReadyCond.block();
        File path = new File(uriPath);
        ensureValidImagePath(path);
        int imode = 0;
        imode |= ParcelFileDescriptor.MODE_READ_ONLY;
        return ParcelFileDescriptor.open(path, imode);
    }

    /**
     * Ensure that the provided file path is part of the image directory.
     * Prevent unauthorized access to other directories by path traversal.
     * Throw security exception for paths outside the directory.
     *
     * @param path The path of the file to check. This path is expected to point to the image
     *             directory.
     * @throws SecurityException     Throws SecurityException if the path is not part of the image
     *                               directory.
     * @throws FileNotFoundException Throws FileNotFoundException if there is
     *                               no file associated with the given URI.
     */
    private void ensureValidImagePath(File path) throws FileNotFoundException {
        try {
            if (!path.getCanonicalPath().startsWith(LOCAL_PATH)) {
                throw new SecurityException(
                        "The requested file path is not part of the image directory");
            }
        } catch (IOException e) {
            throw new FileNotFoundException(e.getMessage());
        }
    }
}