1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef NATIVE_HANDLE_H_
18 #define NATIVE_HANDLE_H_
19 
20 #include <stdalign.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #define NATIVE_HANDLE_MAX_FDS 1024
27 #define NATIVE_HANDLE_MAX_INTS 1024
28 
29 /* Declare a char array for use with native_handle_init */
30 #define NATIVE_HANDLE_DECLARE_STORAGE(name, maxFds, maxInts) \
31     alignas(native_handle_t) char (name)[                            \
32       sizeof(native_handle_t) + sizeof(int) * ((maxFds) + (maxInts))]
33 
34 typedef struct native_handle
35 {
36     int version;        /* sizeof(native_handle_t) */
37     int numFds;         /* number of file-descriptors at &data[0] */
38     int numInts;        /* number of ints at &data[numFds] */
39 #if defined(__clang__)
40 #pragma clang diagnostic push
41 #pragma clang diagnostic ignored "-Wzero-length-array"
42 #endif
43     int data[0];        /* numFds + numInts ints */
44 #if defined(__clang__)
45 #pragma clang diagnostic pop
46 #endif
47 } native_handle_t;
48 
49 typedef const native_handle_t* buffer_handle_t;
50 
51 /*
52  * Closes the file descriptors contained in this native_handle_t, which may
53  * either be untagged or tagged for ownership by this native_handle_t via
54  * native_handle_set_tag(). Mixing untagged and tagged fds in the same
55  * native_handle_t is not permitted and triggers an fdsan exception, but
56  * native_handle_set_fdsan_tag() can be used to bring consistency if this is
57  * intentional.
58  *
59  * If it's known that fds are tagged, prefer native_handle_close_with_tag() for
60  * better safety.
61  *
62  * return 0 on success, or a negative error code on failure
63  */
64 int native_handle_close(const native_handle_t* h);
65 
66 /*
67  * Equivalent to native_handle_close(), but throws an fdsan exception if the fds
68  * are untagged. Use if it's known that the fds in this native_handle_t were
69  * previously tagged via native_handle_set_tag().
70  */
71 int native_handle_close_with_tag(const native_handle_t* h);
72 
73 /*
74  * Initializes a native_handle_t from storage.  storage must be declared with
75  * NATIVE_HANDLE_DECLARE_STORAGE.  numFds and numInts must not respectively
76  * exceed maxFds and maxInts used to declare the storage.
77  */
78 native_handle_t* native_handle_init(char* storage, int numFds, int numInts);
79 
80 /*
81  * Creates a native_handle_t and initializes it. Must be destroyed with
82  * native_handle_delete(). Note that numFds must be <= NATIVE_HANDLE_MAX_FDS,
83  * numInts must be <= NATIVE_HANDLE_MAX_INTS, and both must be >= 0.
84  */
85 native_handle_t* native_handle_create(int numFds, int numInts);
86 
87 /*
88  * Updates the fdsan tag for any file descriptors contained in the supplied
89  * handle to indicate that they are owned by this handle and should only be
90  * closed via native_handle_close()/native_handle_close_with_tag(). Each fd in
91  * the handle must have a tag of either 0 (unset) or the tag associated with
92  * this handle, otherwise an fdsan exception will be triggered.
93  */
94 void native_handle_set_fdsan_tag(const native_handle_t* handle);
95 
96 /*
97  * Clears the fdsan tag for any file descriptors contained in the supplied
98  * native_handle_t. Use if this native_handle_t is giving up ownership of its
99  * fds, but the fdsan tags were previously set. Each fd in the handle must have
100  * a tag of either 0 (unset) or the tag associated with this handle, otherwise
101  * an fdsan exception will be triggered.
102  */
103 void native_handle_unset_fdsan_tag(const native_handle_t* handle);
104 
105 /*
106  * Creates a native_handle_t and initializes it from another native_handle_t.
107  * Must be destroyed with native_handle_delete().
108  */
109 native_handle_t* native_handle_clone(const native_handle_t* handle);
110 
111 /*
112  * Frees a native_handle_t allocated with native_handle_create().
113  * This ONLY frees the memory allocated for the native_handle_t, but doesn't
114  * close the file descriptors; which can be achieved with native_handle_close().
115  *
116  * return 0 on success, or a negative error code on failure
117  */
118 int native_handle_delete(native_handle_t* h);
119 
120 
121 #ifdef __cplusplus
122 }
123 #endif
124 
125 #endif /* NATIVE_HANDLE_H_ */
126