• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 #include <cutils/native_handle.h>
18 
19 #include <errno.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 
25 // Needs to come after stdlib includes to capture the __BIONIC__ definition
26 #ifdef __BIONIC__
27 #include <android/fdsan.h>
28 #endif
29 
30 namespace {
31 
32 #if !defined(__BIONIC__)
33 // fdsan stubs when not linked against bionic
34 #define ANDROID_FDSAN_OWNER_TYPE_NATIVE_HANDLE 0
35 
android_fdsan_create_owner_tag(int,uint64_t)36 uint64_t android_fdsan_create_owner_tag(int /*type*/, uint64_t /*tag*/) {
37     return 0;
38 }
android_fdsan_get_owner_tag(int)39 uint64_t android_fdsan_get_owner_tag(int /*fd*/) {
40     return 0;
41 }
android_fdsan_close_with_tag(int fd,uint64_t)42 int android_fdsan_close_with_tag(int fd, uint64_t /*tag*/) {
43     return close(fd);
44 }
android_fdsan_exchange_owner_tag(int,uint64_t,uint64_t)45 void android_fdsan_exchange_owner_tag(int /*fd*/, uint64_t /*expected_tag*/, uint64_t /*tag*/) {}
46 #endif  // !__BIONIC__
47 
get_fdsan_tag(const native_handle_t * handle)48 uint64_t get_fdsan_tag(const native_handle_t* handle) {
49     return android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_NATIVE_HANDLE,
50                                           reinterpret_cast<uint64_t>(handle));
51 }
52 
close_internal(const native_handle_t * h,bool allowUntagged)53 int close_internal(const native_handle_t* h, bool allowUntagged) {
54     if (!h) return 0;
55 
56     if (h->version != sizeof(native_handle_t)) return -EINVAL;
57 
58     const int numFds = h->numFds;
59     uint64_t tag;
60     if (allowUntagged && numFds > 0 && android_fdsan_get_owner_tag(h->data[0]) == 0) {
61         tag = 0;
62     } else {
63         tag = get_fdsan_tag(h);
64     }
65     int saved_errno = errno;
66     for (int i = 0; i < numFds; ++i) {
67         android_fdsan_close_with_tag(h->data[i], tag);
68     }
69     errno = saved_errno;
70     return 0;
71 }
72 
swap_fdsan_tags(const native_handle_t * handle,uint64_t expected_tag,uint64_t new_tag)73 void swap_fdsan_tags(const native_handle_t* handle, uint64_t expected_tag, uint64_t new_tag) {
74     if (!handle || handle->version != sizeof(native_handle_t)) return;
75 
76     for (int i = 0; i < handle->numFds; i++) {
77         // allow for idempotence to make the APIs easier to use
78         if (android_fdsan_get_owner_tag(handle->data[i]) != new_tag) {
79             android_fdsan_exchange_owner_tag(handle->data[i], expected_tag, new_tag);
80         }
81     }
82 }
83 
84 }  // anonymous namespace
85 
native_handle_init(char * storage,int numFds,int numInts)86 native_handle_t* native_handle_init(char* storage, int numFds, int numInts) {
87     if ((uintptr_t)storage % alignof(native_handle_t)) {
88         errno = EINVAL;
89         return NULL;
90     }
91 
92     native_handle_t* handle = (native_handle_t*)storage;
93     handle->version = sizeof(native_handle_t);
94     handle->numFds = numFds;
95     handle->numInts = numInts;
96     return handle;
97 }
98 
native_handle_create(int numFds,int numInts)99 native_handle_t* native_handle_create(int numFds, int numInts) {
100     if (numFds < 0 || numInts < 0 || numFds > NATIVE_HANDLE_MAX_FDS ||
101         numInts > NATIVE_HANDLE_MAX_INTS) {
102         errno = EINVAL;
103         return NULL;
104     }
105 
106     size_t mallocSize = sizeof(native_handle_t) + (sizeof(int) * (numFds + numInts));
107     native_handle_t* h = static_cast<native_handle_t*>(malloc(mallocSize));
108     if (h) {
109         h->version = sizeof(native_handle_t);
110         h->numFds = numFds;
111         h->numInts = numInts;
112     }
113     return h;
114 }
115 
native_handle_set_fdsan_tag(const native_handle_t * handle)116 void native_handle_set_fdsan_tag(const native_handle_t* handle) {
117     swap_fdsan_tags(handle, 0, get_fdsan_tag(handle));
118 }
119 
native_handle_unset_fdsan_tag(const native_handle_t * handle)120 void native_handle_unset_fdsan_tag(const native_handle_t* handle) {
121     swap_fdsan_tags(handle, get_fdsan_tag(handle), 0);
122 }
123 
native_handle_clone(const native_handle_t * handle)124 native_handle_t* native_handle_clone(const native_handle_t* handle) {
125     native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
126     if (clone == NULL) return NULL;
127 
128     for (int i = 0; i < handle->numFds; i++) {
129         clone->data[i] = dup(handle->data[i]);
130         if (clone->data[i] == -1) {
131             clone->numFds = i;
132             native_handle_close(clone);
133             native_handle_delete(clone);
134             return NULL;
135         }
136     }
137 
138     memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
139            sizeof(int) * handle->numInts);
140 
141     return clone;
142 }
143 
native_handle_delete(native_handle_t * h)144 int native_handle_delete(native_handle_t* h) {
145     if (h) {
146         if (h->version != sizeof(native_handle_t)) return -EINVAL;
147         free(h);
148     }
149     return 0;
150 }
151 
native_handle_close(const native_handle_t * h)152 int native_handle_close(const native_handle_t* h) {
153     return close_internal(h, /*allowUntagged=*/true);
154 }
155 
native_handle_close_with_tag(const native_handle_t * h)156 int native_handle_close_with_tag(const native_handle_t* h) {
157     return close_internal(h, /*allowUntagged=*/false);
158 }
159