MTP: Sanitize filename provided from MTP host
Fix potential security vulnerability via MTP path traversal
Bug: 130656917
Test: atest frameworks/av/mtp/ffs/tests
Test: Manual test: modified libmtp for path traversal attack
Test: Manual test: normal recursive folder copy
Signed-off-by: sekaiacg <sekaiacg@gmail.com>
Change-Id: I118d180a98378c8fecd9fd6f37de7d5983426695
(cherry picked from commit 13b2978e022d81a6c0519a54743876b0481da401)
diff --git a/mtp/ffs/Android.mk b/mtp/ffs/Android.mk
index 0f8bda9..90f9d32 100755
--- a/mtp/ffs/Android.mk
+++ b/mtp/ffs/Android.mk
@@ -59,7 +59,8 @@
libcutils \
libutils \
libselinux \
- libbase
+ libbase \
+ liblog
LOCAL_C_INCLUDES += bootable/recovery/twrplibusbhost/include
diff --git a/mtp/ffs/MtpServer.cpp b/mtp/ffs/MtpServer.cpp
index cacb45e..2a9e305 100755
--- a/mtp/ffs/MtpServer.cpp
+++ b/mtp/ffs/MtpServer.cpp
@@ -43,6 +43,8 @@
#include "MtpStorage.h"
#include "MtpStringBuffer.h"
+static const int SN_EVENT_LOG_ID = 0x534e4554;
+
static const MtpOperationCode kSupportedOperationCodes[] = {
MTP_OPERATION_GET_DEVICE_INFO,
MTP_OPERATION_OPEN_SESSION,
@@ -969,9 +971,20 @@
if (!parseDateTime(modified, modifiedTime))
modifiedTime = 0;
+ if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0) ||
+ (strcmp(name, "/") == 0) || (strcmp(basename(name), name) != 0)) {
+ char errMsg[80];
+
+ sprintf(errMsg, "Invalid name: %s", (const char *) name);
+ ALOGE("%s (b/130656917)", errMsg);
+ android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "130656917", -1, errMsg,
+ strlen(errMsg));
+
+ return MTP_RESPONSE_INVALID_PARAMETER;
+ }
if (path[path.size() - 1] != '/')
path.append("/");
- path.append(name);
+ path.append(basename(name));
// check space first
if (mSendObjectFileSize > storage->getFreeSpace())