Merge changes from topic "lnh-jifd-leak"

* changes:
  Avoid potential fd leaks from jniCreateFileDescriptor (2/2)
  Avoid potential fd leak from jniCreateFileDescriptor (1/2)
This commit is contained in:
Orion Hodson
2020-05-26 19:25:20 +00:00
committed by Gerrit Code Review
6 changed files with 59 additions and 30 deletions

View File

@@ -475,7 +475,11 @@ static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, j
if (fd < 0) return NULL;
fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
if (fd < 0) return NULL;
return jniCreateFileDescriptor(env, fd);
jobject jifd = jniCreateFileDescriptor(env, fd);
if (jifd == NULL) {
close(fd);
}
return jifd;
}
return NULL;
}

View File

@@ -69,7 +69,11 @@ jobject SharedMemory_nCreate(JNIEnv* env, jobject, jstring jname, jint size) {
return nullptr;
}
return jniCreateFileDescriptor(env, fd);
jobject jifd = jniCreateFileDescriptor(env, fd);
if (jifd == nullptr) {
close(fd);
}
return jifd;
}
jint SharedMemory_nGetSize(JNIEnv* env, jobject, jobject fileDescriptor) {

View File

@@ -48,6 +48,7 @@ static jobject android_server_SerialService_open(JNIEnv *env, jobject /* thiz */
jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
if (fileDescriptor == NULL) {
close(fd);
return NULL;
}
return env->NewObject(gParcelFileDescriptorOffsets.mClass,

View File

@@ -19,6 +19,7 @@
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "MtpDescriptors.h"
@@ -88,6 +89,7 @@ static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobjec
}
jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
if (fileDescriptor == NULL) {
close(fd);
return NULL;
}
return env->NewObject(gParcelFileDescriptorOffsets.mClass,
@@ -120,35 +122,30 @@ static jint android_server_UsbDeviceManager_getAudioMode(JNIEnv* /* env */, jobj
}
static jobject android_server_UsbDeviceManager_openControl(JNIEnv *env, jobject /* thiz */, jstring jFunction) {
const char *function = env->GetStringUTFChars(jFunction, NULL);
ScopedUtfChars function(env, jFunction);
bool ptp = false;
int fd = -1;
if (!strcmp(function, "ptp")) {
if (!strcmp(function.c_str(), "ptp")) {
ptp = true;
}
if (!strcmp(function, "mtp") || ptp) {
if (!strcmp(function.c_str(), "mtp") || ptp) {
fd = TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP0 : FFS_MTP_EP0, O_RDWR));
if (fd < 0) {
ALOGE("could not open control for %s %s", function, strerror(errno));
goto error;
ALOGE("could not open control for %s %s", function.c_str(), strerror(errno));
return NULL;
}
if (!writeDescriptors(fd, ptp)) {
goto error;
close(fd);
return NULL;
}
}
if (function != NULL) {
env->ReleaseStringUTFChars(jFunction, function);
}
return jniCreateFileDescriptor(env, fd);
error:
if (fd != -1) {
jobject jifd = jniCreateFileDescriptor(env, fd);
if (jifd == NULL) {
// OutOfMemoryError will be pending.
close(fd);
}
if (function != NULL) {
env->ReleaseStringUTFChars(jFunction, function);
}
return NULL;
return jifd;
}
static const JNINativeMethod method_table[] = {

View File

@@ -134,6 +134,7 @@ static jobject android_server_UsbHostManager_openDevice(JNIEnv *env, jobject /*
jobject fileDescriptor = jniCreateFileDescriptor(env, newFD);
if (fileDescriptor == NULL) {
close(newFD);
return NULL;
}
return env->NewObject(gParcelFileDescriptorOffsets.mClass,

View File

@@ -20,6 +20,7 @@
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
@@ -99,24 +100,45 @@ android_server_UsbMidiDevice_open(JNIEnv *env, jobject thiz, jint card, jint dev
int fd = open(path, O_RDWR);
if (fd < 0) {
ALOGE("open failed on %s for index %d", path, i);
return NULL;
goto release_fds;
}
jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
env->SetObjectArrayElement(fds, i, fileDescriptor);
env->DeleteLocalRef(fileDescriptor);
ScopedLocalRef<jobject> jifd(env, jniCreateFileDescriptor(env, fd));
if (jifd.get() == NULL) {
goto release_fds;
}
env->SetObjectArrayElement(fds, i, jifd.get());
}
// create a pipe to use for unblocking our input thread
int pipeFD[2];
pipe(pipeFD);
jobject fileDescriptor = jniCreateFileDescriptor(env, pipeFD[0]);
env->SetObjectArrayElement(fds, subdevice_count, fileDescriptor);
env->DeleteLocalRef(fileDescriptor);
// store our end of the pipe in mPipeFD
env->SetIntField(thiz, sPipeFDField, pipeFD[1]);
{
int pipeFD[2];
if (pipe(pipeFD) == -1) {
ALOGE("pipe() failed, errno = %d", errno);
goto release_fds;
}
ScopedLocalRef<jobject> jifd(env, jniCreateFileDescriptor(env, pipeFD[0]));
if (jifd.get() == NULL) {
close(pipeFD[0]);
close(pipeFD[1]);
goto release_fds;
}
env->SetObjectArrayElement(fds, subdevice_count, jifd.get());
// store our end of the pipe in mPipeFD
env->SetIntField(thiz, sPipeFDField, pipeFD[1]);
}
return fds;
release_fds:
for (int i = 0; i < subdevice_count + 1; ++i) {
ScopedLocalRef<jobject> jifd(env, env->GetObjectArrayElement(fds, i));
if (jifd.get() == NULL) {
break;
}
int fd = jniGetFDFromFileDescriptor(env, jifd.get());
close(fd);
}
return NULL;
}
static void