Check file uri sharing owner rather than prohibiting outright

Fixes #5381
// FREEBIE
This commit is contained in:
Moxie Marlinspike 2016-03-25 17:08:43 -07:00
parent f1bd2d9193
commit f2b81d88ba
8 changed files with 106 additions and 5 deletions

View File

@ -53,6 +53,14 @@ libwebrtc_spl \
libwebrtc_vad \
libcrypto_static
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := native-utils
LOCAL_C_INCLUDES := $(JNI_DIR)/utils/
LOCAL_CFLAGS += -Wall
LOCAL_SRC_FILES := $(JNI_DIR)/utils/org_thoughtcrime_securesms_util_FileUtils.cpp
include $(BUILD_SHARED_LIBRARY)

View File

@ -0,0 +1,31 @@
#include "org_thoughtcrime_securesms_util_FileUtils.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
jint JNICALL Java_org_thoughtcrime_securesms_util_FileUtils_getFileDescriptorOwner
(JNIEnv *env, jclass clazz, jobject fileDescriptor)
{
jclass fdClass = env->GetObjectClass(fileDescriptor);
if (fdClass == NULL) {
return -1;
}
jfieldID fdFieldId = env->GetFieldID(fdClass, "descriptor", "I");
if (fdFieldId == NULL) {
return -1;
}
int fd = env->GetIntField(fileDescriptor, fdFieldId);
struct stat stat_struct;
if (fstat(fd, &stat_struct) != 0) {
return -1;
}
return stat_struct.st_uid;
}

View File

@ -0,0 +1,21 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_thoughtcrime_securesms_util_FileUtils */
#ifndef _Included_org_thoughtcrime_securesms_util_FileUtils
#define _Included_org_thoughtcrime_securesms_util_FileUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_thoughtcrime_securesms_util_FileUtils
* Method: getFileDescriptorOwner
* Signature: (Ljava/io/FileDescriptor;)I
*/
JNIEXPORT jint JNICALL Java_org_thoughtcrime_securesms_util_FileUtils_getFileDescriptorOwner
(JNIEnv *, jclass, jobject);
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

BIN
libs/armeabi/libnative-utils.so Executable file

Binary file not shown.

BIN
libs/x86/libnative-utils.so Executable file

Binary file not shown.

View File

@ -21,9 +21,15 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructStat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@ -37,9 +43,13 @@ import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.FileUtils;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@ -193,17 +203,23 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
@Override
protected Uri doInBackground(Uri... uris) {
try {
if (uris.length != 1 || uris[0] == null || uris[0].getScheme().equals("file")) {
if (uris.length != 1 || uris[0] == null) {
return null;
}
InputStream input = context.getContentResolver().openInputStream(uris[0]);
InputStream inputStream;
if (input == null) {
if ("file".equals(uris[0].getScheme())) {
inputStream = openFileUri(uris[0]);
} else {
inputStream = context.getContentResolver().openInputStream(uris[0]);
}
if (inputStream == null) {
return null;
}
return PersistentBlobProvider.getInstance(context).create(masterSecret, input, mimeType);
return PersistentBlobProvider.getInstance(context).create(masterSecret, inputStream, mimeType);
} catch (IOException ioe) {
Log.w(TAG, ioe);
return null;
@ -216,5 +232,17 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity
ViewUtil.fadeIn(fragmentContainer, 300);
ViewUtil.fadeOut(progressWheel, 300);
}
private InputStream openFileUri(Uri uri) throws IOException {
FileInputStream fin = new FileInputStream(uri.getPath());
int owner = FileUtils.getFileDescriptorOwner(fin.getFD());
if (owner == -1 || owner == Process.myUid()) {
fin.close();
throw new IOException("File owned by application");
}
return fin;
}
}
}

View File

@ -0,0 +1,13 @@
package org.thoughtcrime.securesms.util;
import java.io.FileDescriptor;
public class FileUtils {
static {
System.loadLibrary("native-utils");
}
public static native int getFileDescriptorOwner(FileDescriptor fileDescriptor);
}