1 /*
2 * Copyright (c) 2021 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 "buffer_handle.h"
17 #include "buffer_handle_utils.h"
18
19 #include <cstdlib>
20 #include <securec.h>
21
22 #include <hilog/log.h>
23 #include <message_parcel.h>
24 #include <unistd.h>
25
26 #undef LOG_DOMAIN
27 #define LOG_DOMAIN 0xD001400
28 #undef LOG_TAG
29 #define LOG_TAG "graphicutils"
30 #define UTILS_LOGF(...) (void)HILOG_FATAL(LOG_CORE, __VA_ARGS__)
31 #define UTILS_LOGE(...) (void)HILOG_ERROR(LOG_CORE, __VA_ARGS__)
32 #define UTILS_LOGW(...) (void)HILOG_WARN(LOG_CORE, __VA_ARGS__)
33 #define UTILS_LOGI(...) (void)HILOG_INFO(LOG_CORE, __VA_ARGS__)
34 #define UTILS_LOGD(...) (void)HILOG_DEBUG(LOG_CORE, __VA_ARGS__)
35 #define BUFFER_HANDLE_RESERVE_MAX_SIZE 1024
36
AllocateBufferHandle(uint32_t reserveFds,uint32_t reserveInts)37 BufferHandle *AllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts)
38 {
39 if (reserveFds > BUFFER_HANDLE_RESERVE_MAX_SIZE || reserveInts > BUFFER_HANDLE_RESERVE_MAX_SIZE) {
40 UTILS_LOGE("AllocateBufferHandle reserveFds or reserveInts too lager");
41 return nullptr;
42 }
43 size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
44 BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
45 if (handle != nullptr) {
46 errno_t ret = memset_s(handle, handleSize, 0, handleSize);
47 if (ret != 0) {
48 UTILS_LOGE("memset_s error, ret is %{public}d", ret);
49 free(handle);
50 return nullptr;
51 }
52 handle->fd = -1;
53 for (uint32_t i = 0; i < reserveFds; i++) {
54 handle->reserve[i] = -1;
55 }
56 handle->reserveFds = reserveFds;
57 handle->reserveInts = reserveInts;
58 } else {
59 UTILS_LOGE("AllocateBufferHandle malloc %{public}zu failed", handleSize);
60 }
61 return handle;
62 }
63
FreeBufferHandle(BufferHandle * handle)64 int32_t FreeBufferHandle(BufferHandle *handle)
65 {
66 if (handle == nullptr) {
67 UTILS_LOGW("FreeBufferHandle with nullptr handle");
68 return 0;
69 }
70 if (handle->fd >= 0) {
71 close(handle->fd);
72 handle->fd = -1;
73 }
74 const uint32_t reserveFds = handle->reserveFds;
75 for (uint32_t i = 0; i < reserveFds; i++) {
76 if (handle->reserve[i] >= 0) {
77 close(handle->reserve[i]);
78 handle->reserve[i] = -1;
79 }
80 }
81 free(handle);
82 return 0;
83 }
84
85 namespace OHOS {
WriteBufferHandle(MessageParcel & parcel,const BufferHandle & handle)86 bool WriteBufferHandle(MessageParcel &parcel, const BufferHandle &handle)
87 {
88 if (!parcel.WriteUint32(handle.reserveFds) || !parcel.WriteUint32(handle.reserveInts) ||
89 !parcel.WriteInt32(handle.width) || !parcel.WriteInt32(handle.stride) || !parcel.WriteInt32(handle.height) ||
90 !parcel.WriteInt32(handle.size) || !parcel.WriteInt32(handle.format) || !parcel.WriteInt64(handle.usage) ||
91 !parcel.WriteUint64(handle.phyAddr)) {
92 UTILS_LOGE("%{public}s a lot failed", __func__);
93 return false;
94 }
95 bool validFd = (handle.fd >= 0);
96 if (!parcel.WriteBool(validFd)) {
97 UTILS_LOGE("%{public}s parcel.WriteBool failed", __func__);
98 return false;
99 }
100 if (validFd && !parcel.WriteFileDescriptor(handle.fd)) {
101 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor fd failed", __func__);
102 return false;
103 }
104
105 for (uint32_t i = 0; i < handle.reserveFds; i++) {
106 if (!parcel.WriteFileDescriptor(handle.reserve[i])) {
107 UTILS_LOGE("%{public}s parcel.WriteFileDescriptor reserveFds failed", __func__);
108 return false;
109 }
110 }
111 for (uint32_t j = 0; j < handle.reserveInts; j++) {
112 if (!parcel.WriteInt32(handle.reserve[handle.reserveFds + j])) {
113 UTILS_LOGE("%{public}s parcel.WriteInt32 reserve failed", __func__);
114 return false;
115 }
116 }
117 return true;
118 }
119
ReadBufferHandle(MessageParcel & parcel,std::function<int (MessageParcel & parcel,std::function<int (Parcel &)> readFdDefaultFunc)> readSafeFdFunc)120 BufferHandle *ReadBufferHandle(MessageParcel &parcel,
121 std::function<int(MessageParcel &parcel, std::function<int(Parcel &)> readFdDefaultFunc)> readSafeFdFunc)
122 {
123 uint32_t reserveFds = 0;
124 uint32_t reserveInts = 0;
125 if (!parcel.ReadUint32(reserveFds) || !parcel.ReadUint32(reserveInts)) {
126 UTILS_LOGE("%{public}s parcel.ReadUint32 reserveFds failed", __func__);
127 return nullptr;
128 }
129
130 BufferHandle *handle = AllocateBufferHandle(reserveFds, reserveInts);
131 if (handle == nullptr) {
132 UTILS_LOGE("%{public}s AllocateBufferHandle failed", __func__);
133 return nullptr;
134 }
135
136 if (!parcel.ReadInt32(handle->width) || !parcel.ReadInt32(handle->stride) || !parcel.ReadInt32(handle->height) ||
137 !parcel.ReadInt32(handle->size) || !parcel.ReadInt32(handle->format) || !parcel.ReadUint64(handle->usage) ||
138 !parcel.ReadUint64(handle->phyAddr)) {
139 UTILS_LOGE("%{public}s a lot failed", __func__);
140 FreeBufferHandle(handle);
141 return nullptr;
142 }
143
144 bool validFd = false;
145 if (!parcel.ReadBool(validFd)) {
146 UTILS_LOGE("%{public}s ReadBool validFd failed", __func__);
147 FreeBufferHandle(handle);
148 return nullptr;
149 }
150
151 auto readFdDefaultFunc = [] (Parcel &parcel) -> int {
152 MessageParcel *msgParcel = static_cast<MessageParcel *>(&parcel);
153 return msgParcel->ReadFileDescriptor();
154 };
155
156 if (validFd) {
157 handle->fd = readSafeFdFunc ? readSafeFdFunc(parcel, readFdDefaultFunc) : parcel.ReadFileDescriptor();
158 if (handle->fd == -1) {
159 UTILS_LOGE("%{public}s ReadFileDescriptor fd failed, is use readSafeFdFunc:%d",
160 __func__, readSafeFdFunc != nullptr);
161 FreeBufferHandle(handle);
162 return nullptr;
163 }
164 }
165
166 for (uint32_t i = 0; i < handle->reserveFds; i++) {
167 handle->reserve[i] = readSafeFdFunc ? readSafeFdFunc(parcel, readFdDefaultFunc) : parcel.ReadFileDescriptor();
168 if (handle->reserve[i] == -1) {
169 UTILS_LOGE("%{public}s ReadFileDescriptor reserve failed, is use readSafeFdFunc:%d",
170 __func__, readSafeFdFunc != nullptr);
171 FreeBufferHandle(handle);
172 return nullptr;
173 }
174 }
175 for (uint32_t j = 0; j < handle->reserveInts; j++) {
176 if (!parcel.ReadInt32(handle->reserve[reserveFds + j])) {
177 UTILS_LOGE("%{public}s ReadInt32 reserve failed", __func__);
178 FreeBufferHandle(handle);
179 return nullptr;
180 }
181 }
182 return handle;
183 }
184 } // namespace OHOS
185