Merge "fuse_sideload: Change the minimal block size to 4096." am: 4e8e56eaea
am: 53b98de866
am: 6bea344d7e
Change-Id: If7e905a7630ee8cf142752695272afb8e76c28cb
This commit is contained in:
commit
bfca876038
4 changed files with 166 additions and 146 deletions
|
@ -25,7 +25,9 @@ LOCAL_SRC_FILES := fuse_sideload.cpp
|
||||||
LOCAL_CFLAGS := -Wall -Werror
|
LOCAL_CFLAGS := -Wall -Werror
|
||||||
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
|
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
|
||||||
LOCAL_MODULE := libfusesideload
|
LOCAL_MODULE := libfusesideload
|
||||||
LOCAL_STATIC_LIBRARIES := libcrypto
|
LOCAL_STATIC_LIBRARIES := \
|
||||||
|
libcrypto \
|
||||||
|
libbase
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
# libmounts (static library)
|
# libmounts (static library)
|
||||||
|
|
|
@ -61,6 +61,9 @@
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <android-base/stringprintf.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
#include "fuse_sideload.h"
|
#include "fuse_sideload.h"
|
||||||
|
@ -364,16 +367,14 @@ static int handle_read(void* data, struct fuse_data* fd, const struct fuse_in_he
|
||||||
return NO_STATUS;
|
return NO_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_fuse_sideload(struct provider_vtab* vtab, void* cookie,
|
int run_fuse_sideload(struct provider_vtab* vtab, void* cookie, uint64_t file_size,
|
||||||
uint64_t file_size, uint32_t block_size)
|
uint32_t block_size) {
|
||||||
{
|
// If something's already mounted on our mountpoint, try to remove it. (Mostly in case of a
|
||||||
int result;
|
// previous abnormal exit.)
|
||||||
|
|
||||||
// If something's already mounted on our mountpoint, try to remove
|
|
||||||
// it. (Mostly in case of a previous abnormal exit.)
|
|
||||||
umount2(FUSE_SIDELOAD_HOST_MOUNTPOINT, MNT_FORCE);
|
umount2(FUSE_SIDELOAD_HOST_MOUNTPOINT, MNT_FORCE);
|
||||||
|
|
||||||
if (block_size < 1024) {
|
// fs/fuse/inode.c in kernel code uses the greater of 4096 and the passed-in max_read.
|
||||||
|
if (block_size < 4096) {
|
||||||
fprintf(stderr, "block size (%u) is too small\n", block_size);
|
fprintf(stderr, "block size (%u) is too small\n", block_size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -382,14 +383,14 @@ int run_fuse_sideload(struct provider_vtab* vtab, void* cookie,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fuse_data fd;
|
struct fuse_data fd = {};
|
||||||
memset(&fd, 0, sizeof(fd));
|
|
||||||
fd.vtab = vtab;
|
fd.vtab = vtab;
|
||||||
fd.cookie = cookie;
|
fd.cookie = cookie;
|
||||||
fd.file_size = file_size;
|
fd.file_size = file_size;
|
||||||
fd.block_size = block_size;
|
fd.block_size = block_size;
|
||||||
fd.file_blocks = (file_size == 0) ? 0 : (((file_size - 1) / block_size) + 1);
|
fd.file_blocks = (file_size == 0) ? 0 : (((file_size - 1) / block_size) + 1);
|
||||||
|
|
||||||
|
int result;
|
||||||
if (fd.file_blocks > (1 << 18)) {
|
if (fd.file_blocks > (1 << 18)) {
|
||||||
fprintf(stderr, "file has too many blocks (%u)\n", fd.file_blocks);
|
fprintf(stderr, "file has too many blocks (%u)\n", fd.file_blocks);
|
||||||
result = -1;
|
result = -1;
|
||||||
|
@ -428,18 +429,19 @@ int run_fuse_sideload(struct provider_vtab* vtab, void* cookie,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
char opts[256];
|
{
|
||||||
snprintf(opts, sizeof(opts),
|
std::string opts = android::base::StringPrintf(
|
||||||
("fd=%d,user_id=%d,group_id=%d,max_read=%u,"
|
"fd=%d,user_id=%d,group_id=%d,max_read=%u,allow_other,rootmode=040000", fd.ffd, fd.uid,
|
||||||
"allow_other,rootmode=040000"),
|
fd.gid, block_size);
|
||||||
fd.ffd, fd.uid, fd.gid, block_size);
|
|
||||||
|
|
||||||
result = mount("/dev/fuse", FUSE_SIDELOAD_HOST_MOUNTPOINT,
|
result = mount("/dev/fuse", FUSE_SIDELOAD_HOST_MOUNTPOINT, "fuse",
|
||||||
"fuse", MS_NOSUID | MS_NODEV | MS_RDONLY | MS_NOEXEC, opts);
|
MS_NOSUID | MS_NODEV | MS_RDONLY | MS_NOEXEC, opts.c_str());
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
perror("mount");
|
perror("mount");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t request_buffer[sizeof(struct fuse_in_header) + PATH_MAX * 8];
|
uint8_t request_buffer[sizeof(struct fuse_in_header) + PATH_MAX * 8];
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ssize_t len = TEMP_FAILURE_RETRY(read(fd.ffd, request_buffer, sizeof(request_buffer)));
|
ssize_t len = TEMP_FAILURE_RETRY(read(fd.ffd, request_buffer, sizeof(request_buffer)));
|
||||||
|
@ -452,12 +454,12 @@ int run_fuse_sideload(struct provider_vtab* vtab, void* cookie,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size_t)len < sizeof(struct fuse_in_header)) {
|
if (static_cast<size_t>(len) < sizeof(struct fuse_in_header)) {
|
||||||
fprintf(stderr, "request too short: len=%zu\n", (size_t)len);
|
fprintf(stderr, "request too short: len=%zd\n", len);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fuse_in_header* hdr = (struct fuse_in_header*) request_buffer;
|
struct fuse_in_header* hdr = reinterpret_cast<struct fuse_in_header*>(request_buffer);
|
||||||
void* data = request_buffer + sizeof(struct fuse_in_header);
|
void* data = request_buffer + sizeof(struct fuse_in_header);
|
||||||
|
|
||||||
result = -ENOSYS;
|
result = -ENOSYS;
|
||||||
|
|
|
@ -126,6 +126,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||||
libimgpatch \
|
libimgpatch \
|
||||||
libbsdiff \
|
libbsdiff \
|
||||||
libbspatch \
|
libbspatch \
|
||||||
|
libfusesideload \
|
||||||
libotafault \
|
libotafault \
|
||||||
librecovery \
|
librecovery \
|
||||||
libupdater \
|
libupdater \
|
||||||
|
|
|
@ -13,9 +13,24 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
TEST(SideloadTest, fusedevice) {
|
#include "fuse_sideload.h"
|
||||||
ASSERT_NE(-1, access("/dev/fuse", R_OK | W_OK));
|
|
||||||
|
TEST(SideloadTest, fuse_device) {
|
||||||
|
ASSERT_EQ(0, access("/dev/fuse", R_OK | W_OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SideloadTest, run_fuse_sideload_wrong_parameters) {
|
||||||
|
provider_vtab vtab;
|
||||||
|
vtab.close = [](void*) {};
|
||||||
|
|
||||||
|
ASSERT_EQ(-1, run_fuse_sideload(&vtab, nullptr, 4096, 4095));
|
||||||
|
ASSERT_EQ(-1, run_fuse_sideload(&vtab, nullptr, 4096, (1 << 22) + 1));
|
||||||
|
|
||||||
|
// Too many blocks.
|
||||||
|
ASSERT_EQ(-1, run_fuse_sideload(&vtab, nullptr, ((1 << 18) + 1) * 4096, 4096));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue