10b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn/* 20b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * Copyright (C) 2016 The Android Open Source Project 30b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * All rights reserved. 40b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * 50b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * Redistribution and use in source and binary forms, with or without 60b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * modification, are permitted provided that the following conditions 70b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * are met: 80b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * * Redistributions of source code must retain the above copyright 90b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * notice, this list of conditions and the following disclaimer. 100b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * * Redistributions in binary form must reproduce the above copyright 110b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * notice, this list of conditions and the following disclaimer in 120b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * the documentation and/or other materials provided with the 130b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * distribution. 140b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * 150b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 160b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 170b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 180b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 190b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 200b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 210b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 220b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 230b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 240b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 250b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 260b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn * SUCH DAMAGE. 270b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn */ 280b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <ctype.h> 290b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <errno.h> 300b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <fcntl.h> 310b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <limits.h> 320b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <stdio.h> 330b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <stdlib.h> 340b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <string.h> 350b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <sys/stat.h> 360b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <sys/types.h> 370b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#include <unistd.h> 380b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 3952bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn#include <cutils/android_get_control_file.h> 400b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 4152bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn#include "android_get_control_env.h" 420b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 436b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn#ifndef TEMP_FAILURE_RETRY 446b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn#define TEMP_FAILURE_RETRY(exp) (exp) // KISS implementation 456b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn#endif 466b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn 4752bd37e63373b410c009e8611508191dfbf31d30Mark SalyzynLIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix, 4852bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn const char* name) { 4952bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn if (!prefix || !name) return -1; 500b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 510b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn char *key = NULL; 5252bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn if (asprintf(&key, "%s%s", prefix, name) < 0) return -1; 530b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (!key) return -1; 540b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 550b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn char *cp = key; 560b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn while (*cp) { 570b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (!isalnum(*cp)) *cp = '_'; 580b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn ++cp; 590b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn } 600b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 610b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn const char* val = getenv(key); 620b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn free(key); 630b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (!val) return -1; 640b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 650b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn errno = 0; 660b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn long fd = strtol(val, NULL, 10); 670b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (errno) return -1; 680b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 690b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn // validity checking 700b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if ((fd < 0) || (fd > INT_MAX)) return -1; 710b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 7252bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn // Since we are inheriting an fd, it could legitimately exceed _SC_OPEN_MAX 7352bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn 7452bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn // Still open? 756b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn#if defined(F_GETFD) // Lowest overhead 760b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1; 776b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn#elif defined(F_GETFL) // Alternate lowest overhead 786b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1; 7952bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn#else // Hail Mary pass 800b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn struct stat s; 816b652160d1f33ecb31663224813c57288f7008e1Mark Salyzyn if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1; 820b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#endif 830b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 8452bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn return static_cast<int>(fd); 8552bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn} 8652bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn 8752bd37e63373b410c009e8611508191dfbf31d30Mark Salyzynint android_get_control_file(const char* path) { 8852bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn int fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path); 8952bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn 900b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#if defined(__linux__) 9152bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn // Find file path from /proc and make sure it is correct 920b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn char *proc = NULL; 9352bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn if (asprintf(&proc, "/proc/self/fd/%d", fd) < 0) return -1; 940b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (!proc) return -1; 950b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 960b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn size_t len = strlen(path); 9752bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn // readlink() does not guarantee a nul byte, len+2 so we catch truncation. 980b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn char *buf = static_cast<char *>(calloc(1, len + 2)); 990b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (!buf) { 1000b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn free(proc); 1010b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn return -1; 1020b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn } 1030b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn ssize_t ret = TEMP_FAILURE_RETRY(readlink(proc, buf, len + 1)); 1040b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn free(proc); 1050b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn int cmp = (len != static_cast<size_t>(ret)) || strcmp(buf, path); 1060b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn free(buf); 1070b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (ret < 0) return -1; 1080b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn if (cmp != 0) return -1; 10952bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn // It is what we think it is 1100b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn#endif 1110b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn 11252bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn return fd; 1130b034d9d7b1af4e2f608ddf2dc2a0e08773e69acMark Salyzyn} 114