1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "base/buffer_util.h"
17 #include <unistd.h>
18 #include "hdf_log.h"
19 #include "osal_mem.h"
20 #include "securec.h"
21
22 #define HDF_LOG_TAG buffer_util
23
AllocateNativeBufferHandle(uint32_t reserveFds,uint32_t reserveInts)24 BufferHandle *AllocateNativeBufferHandle(uint32_t reserveFds, uint32_t reserveInts)
25 {
26 if (reserveFds > MAX_RESERVE_FDS || reserveInts > MAX_RESERVE_INTS) {
27 HDF_LOGE("%{public}s: illegal reserveFds or reserveInts", __func__);
28 return NULL;
29 }
30
31 size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
32 BufferHandle *handle = (BufferHandle *)(OsalMemCalloc(handleSize));
33 if (handle != NULL) {
34 handle->fd = -1;
35 handle->reserveFds = reserveFds;
36 handle->reserveInts = reserveInts;
37 for (uint32_t i = 0; i < reserveFds; i++) {
38 handle->reserve[i] = -1;
39 }
40 } else {
41 HDF_LOGE("BufferHandle malloc %zu failed", handleSize);
42 }
43 return handle;
44 }
45
CloneNativeBufferHandle(const BufferHandle * other)46 BufferHandle *CloneNativeBufferHandle(const BufferHandle *other)
47 {
48 if (other == NULL) {
49 HDF_LOGW("%{public}s handle is NULL", __func__);
50 return NULL;
51 }
52
53 BufferHandle *handle = AllocateNativeBufferHandle(other->reserveFds, other->reserveInts);
54 if (handle == NULL) {
55 HDF_LOGW("%{public}s AllocateBufferHandle failed, handle is NULL", __func__);
56 return NULL;
57 }
58
59 if (other->fd == -1) {
60 handle->fd = other->fd;
61 } else {
62 handle->fd = dup(other->fd);
63 if (handle->fd == -1) {
64 HDF_LOGE("CloneBufferHandle dup failed");
65 FreeNativeBufferHandle(handle);
66 return NULL;
67 }
68 }
69 handle->width = other->width;
70 handle->stride = other->stride;
71 handle->height = other->height;
72 handle->size = other->size;
73 handle->format = other->format;
74 handle->usage = other->usage;
75 handle->phyAddr = other->phyAddr;
76
77 for (uint32_t i = 0; i < handle->reserveFds; i++) {
78 handle->reserve[i] = dup(other->reserve[i]);
79 if (handle->reserve[i] == -1) {
80 HDF_LOGE("CloneBufferHandle dup reserveFds failed");
81 FreeNativeBufferHandle(handle);
82 return NULL;
83 }
84 }
85
86 if (other->reserveInts == 0) {
87 return handle;
88 }
89
90 if (memcpy_s(&handle->reserve[handle->reserveFds], sizeof(int32_t) * handle->reserveInts,
91 &other->reserve[other->reserveFds], sizeof(int32_t) * other->reserveInts) != EOK) {
92 HDF_LOGE("CloneBufferHandle memcpy_s failed");
93 FreeNativeBufferHandle(handle);
94 return NULL;
95 }
96 return handle;
97 }
98
FreeNativeBufferHandle(BufferHandle * handle)99 void FreeNativeBufferHandle(BufferHandle *handle)
100 {
101 if (handle == NULL) {
102 return;
103 }
104
105 if (handle->fd != -1) {
106 close(handle->fd);
107 handle->fd = -1;
108 }
109
110 for (uint32_t i = 0; i < handle->reserveFds; i++) {
111 if (handle->reserve[i] != -1) {
112 close(handle->reserve[i]);
113 handle->reserve[i] = -1;
114 }
115 }
116 OsalMemFree(handle);
117 }
118
HdfSbufWriteNativeBufferHandle(struct HdfSBuf * data,const BufferHandle * handle)119 bool HdfSbufWriteNativeBufferHandle(struct HdfSBuf *data, const BufferHandle *handle)
120 {
121 if (data == NULL) {
122 HDF_LOGE("%{public}s: invalid sbuf", __func__);
123 return false;
124 }
125
126 if (handle == NULL) {
127 HDF_LOGE("%{public}s: write invalid handle", __func__);
128 return false;
129 }
130
131 if (!HdfSbufWriteUint32(data, handle->reserveFds) || !HdfSbufWriteUint32(data, handle->reserveInts) ||
132 !HdfSbufWriteInt32(data, handle->width) || !HdfSbufWriteInt32(data, handle->stride) ||
133 !HdfSbufWriteInt32(data, handle->height) || !HdfSbufWriteInt32(data, handle->size) ||
134 !HdfSbufWriteInt32(data, handle->format) || !HdfSbufWriteUint64(data, handle->usage)) {
135 HDF_LOGE("%{public}s a lot failed", __func__);
136 return false;
137 }
138
139 bool validFd = (handle->fd >= 0);
140 if (!HdfSbufWriteInt8(data, validFd ? 1 : 0)) {
141 HDF_LOGE("%{public}s: failed to write valid flag of fd", __func__);
142 return false;
143 }
144 if (validFd && !HdfSbufWriteFileDescriptor(data, handle->fd)) {
145 HDF_LOGE("%{public}s: failed to write fd", __func__);
146 return false;
147 }
148
149 for (uint32_t i = 0; i < handle->reserveFds; i++) {
150 if (!HdfSbufWriteFileDescriptor(data, handle->reserve[i])) {
151 HDF_LOGE("%{public}s: failed to write reserved fd value", __func__);
152 return false;
153 }
154 }
155 for (uint32_t j = 0; j < handle->reserveInts; j++) {
156 if (!HdfSbufWriteInt32(data, handle->reserve[handle->reserveFds + j])) {
157 HDF_LOGE("%{public}s: failed to write reserved integer value", __func__);
158 return false;
159 }
160 }
161 return true;
162 }
163
ReadReserveData(struct HdfSBuf * data,BufferHandle * handle)164 static bool ReadReserveData(struct HdfSBuf *data, BufferHandle *handle)
165 {
166 for (uint32_t i = 0; i < handle->reserveFds; i++) {
167 handle->reserve[i] = HdfSbufReadFileDescriptor(data);
168 if (handle->reserve[i] == -1) {
169 HDF_LOGE("%{public}s: failed to read reserved fd value", __func__);
170 return false;
171 }
172 }
173 for (uint32_t j = 0; j < handle->reserveInts; j++) {
174 if (!HdfSbufReadInt32(data, &(handle->reserve[handle->reserveFds + j]))) {
175 HDF_LOGE("%{public}s: failed to read reserved integer value", __func__);
176 return false;
177 }
178 }
179 return true;
180 }
181
HdfSbufReadNativeBufferHandle(struct HdfSBuf * data)182 BufferHandle *HdfSbufReadNativeBufferHandle(struct HdfSBuf *data)
183 {
184 if (data == NULL) {
185 HDF_LOGE("%{public}s: invalid sbuf", __func__);
186 return NULL;
187 }
188
189 uint32_t reserveFds = 0;
190 uint32_t reserveInts = 0;
191 if (!HdfSbufReadUint32(data, &reserveFds) || !HdfSbufReadUint32(data, &reserveInts)) {
192 HDF_LOGE("%{public}s: failed to read reserveFds or reserveInts", __func__);
193 return NULL;
194 }
195
196 BufferHandle *handle = AllocateNativeBufferHandle(reserveFds, reserveInts);
197 if (handle == NULL) {
198 HDF_LOGE("%{public}s: failed to malloc BufferHandle", __func__);
199 return NULL;
200 }
201
202 if (!HdfSbufReadInt32(data, &handle->width) || !HdfSbufReadInt32(data, &handle->stride) ||
203 !HdfSbufReadInt32(data, &handle->height) || !HdfSbufReadInt32(data, &handle->size) ||
204 !HdfSbufReadInt32(data, &handle->format) || !HdfSbufReadUint64(data, &handle->usage)) {
205 HDF_LOGE("%{public}s: failed to read a lot", __func__);
206 FreeNativeBufferHandle(handle);
207 return NULL;
208 }
209
210 bool validFd = false;
211 if (!HdfSbufReadInt8(data, (int8_t *)&validFd)) {
212 HDF_LOGE("%{public}s: failed to read valid flag of fd", __func__);
213 FreeNativeBufferHandle(handle);
214 return NULL;
215 }
216 if (validFd) {
217 handle->fd = HdfSbufReadFileDescriptor(data);
218 if (handle->fd == -1) {
219 HDF_LOGE("%{public}s: failed to read fd", __func__);
220 FreeNativeBufferHandle(handle);
221 return NULL;
222 }
223 }
224
225 if (!ReadReserveData(data, handle)) {
226 FreeNativeBufferHandle(handle);
227 return NULL;
228 }
229 return handle;
230 }
231