• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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