1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #pragma once 30 31 #include <sys/cdefs.h> 32 33 #include <stdbool.h> 34 #include <stdint.h> 35 36 __BEGIN_DECLS 37 38 /* 39 * Error checking for close(2). 40 * 41 * Mishandling of file descriptor ownership is a common source of errors that 42 * can be extremely difficult to diagnose. Mistakes like the following can 43 * result in seemingly 'impossible' failures showing up on other threads that 44 * happened to try to open a file descriptor between the buggy code's close and 45 * fclose: 46 * 47 * int print(int fd) { 48 * int rc; 49 * char buf[128]; 50 * while ((rc = read(fd, buf, sizeof(buf))) > 0) { 51 * printf("%.*s", rc); 52 * } 53 * close(fd); 54 * } 55 * 56 * int bug() { 57 * FILE* f = fopen("foo", "r"); 58 * print(fileno(f)); 59 * fclose(f); 60 * } 61 * 62 * To make it easier to find this class of bugs, bionic provides a method to 63 * require that file descriptors are closed by their owners. File descriptors 64 * can be associated with tags with which they must be closed. This allows 65 * objects that conceptually own an fd (FILE*, unique_fd, etc.) to use their 66 * own address at the tag, to enforce that closure of the fd must come as a 67 * result of their own destruction (fclose, ~unique_fd, etc.) 68 * 69 * By default, a file descriptor's tag is 0, and close(fd) is equivalent to 70 * closing fd with the tag 0. 71 */ 72 73 /* 74 * For improved diagnostics, the type of a file descriptors owner can be 75 * encoded in the most significant byte of the owner tag. Values of 0 and 0xff 76 * are ignored, which allows for raw pointers to be used as owner tags without 77 * modification. 78 */ 79 enum android_fdsan_owner_type { 80 /* 81 * Generic Java or native owners. 82 * 83 * Generic Java objects always use 255 as their type, using identityHashCode 84 * as the value of the tag, leaving bits 33-56 unset. Native pointers are sign 85 * extended from 48-bits of virtual address space, and so can have the MSB 86 * set to 255 as well. Use the value of bits 49-56 to distinguish between 87 * these cases. 88 */ 89 ANDROID_FDSAN_OWNER_TYPE_GENERIC_00 = 0, 90 ANDROID_FDSAN_OWNER_TYPE_GENERIC_FF = 255, 91 92 /* FILE* */ 93 ANDROID_FDSAN_OWNER_TYPE_FILE = 1, 94 95 /* DIR* */ 96 ANDROID_FDSAN_OWNER_TYPE_DIR = 2, 97 98 /* android::base::unique_fd */ 99 ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD = 3, 100 101 /* sqlite-owned file descriptors */ 102 ANDROID_FDSAN_OWNER_TYPE_SQLITE = 4, 103 104 /* java.io.FileInputStream */ 105 ANDROID_FDSAN_OWNER_TYPE_FILEINPUTSTREAM = 5, 106 107 /* java.io.FileOutputStream */ 108 ANDROID_FDSAN_OWNER_TYPE_FILEOUTPUTSTREAM = 6, 109 110 /* java.io.RandomAccessFile */ 111 ANDROID_FDSAN_OWNER_TYPE_RANDOMACCESSFILE = 7, 112 113 /* android.os.ParcelFileDescriptor */ 114 ANDROID_FDSAN_OWNER_TYPE_PARCELFILEDESCRIPTOR = 8, 115 116 /* ART FdFile */ 117 ANDROID_FDSAN_OWNER_TYPE_ART_FDFILE = 9, 118 119 /* java.net.DatagramSocketImpl */ 120 ANDROID_FDSAN_OWNER_TYPE_DATAGRAMSOCKETIMPL = 10, 121 122 /* java.net.SocketImpl */ 123 ANDROID_FDSAN_OWNER_TYPE_SOCKETIMPL = 11, 124 125 /* libziparchive's ZipArchive */ 126 ANDROID_FDSAN_OWNER_TYPE_ZIPARCHIVE = 12, 127 128 /* native_handle_t */ 129 ANDROID_FDSAN_OWNER_TYPE_NATIVE_HANDLE = 13, 130 131 /* android::Parcel */ 132 ANDROID_FDSAN_OWNER_TYPE_PARCEL = 14, 133 }; 134 135 /* 136 * Create an owner tag with the specified type and least significant 56 bits of tag. 137 */ 138 139 #if __BIONIC_AVAILABILITY_GUARD(29) 140 uint64_t android_fdsan_create_owner_tag(enum android_fdsan_owner_type type, uint64_t tag) __INTRODUCED_IN(29) __attribute__((__weak__)); 141 142 /* 143 * Exchange a file descriptor's tag. 144 * 145 * Logs and aborts if the fd's tag does not match expected_tag. 146 */ 147 void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag) __INTRODUCED_IN(29) __attribute__((__weak__)); 148 149 /* 150 * Close a file descriptor with a tag, and resets the tag to 0. 151 * 152 * Logs and aborts if the tag is incorrect. 153 */ 154 int android_fdsan_close_with_tag(int fd, uint64_t tag) __INTRODUCED_IN(29) __attribute__((__weak__)); 155 156 /* 157 * Get a file descriptor's current owner tag. 158 * 159 * Returns 0 for untagged and invalid file descriptors. 160 */ 161 uint64_t android_fdsan_get_owner_tag(int fd) __INTRODUCED_IN(29); 162 163 /* 164 * Get an owner tag's string representation. 165 * 166 * The return value points to memory with static lifetime, do not attempt to modify it. 167 */ 168 const char* _Nonnull android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29); 169 170 /* 171 * Get an owner tag's value, with the type masked off. 172 */ 173 uint64_t android_fdsan_get_tag_value(uint64_t tag) __INTRODUCED_IN(29); 174 #endif /* __BIONIC_AVAILABILITY_GUARD(29) */ 175 176 177 enum android_fdsan_error_level { 178 // No errors. 179 ANDROID_FDSAN_ERROR_LEVEL_DISABLED, 180 181 // Warn once(ish) on error, and then downgrade to ANDROID_FDSAN_ERROR_LEVEL_DISABLED. 182 ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE, 183 184 // Warn always on error. 185 ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS, 186 187 // Abort on error. 188 ANDROID_FDSAN_ERROR_LEVEL_FATAL, 189 }; 190 191 /* 192 * Get the error level. 193 */ 194 195 #if __BIONIC_AVAILABILITY_GUARD(29) 196 enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN(29) __attribute__((__weak__)); 197 198 /* 199 * Set the error level and return the previous state. 200 * 201 * Error checking is automatically disabled in the child of a fork, to maintain 202 * compatibility with code that forks, closes all file descriptors, and then 203 * execs. 204 * 205 * In cases such as the zygote, where the child has no intention of calling 206 * exec, call this function to reenable fdsan checks. 207 * 208 * This function is not thread-safe and does not synchronize with checks of the 209 * value, and so should probably only be called in single-threaded contexts 210 * (e.g. postfork). 211 */ 212 enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__)); 213 #endif /* __BIONIC_AVAILABILITY_GUARD(29) */ 214 215 216 /* 217 * Set the error level to the global setting if available, or a default value. 218 */ 219 220 #if __BIONIC_AVAILABILITY_GUARD(30) 221 enum android_fdsan_error_level android_fdsan_set_error_level_from_property(enum android_fdsan_error_level default_level) __INTRODUCED_IN(30) __attribute__((__weak__)); 222 #endif /* __BIONIC_AVAILABILITY_GUARD(30) */ 223 224 __END_DECLS 225