Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 1 | #define TAG "ext4_utils" |
| 2 | |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 3 | #include "ext4_crypt_init_extensions.h" |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 4 | |
| 5 | #include <string> |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 6 | |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 7 | #include <dirent.h> |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 8 | #include <errno.h> |
Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 9 | #include <sys/mount.h> |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 10 | #include <sys/stat.h> |
Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 11 | |
| 12 | #include <cutils/klog.h> |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 13 | #include <cutils/properties.h> |
| 14 | #include <cutils/sockets.h> |
Paul Crowley | 36d056c | 2015-04-09 10:18:54 +0100 | [diff] [blame] | 15 | #include <poll.h> |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 16 | |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 17 | #include "key_control.h" |
Paul Lawrence | 6198026 | 2015-03-16 15:35:55 -0700 | [diff] [blame] | 18 | #include "unencrypted_properties.h" |
| 19 | |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 20 | static const std::string arbitrary_sequence_number = "42"; |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 21 | static const int vold_command_timeout_ms = 60 * 1000; |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 22 | |
| 23 | static std::string vold_command(std::string const& command) |
| 24 | { |
Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 25 | KLOG_INFO(TAG, "Running command %s\n", command.c_str()); |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 26 | int sock = -1; |
| 27 | |
| 28 | while (true) { |
Paul Lawrence | b411bcc | 2015-06-03 14:18:17 -0700 | [diff] [blame] | 29 | sock = socket_local_client("cryptd", |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 30 | ANDROID_SOCKET_NAMESPACE_RESERVED, |
| 31 | SOCK_STREAM); |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 32 | if (sock >= 0) { |
| 33 | break; |
| 34 | } |
| 35 | usleep(10000); |
| 36 | } |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 37 | |
| 38 | if (sock < 0) { |
Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 39 | KLOG_INFO(TAG, "Cannot open vold, failing command\n"); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 40 | return ""; |
| 41 | } |
| 42 | |
| 43 | class CloseSocket |
| 44 | { |
| 45 | int sock_; |
| 46 | public: |
| 47 | CloseSocket(int sock) : sock_(sock) {} |
| 48 | ~CloseSocket() { close(sock_); } |
| 49 | }; |
| 50 | |
| 51 | CloseSocket cs(sock); |
| 52 | |
| 53 | // Use arbitrary sequence number. This should only be used when the |
| 54 | // framework is down, so this is (mostly) OK. |
| 55 | std::string actual_command = arbitrary_sequence_number + " " + command; |
| 56 | if (write(sock, actual_command.c_str(), actual_command.size() + 1) < 0) { |
Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 57 | KLOG_ERROR(TAG, "Cannot write command\n"); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 58 | return ""; |
| 59 | } |
| 60 | |
Paul Crowley | 36d056c | 2015-04-09 10:18:54 +0100 | [diff] [blame] | 61 | struct pollfd poll_sock = {sock, POLLIN, 0}; |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 62 | |
Paul Lawrence | 2fa9e93 | 2015-06-12 13:06:21 -0700 | [diff] [blame] | 63 | int rc = TEMP_FAILURE_RETRY(poll(&poll_sock, 1, vold_command_timeout_ms)); |
Paul Crowley | 36d056c | 2015-04-09 10:18:54 +0100 | [diff] [blame] | 64 | if (rc < 0) { |
| 65 | KLOG_ERROR(TAG, "Error in poll %s\n", strerror(errno)); |
| 66 | return ""; |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 67 | } |
Paul Lawrence | 2fa9e93 | 2015-06-12 13:06:21 -0700 | [diff] [blame] | 68 | |
Paul Crowley | 36d056c | 2015-04-09 10:18:54 +0100 | [diff] [blame] | 69 | if (!(poll_sock.revents & POLLIN)) { |
| 70 | KLOG_ERROR(TAG, "Timeout\n"); |
| 71 | return ""; |
| 72 | } |
| 73 | char buffer[4096]; |
| 74 | memset(buffer, 0, sizeof(buffer)); |
Paul Lawrence | 2fa9e93 | 2015-06-12 13:06:21 -0700 | [diff] [blame] | 75 | rc = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); |
Paul Crowley | 36d056c | 2015-04-09 10:18:54 +0100 | [diff] [blame] | 76 | if (rc <= 0) { |
| 77 | if (rc == 0) { |
| 78 | KLOG_ERROR(TAG, "Lost connection to Vold - did it crash?\n"); |
| 79 | } else { |
| 80 | KLOG_ERROR(TAG, "Error reading data (%s)\n", strerror(errno)); |
| 81 | } |
| 82 | return ""; |
| 83 | } |
| 84 | |
| 85 | // We don't truly know that this is the correct result. However, |
| 86 | // since this will only be used when the framework is down, |
| 87 | // it should be OK unless someone is running vdc at the same time. |
| 88 | // Worst case we force a reboot in the very rare synchronization |
| 89 | // error |
| 90 | return std::string(buffer, rc); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 91 | } |
| 92 | |
Paul Lawrence | f976875 | 2015-03-30 09:16:09 -0700 | [diff] [blame] | 93 | int e4crypt_create_device_key(const char* dir, |
| 94 | int ensure_dir_exists(const char*)) |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 95 | { |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 96 | // Already encrypted with password? If so bail |
| 97 | std::string temp_folder = std::string() + dir + "/tmp_mnt"; |
| 98 | DIR* temp_dir = opendir(temp_folder.c_str()); |
| 99 | if (temp_dir) { |
| 100 | closedir(temp_dir); |
| 101 | return 0; |
| 102 | } |
| 103 | |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 104 | // Make sure folder exists. Use make_dir to set selinux permissions. |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 105 | if (ensure_dir_exists(UnencryptedProperties::GetPath(dir).c_str())) { |
Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 106 | KLOG_ERROR(TAG, "Failed to create %s with error %s\n", |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 107 | UnencryptedProperties::GetPath(dir).c_str(), |
| 108 | strerror(errno)); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 109 | return -1; |
| 110 | } |
| 111 | |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 112 | auto result = vold_command("cryptfs enablefilecrypto"); |
| 113 | // ext4enc:TODO proper error handling |
| 114 | KLOG_INFO(TAG, "enablefilecrypto returned with result %s\n", |
| 115 | result.c_str()); |
Paul Lawrence | 6198026 | 2015-03-16 15:35:55 -0700 | [diff] [blame] | 116 | |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 117 | return 0; |
| 118 | } |
| 119 | |
| 120 | int e4crypt_install_keyring() |
| 121 | { |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 122 | key_serial_t device_keyring = add_key("keyring", "e4crypt", 0, 0, |
| 123 | KEY_SPEC_SESSION_KEYRING); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 124 | |
| 125 | if (device_keyring == -1) { |
Elliott Hughes | ee29686 | 2015-03-28 10:39:46 -0700 | [diff] [blame] | 126 | KLOG_ERROR(TAG, "Failed to create keyring\n"); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 127 | return -1; |
| 128 | } |
| 129 | |
Paul Lawrence | 6198026 | 2015-03-16 15:35:55 -0700 | [diff] [blame] | 130 | KLOG_INFO(TAG, "Keyring created wth id %d in process %d\n", |
| 131 | device_keyring, getpid()); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 132 | |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 133 | return 0; |
| 134 | } |
| 135 | |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 136 | int e4crypt_set_directory_policy(const char* dir) |
| 137 | { |
| 138 | // Only set policy on first level /data directories |
Paul Lawrence | 6198026 | 2015-03-16 15:35:55 -0700 | [diff] [blame] | 139 | // To make this less restrictive, consider using a policy file. |
| 140 | // However this is overkill for as long as the policy is simply |
| 141 | // to apply a global policy to all /data folders created via makedir |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 142 | if (!dir || strncmp(dir, "/data/", 6) || strchr(dir + 6, '/')) { |
| 143 | return 0; |
| 144 | } |
Paul Crowley | 15e73f5 | 2015-05-06 15:28:35 +0100 | [diff] [blame^] | 145 | // ext4enc:TODO exclude /data/user with a horrible special case. |
| 146 | if (!strcmp(dir, "/data/user")) { |
| 147 | return 0; |
| 148 | } |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 149 | |
Paul Lawrence | 6198026 | 2015-03-16 15:35:55 -0700 | [diff] [blame] | 150 | UnencryptedProperties props("/data"); |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 151 | std::string policy = props.Get<std::string>(properties::ref); |
Paul Lawrence | db1d49c | 2015-04-10 07:47:30 -0700 | [diff] [blame] | 152 | if (policy.empty()) { |
Paul Crowley | 15e73f5 | 2015-05-06 15:28:35 +0100 | [diff] [blame^] | 153 | // ext4enc:TODO why is this OK? |
Paul Lawrence | db1d49c | 2015-04-10 07:47:30 -0700 | [diff] [blame] | 154 | return 0; |
| 155 | } |
| 156 | |
Paul Lawrence | af02e8a | 2015-05-01 05:24:04 -0700 | [diff] [blame] | 157 | KLOG_INFO(TAG, "Setting policy on %s\n", dir); |
Paul Lawrence | db1d49c | 2015-04-10 07:47:30 -0700 | [diff] [blame] | 158 | int result = do_policy_set(dir, policy.c_str(), policy.size()); |
Paul Lawrence | 6198026 | 2015-03-16 15:35:55 -0700 | [diff] [blame] | 159 | if (result) { |
Paul Lawrence | bc2eb8c | 2015-04-28 22:13:04 +0000 | [diff] [blame] | 160 | KLOG_ERROR(TAG, "Setting %s policy on %s failed!\n", |
| 161 | policy.c_str(), dir); |
Paul Lawrence | 92da49d | 2015-02-25 15:11:13 -0800 | [diff] [blame] | 162 | return -1; |
| 163 | } |
| 164 | |
| 165 | return 0; |
| 166 | } |