remount_service.cpp revision 9aa4fda4e64c1882faf019cc2a483ee4917e0c85
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define TRACE_TAG TRACE_ADB 18 19#include "sysdeps.h" 20 21#include <errno.h> 22#include <fcntl.h> 23#include <mntent.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <sys/mount.h> 28#include <unistd.h> 29 30#include <string> 31 32#include "adb.h" 33#include "adb_io.h" 34#include "adb_utils.h" 35#include "cutils/properties.h" 36 37// Returns the device used to mount a directory in /proc/mounts. 38static std::string find_mount(const char* dir) { 39 std::unique_ptr<FILE, int(*)(FILE*)> fp(setmntent("/proc/mounts", "r"), endmntent); 40 if (!fp) { 41 return ""; 42 } 43 44 mntent* e; 45 while ((e = getmntent(fp.get())) != nullptr) { 46 if (strcmp(dir, e->mnt_dir) == 0) { 47 return e->mnt_fsname; 48 } 49 } 50 return ""; 51} 52 53bool make_block_device_writable(const std::string& dev) { 54 int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC); 55 if (fd == -1) { 56 return false; 57 } 58 59 int OFF = 0; 60 bool result = (ioctl(fd, BLKROSET, &OFF) != -1); 61 adb_close(fd); 62 return result; 63} 64 65static bool remount_partition(int fd, const char* dir) { 66 if (!directory_exists(dir)) { 67 return true; 68 } 69 std::string dev = find_mount(dir); 70 if (dev.empty()) { 71 return true; 72 } 73 if (!make_block_device_writable(dev)) { 74 WriteFdFmt(fd, "remount of %s failed; couldn't make block device %s writable: %s\n", 75 dir, dev.c_str(), strerror(errno)); 76 return false; 77 } 78 if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) { 79 WriteFdFmt(fd, "remount of %s failed: %s\n", dir, strerror(errno)); 80 return false; 81 } 82 return true; 83} 84 85void remount_service(int fd, void* cookie) { 86 if (getuid() != 0) { 87 WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n"); 88 adb_close(fd); 89 return; 90 } 91 92 char prop_buf[PROPERTY_VALUE_MAX]; 93 property_get("partition.system.verified", prop_buf, ""); 94 bool system_verified = (strlen(prop_buf) > 0); 95 96 property_get("partition.vendor.verified", prop_buf, ""); 97 bool vendor_verified = (strlen(prop_buf) > 0); 98 99 if (system_verified || vendor_verified) { 100 // Allow remount but warn of likely bad effects 101 bool both = system_verified && vendor_verified; 102 WriteFdFmt(fd, 103 "dm_verity is enabled on the %s%s%s partition%s.\n", 104 system_verified ? "system" : "", 105 both ? " and " : "", 106 vendor_verified ? "vendor" : "", 107 both ? "s" : ""); 108 WriteFdExactly(fd, 109 "Use \"adb disable-verity\" to disable verity.\n" 110 "If you do not, remount may succeed, however, you will still " 111 "not be able to write to these volumes.\n"); 112 } 113 114 bool success = true; 115 success &= remount_partition(fd, "/system"); 116 success &= remount_partition(fd, "/vendor"); 117 success &= remount_partition(fd, "/oem"); 118 119 WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n"); 120 121 adb_close(fd); 122} 123