18b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn/* 28b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * Copyright (C) 2007 The Android Open Source Project 38b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * 48b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 58b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * you may not use this file except in compliance with the License. 68b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * You may obtain a copy of the License at 78b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * 88b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 98b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * 108b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * Unless required by applicable law or agreed to in writing, software 118b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 128b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * See the License for the specific language governing permissions and 148b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * limitations under the License. 158b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn */ 168b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 178b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn/* This file is used to define the properties of the filesystem 188b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** images generated by build tools (mkbootfs and mkyaffs2image) and 198b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** by the device side of adb. 208b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn*/ 218b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 2268651148dd06da576068749d33a82b5105d67091Mark Salyzyn#define LOG_TAG "fs_config" 2368651148dd06da576068749d33a82b5105d67091Mark Salyzyn 2468651148dd06da576068749d33a82b5105d67091Mark Salyzyn#define _GNU_SOURCE 2568651148dd06da576068749d33a82b5105d67091Mark Salyzyn 2668651148dd06da576068749d33a82b5105d67091Mark Salyzyn#include <errno.h> 2768651148dd06da576068749d33a82b5105d67091Mark Salyzyn#include <fcntl.h> 2868651148dd06da576068749d33a82b5105d67091Mark Salyzyn#include <stdbool.h> 298b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn#include <stdint.h> 3068651148dd06da576068749d33a82b5105d67091Mark Salyzyn#include <stdio.h> 3168651148dd06da576068749d33a82b5105d67091Mark Salyzyn#include <stdlib.h> 328b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn#include <string.h> 338b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn#include <sys/stat.h> 3468651148dd06da576068749d33a82b5105d67091Mark Salyzyn#include <sys/types.h> 358b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 3668651148dd06da576068749d33a82b5105d67091Mark Salyzyn#include <log/log.h> 378b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn#include <private/android_filesystem_config.h> 38fd5b425b6eeef94987f7540bc2522fc05750857cMark Salyzyn#include <utils/Compat.h> 398b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 404232b378e79f4254abc16a4254e2ba1b91851f11Mark Salyzyn#ifndef O_BINARY 414232b378e79f4254abc16a4254e2ba1b91851f11Mark Salyzyn#define O_BINARY 0 424232b378e79f4254abc16a4254e2ba1b91851f11Mark Salyzyn#endif 434232b378e79f4254abc16a4254e2ba1b91851f11Mark Salyzyn 4468651148dd06da576068749d33a82b5105d67091Mark Salyzyn/* The following structure is stored little endian */ 4568651148dd06da576068749d33a82b5105d67091Mark Salyzynstruct fs_path_config_from_file { 4668651148dd06da576068749d33a82b5105d67091Mark Salyzyn uint16_t len; 4768651148dd06da576068749d33a82b5105d67091Mark Salyzyn uint16_t mode; 4868651148dd06da576068749d33a82b5105d67091Mark Salyzyn uint16_t uid; 4968651148dd06da576068749d33a82b5105d67091Mark Salyzyn uint16_t gid; 5068651148dd06da576068749d33a82b5105d67091Mark Salyzyn uint64_t capabilities; 5168651148dd06da576068749d33a82b5105d67091Mark Salyzyn char prefix[]; 5268651148dd06da576068749d33a82b5105d67091Mark Salyzyn} __attribute__((__aligned__(sizeof(uint64_t)))); 5368651148dd06da576068749d33a82b5105d67091Mark Salyzyn 5468651148dd06da576068749d33a82b5105d67091Mark Salyzyn/* My kingdom for <endian.h> */ 5568651148dd06da576068749d33a82b5105d67091Mark Salyzynstatic inline uint16_t get2LE(const uint8_t* src) 5668651148dd06da576068749d33a82b5105d67091Mark Salyzyn{ 5768651148dd06da576068749d33a82b5105d67091Mark Salyzyn return src[0] | (src[1] << 8); 5868651148dd06da576068749d33a82b5105d67091Mark Salyzyn} 5968651148dd06da576068749d33a82b5105d67091Mark Salyzyn 6068651148dd06da576068749d33a82b5105d67091Mark Salyzynstatic inline uint64_t get8LE(const uint8_t* src) 6168651148dd06da576068749d33a82b5105d67091Mark Salyzyn{ 6268651148dd06da576068749d33a82b5105d67091Mark Salyzyn uint32_t low, high; 6368651148dd06da576068749d33a82b5105d67091Mark Salyzyn 6468651148dd06da576068749d33a82b5105d67091Mark Salyzyn low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 6568651148dd06da576068749d33a82b5105d67091Mark Salyzyn high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24); 6668651148dd06da576068749d33a82b5105d67091Mark Salyzyn return ((uint64_t) high << 32) | (uint64_t) low; 6768651148dd06da576068749d33a82b5105d67091Mark Salyzyn} 6868651148dd06da576068749d33a82b5105d67091Mark Salyzyn 695d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn#define ALIGN(x, alignment) ( ((x) + ((alignment) - 1)) & ~((alignment) - 1) ) 705d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn 718b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn/* Rules for directories. 728b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** These rules are applied based on "first match", so they 738b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** should start with the most specific path and work their 748b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** way up to the root. 758b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn*/ 768b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 778b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzynstatic const struct fs_path_config android_dirs[] = { 788b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00770, AID_SYSTEM, AID_CACHE, 0, "cache" }, 798b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" }, 808b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private" }, 818b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_ROOT, AID_ROOT, 0, "data/dalvik-cache" }, 828b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/data" }, 838b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_SHELL, AID_SHELL, 0, "data/local/tmp" }, 848b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_SHELL, AID_SHELL, 0, "data/local" }, 858b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 01771, AID_SYSTEM, AID_MISC, 0, "data/misc" }, 868b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00770, AID_DHCP, AID_DHCP, 0, "data/misc/dhcp" }, 878b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" }, 888b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" }, 898b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" }, 908b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" }, 918b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00750, AID_ROOT, AID_SHELL, 0, "sbin" }, 928b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "system/bin" }, 938b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor" }, 948b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin" }, 958b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_ROOT, 0, "system/etc/ppp" }, 968b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "vendor" }, 978b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00777, AID_ROOT, AID_ROOT, 0, "sdcard" }, 988b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_ROOT, 0, 0 }, 998b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn}; 1008b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 1018b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn/* Rules for files. 1028b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** These rules are applied based on "first match", so they 1038b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** should start with the most specific path and work their 1048b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** way up to the root. Prefixes ending in * denotes wildcard 1058b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn** and will allow partial matches. 1068b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn*/ 10768651148dd06da576068749d33a82b5105d67091Mark Salyzynstatic const char conf_dir[] = "/system/etc/fs_config_dirs"; 10868651148dd06da576068749d33a82b5105d67091Mark Salyzynstatic const char conf_file[] = "/system/etc/fs_config_files"; 10968651148dd06da576068749d33a82b5105d67091Mark Salyzyn 1108b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzynstatic const struct fs_path_config android_files[] = { 1118b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00440, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.rc" }, 1128b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.sh" }, 1138b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.ril" }, 1148b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00550, AID_DHCP, AID_SHELL, 0, "system/etc/dhcpcd/dhcpcd-run-hooks" }, 1158b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/ppp/*" }, 1168b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/rc.*" }, 11768651148dd06da576068749d33a82b5105d67091Mark Salyzyn { 00444, AID_ROOT, AID_ROOT, 0, conf_dir + 1 }, 11868651148dd06da576068749d33a82b5105d67091Mark Salyzyn { 00444, AID_ROOT, AID_ROOT, 0, conf_file + 1 }, 1198b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" }, 1208b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00644, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/*" }, 1218b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" }, 1228b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00644, AID_APP, AID_APP, 0, "data/data/*" }, 1238b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 1248b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn /* the following five files are INTENTIONALLY set-uid, but they 1258b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn * are NOT included on user builds. */ 1268b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" }, 1278b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/librank" }, 1288b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procrank" }, 1298b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" }, 1308b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 04770, AID_ROOT, AID_RADIO, 0, "system/bin/pppd-ril" }, 1318b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 1328b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn /* the following files have enhanced capabilities and ARE included in user builds. */ 1338b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00750, AID_ROOT, AID_SHELL, (1ULL << CAP_SETUID) | (1ULL << CAP_SETGID), "system/bin/run-as" }, 1348b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00700, AID_SYSTEM, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND), "system/bin/inputflinger" }, 1358b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 1368b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" }, 1378b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/install-recovery.sh" }, 1388b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" }, 1398b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" }, 1408b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_ROOT, 0, "system/lib64/valgrind/*" }, 1418b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" }, 1428b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor/bin/*" }, 1438b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" }, 1448b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00750, AID_ROOT, AID_SHELL, 0, "sbin/*" }, 1458b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00755, AID_ROOT, AID_ROOT, 0, "bin/*" }, 1468b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00750, AID_ROOT, AID_SHELL, 0, "init*" }, 1478b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00750, AID_ROOT, AID_SHELL, 0, "sbin/fs_mgr" }, 1488b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" }, 1498b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn { 00644, AID_ROOT, AID_ROOT, 0, 0 }, 1508b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn}; 1518b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 152df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudelstatic int fs_config_open(int dir, const char *target_out_path) 15368651148dd06da576068749d33a82b5105d67091Mark Salyzyn{ 15468651148dd06da576068749d33a82b5105d67091Mark Salyzyn int fd = -1; 15568651148dd06da576068749d33a82b5105d67091Mark Salyzyn 156df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel if (target_out_path && *target_out_path) { 157df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel /* target_out_path is the path to the directory holding content of system partition 158df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel but as we cannot guaranty it ends with '/system' we need this below skip_len logic */ 15968651148dd06da576068749d33a82b5105d67091Mark Salyzyn char *name = NULL; 160df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel int target_out_path_len = strlen(target_out_path); 161df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel int skip_len = strlen("/system"); 162df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel 163df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel if (target_out_path[target_out_path_len] == '/') { 164df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel skip_len++; 165df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel } 166df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel asprintf(&name, "%s%s", target_out_path, (dir ? conf_dir : conf_file) + skip_len); 16768651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (name) { 1684232b378e79f4254abc16a4254e2ba1b91851f11Mark Salyzyn fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_BINARY)); 16968651148dd06da576068749d33a82b5105d67091Mark Salyzyn free(name); 17068651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 17168651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 17268651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (fd < 0) { 1734232b378e79f4254abc16a4254e2ba1b91851f11Mark Salyzyn fd = TEMP_FAILURE_RETRY(open(dir ? conf_dir : conf_file, O_RDONLY | O_BINARY)); 17468651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 17568651148dd06da576068749d33a82b5105d67091Mark Salyzyn return fd; 17668651148dd06da576068749d33a82b5105d67091Mark Salyzyn} 17768651148dd06da576068749d33a82b5105d67091Mark Salyzyn 17868651148dd06da576068749d33a82b5105d67091Mark Salyzynstatic bool fs_config_cmp(bool dir, const char *prefix, size_t len, 17968651148dd06da576068749d33a82b5105d67091Mark Salyzyn const char *path, size_t plen) 18068651148dd06da576068749d33a82b5105d67091Mark Salyzyn{ 18168651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (dir) { 18268651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (plen < len) { 18368651148dd06da576068749d33a82b5105d67091Mark Salyzyn return false; 18468651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 18568651148dd06da576068749d33a82b5105d67091Mark Salyzyn } else { 18668651148dd06da576068749d33a82b5105d67091Mark Salyzyn /* If name ends in * then allow partial matches. */ 18768651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (prefix[len - 1] == '*') { 18868651148dd06da576068749d33a82b5105d67091Mark Salyzyn return !strncmp(prefix, path, len - 1); 18968651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 19068651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (plen != len) { 19168651148dd06da576068749d33a82b5105d67091Mark Salyzyn return false; 19268651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 19368651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 19468651148dd06da576068749d33a82b5105d67091Mark Salyzyn return !strncmp(prefix, path, len); 19568651148dd06da576068749d33a82b5105d67091Mark Salyzyn} 19668651148dd06da576068749d33a82b5105d67091Mark Salyzyn 197df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudelvoid fs_config(const char *path, int dir, const char *target_out_path, 1988b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities) 1998b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn{ 2008b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn const struct fs_path_config *pc; 2017977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn int fd, plen; 2028b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 2038b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn if (path[0] == '/') { 2048b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn path++; 2058b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn } 2068b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn 2077e82633106361d628338bcac12d2d269e56a9a71Mark Salyzyn plen = strlen(path); 20868651148dd06da576068749d33a82b5105d67091Mark Salyzyn 209df33ffadd29ed02d87e87515626b673eac67f735Thierry Strudel fd = fs_config_open(dir, target_out_path); 2107977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn if (fd >= 0) { 2117977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn struct fs_path_config_from_file header; 2127977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn 2137977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn while (TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header))) == sizeof(header)) { 2147977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn char *prefix; 2157977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn uint16_t host_len = get2LE((const uint8_t *)&header.len); 2167977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn ssize_t len, remainder = host_len - sizeof(header); 21768651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (remainder <= 0) { 2187977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn ALOGE("%s len is corrupted", dir ? conf_dir : conf_file); 2197977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn break; 2207977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn } 2217977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn prefix = calloc(1, remainder); 2227977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn if (!prefix) { 2237977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn ALOGE("%s out of memory", dir ? conf_dir : conf_file); 22468651148dd06da576068749d33a82b5105d67091Mark Salyzyn break; 22568651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 2267977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn if (TEMP_FAILURE_RETRY(read(fd, prefix, remainder)) != remainder) { 2277977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn free(prefix); 2287977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn ALOGE("%s prefix is truncated", dir ? conf_dir : conf_file); 2297977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn break; 23068651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 2317977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn len = strnlen(prefix, remainder); 23268651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (len >= remainder) { /* missing a terminating null */ 2337977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn free(prefix); 23468651148dd06da576068749d33a82b5105d67091Mark Salyzyn ALOGE("%s is corrupted", dir ? conf_dir : conf_file); 23568651148dd06da576068749d33a82b5105d67091Mark Salyzyn break; 23668651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 2377977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn if (fs_config_cmp(dir, prefix, len, path, plen)) { 2387977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn free(prefix); 2397977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn close(fd); 2407977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn *uid = get2LE((const uint8_t *)&(header.uid)); 2417977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn *gid = get2LE((const uint8_t *)&(header.gid)); 2427977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn *mode = (*mode & (~07777)) | get2LE((const uint8_t *)&(header.mode)); 2437977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn *capabilities = get8LE((const uint8_t *)&(header.capabilities)); 2447977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn return; 24568651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 2467977cc63b1c287158f1b02fe6f437d89f510bb47Mark Salyzyn free(prefix); 2477e82633106361d628338bcac12d2d269e56a9a71Mark Salyzyn } 24868651148dd06da576068749d33a82b5105d67091Mark Salyzyn close(fd); 24968651148dd06da576068749d33a82b5105d67091Mark Salyzyn } 25068651148dd06da576068749d33a82b5105d67091Mark Salyzyn 25168651148dd06da576068749d33a82b5105d67091Mark Salyzyn pc = dir ? android_dirs : android_files; 25268651148dd06da576068749d33a82b5105d67091Mark Salyzyn for(; pc->prefix; pc++){ 25368651148dd06da576068749d33a82b5105d67091Mark Salyzyn if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) { 25468651148dd06da576068749d33a82b5105d67091Mark Salyzyn break; 2558b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn } 2568b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn } 2578b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn *uid = pc->uid; 2588b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn *gid = pc->gid; 2598b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn *mode = (*mode & (~07777)) | pc->mode; 2608b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn *capabilities = pc->capabilities; 2618b2c7dee59f0ca89e6a0866537054a0d41dbae97Mark Salyzyn} 2625d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn 2635d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzynssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc) 2645d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn{ 2655d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn struct fs_path_config_from_file *p = (struct fs_path_config_from_file *)buffer; 2665d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn size_t len = ALIGN(sizeof(*p) + strlen(pc->prefix) + 1, sizeof(uint64_t)); 2675d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn 2685d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn if ((length < len) || (len > UINT16_MAX)) { 2695d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn return -ENOSPC; 2705d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn } 2715d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn memset(p, 0, len); 2725d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn uint16_t host_len = len; 2735d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn p->len = get2LE((const uint8_t *)&host_len); 2745d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn p->mode = get2LE((const uint8_t *)&(pc->mode)); 2755d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn p->uid = get2LE((const uint8_t *)&(pc->uid)); 2765d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn p->gid = get2LE((const uint8_t *)&(pc->gid)); 2775d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn p->capabilities = get8LE((const uint8_t *)&(pc->capabilities)); 2785d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn strcpy(p->prefix, pc->prefix); 2795d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn return len; 2805d9e5efbcdab4a5442e332944765f67eb7005be5Mark Salyzyn} 281