Home | History | Annotate | Download | only in android
      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 <stdbool.h>
     32 #include <stdint.h>
     33 #include <sys/cdefs.h>
     34 
     35 __BEGIN_DECLS
     36 
     37 /*
     38  * Error checking for close(2).
     39  *
     40  * Mishandling of file descriptor ownership is a common source of errors that
     41  * can be extremely difficult to diagnose. Mistakes like the following can
     42  * result in seemingly 'impossible' failures showing up on other threads that
     43  * happened to try to open a file descriptor between the buggy code's close and
     44  * fclose:
     45  *
     46  *     int print(int fd) {
     47  *         int rc;
     48  *         char buf[128];
     49  *         while ((rc = read(fd, buf, sizeof(buf))) > 0) {
     50  *             printf("%.*s", rc);
     51  *         }
     52  *         close(fd);
     53  *     }
     54  *
     55  *     int bug() {
     56  *         FILE* f = fopen("foo", "r");
     57  *         print(fileno(f));
     58  *         fclose(f);
     59  *     }
     60  *
     61  * To make it easier to find this class of bugs, bionic provides a method to
     62  * require that file descriptors are closed by their owners. File descriptors
     63  * can be associated with tags with which they must be closed. This allows
     64  * objects that conceptually own an fd (FILE*, unique_fd, etc.) to use their
     65  * own address at the tag, to enforce that closure of the fd must come as a
     66  * result of their own destruction (fclose, ~unique_fd, etc.)
     67  *
     68  * By default, a file descriptor's tag is 0, and close(fd) is equivalent to
     69  * closing fd with the tag 0.
     70  */
     71 
     72 /*
     73  * For improved diagnostics, the type of a file descriptors owner can be
     74  * encoded in the most significant byte of the owner tag. Values of 0 and 0xff
     75  * are ignored, which allows for raw pointers to be used as owner tags without
     76  * modification.
     77  */
     78 enum android_fdsan_owner_type {
     79   /*
     80    * Generic Java or native owners.
     81    *
     82    * Generic Java objects always use 255 as their type, using identityHashCode
     83    * as the value of the tag, leaving bits 33-56 unset. Native pointers are sign
     84    * extended from 48-bits of virtual address space, and so can have the MSB
     85    * set to 255 as well. Use the value of bits 49-56 to distinguish between
     86    * these cases.
     87    */
     88   ANDROID_FDSAN_OWNER_TYPE_GENERIC_00 = 0,
     89   ANDROID_FDSAN_OWNER_TYPE_GENERIC_FF = 255,
     90 
     91   /* FILE* */
     92   ANDROID_FDSAN_OWNER_TYPE_FILE = 1,
     93 
     94   /* DIR* */
     95   ANDROID_FDSAN_OWNER_TYPE_DIR = 2,
     96 
     97   /* android::base::unique_fd */
     98   ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD = 3,
     99 
    100   /* sqlite-owned file descriptors */
    101   ANDROID_FDSAN_OWNER_TYPE_SQLITE = 4,
    102 
    103   /* java.io.FileInputStream */
    104   ANDROID_FDSAN_OWNER_TYPE_FILEINPUTSTREAM = 5,
    105 
    106   /* java.io.FileOutputStream */
    107   ANDROID_FDSAN_OWNER_TYPE_FILEOUTPUTSTREAM = 6,
    108 
    109   /* java.io.RandomAccessFile */
    110   ANDROID_FDSAN_OWNER_TYPE_RANDOMACCESSFILE = 7,
    111 
    112   /* android.os.ParcelFileDescriptor */
    113   ANDROID_FDSAN_OWNER_TYPE_PARCELFILEDESCRIPTOR = 8,
    114 
    115   /* ART FdFile */
    116   ANDROID_FDSAN_OWNER_TYPE_ART_FDFILE = 9,
    117 
    118   /* java.net.DatagramSocketImpl */
    119   ANDROID_FDSAN_OWNER_TYPE_DATAGRAMSOCKETIMPL = 10,
    120 
    121   /* java.net.SocketImpl */
    122   ANDROID_FDSAN_OWNER_TYPE_SOCKETIMPL = 11,
    123 
    124   /* libziparchive's ZipArchive */
    125   ANDROID_FDSAN_OWNER_TYPE_ZIPARCHIVE = 12,
    126 };
    127 
    128 /*
    129  * Create an owner tag with the specified type and least significant 56 bits of tag.
    130  */
    131 uint64_t android_fdsan_create_owner_tag(enum android_fdsan_owner_type type, uint64_t tag) __INTRODUCED_IN(29) __attribute__((__weak__));
    132 
    133 /*
    134  * Exchange a file descriptor's tag.
    135  *
    136  * Logs and aborts if the fd's tag does not match expected_tag.
    137  */
    138 void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag) __INTRODUCED_IN(29) __attribute__((__weak__));
    139 
    140 /*
    141  * Close a file descriptor with a tag, and resets the tag to 0.
    142  *
    143  * Logs and aborts if the tag is incorrect.
    144  */
    145 int android_fdsan_close_with_tag(int fd, uint64_t tag) __INTRODUCED_IN(29) __attribute__((__weak__));
    146 
    147 /*
    148  * Get a file descriptor's current owner tag.
    149  *
    150  * Returns 0 for untagged and invalid file descriptors.
    151  */
    152 uint64_t android_fdsan_get_owner_tag(int fd) __INTRODUCED_IN(29);
    153 
    154 /*
    155  * Get an owner tag's string representation.
    156  *
    157  * The return value points to memory with static lifetime, do not attempt to modify it.
    158  */
    159 const char* android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
    160 
    161 /*
    162  * Get an owner tag's value, with the type masked off.
    163  */
    164 uint64_t android_fdsan_get_tag_value(uint64_t tag) __INTRODUCED_IN(29);
    165 
    166 enum android_fdsan_error_level {
    167   // No errors.
    168   ANDROID_FDSAN_ERROR_LEVEL_DISABLED,
    169 
    170   // Warn once(ish) on error, and then downgrade to ANDROID_FDSAN_ERROR_LEVEL_DISABLED.
    171   ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE,
    172 
    173   // Warn always on error.
    174   ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS,
    175 
    176   // Abort on error.
    177   ANDROID_FDSAN_ERROR_LEVEL_FATAL,
    178 };
    179 
    180 /*
    181  * Get the error level.
    182  */
    183 enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN(29) __attribute__((__weak__));
    184 
    185 /*
    186  * Set the error level and return the previous state.
    187  *
    188  * Error checking is automatically disabled in the child of a fork, to maintain
    189  * compatibility with code that forks, blindly closes FDs, and then execs.
    190  *
    191  * In cases such as the zygote, where the child has no intention of calling
    192  * exec, call this function to reenable fdsan checks.
    193  *
    194  * This function is not thread-safe and does not synchronize with checks of the
    195  * value, and so should probably only be called in single-threaded contexts
    196  * (e.g. postfork).
    197  */
    198 enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__));
    199 
    200 __END_DECLS
    201