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