1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "hdf_log.h"
10 #include "hdf_sbuf.h"
11 #include "hdf_sbuf_impl.h"
12 #include "osal_mem.h"
13 #include "securec.h"
14 
15 #define HDF_LOG_TAG                hdf_sbuf_impl_raw
16 #define HDF_SBUF_GROW_SIZE_DEFAULT 256
17 #define HDF_SBUF_MAX_SIZE          (512 * 1024) // 512KB
18 #define HDF_SBUF_ALIGN             4
19 
20 #ifndef INT16_MAX
21 #ifdef S16_MAX
22 #define INT16_MAX S16_MAX
23 #else
24 #define INT16_MAX 32767
25 #endif // !S16_MAX
26 #endif // INT16_MAX
27 
28 struct HdfSBufRaw {
29     struct HdfSBufImpl infImpl;
30     size_t writePos; /**< Current write position */
31     size_t readPos;  /**< Current read position */
32     size_t capacity; /**< Storage capacity, 512 KB at most. */
33     uint8_t *data;   /**< Pointer to data storage */
34     bool isBind;     /**< Whether to bind the externally transferred pointer to data storage */
35 };
36 
37 #define SBUF_RAW_CAST(impl) (struct HdfSBufRaw *)(impl)
38 
39 static struct HdfSBufRaw *SbufRawImplNewInstance(size_t capacity);
40 static void SbufInterfaceAssign(struct HdfSBufImpl *inf);
41 
SbufRawImplGetAlignSize(size_t size)42 static size_t SbufRawImplGetAlignSize(size_t size)
43 {
44     if (size > (SIZE_MAX - HDF_SBUF_ALIGN)) {
45         HDF_LOGE("Be careful of integer overflow!");
46         return 0;
47     }
48     return (size + HDF_SBUF_ALIGN - 1) & (~(HDF_SBUF_ALIGN - 1));
49 }
50 
SbufRawImplRecycle(struct HdfSBufImpl * impl)51 static void SbufRawImplRecycle(struct HdfSBufImpl *impl)
52 {
53     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
54     if (sbuf != NULL) {
55         if (sbuf->data != NULL && !sbuf->isBind) {
56             OsalMemFree(sbuf->data);
57         }
58         OsalMemFree(sbuf);
59     }
60 }
61 
SbufRawImplGetLeftWriteSize(struct HdfSBufRaw * sbuf)62 static size_t SbufRawImplGetLeftWriteSize(struct HdfSBufRaw *sbuf)
63 {
64     return (sbuf->capacity < sbuf->writePos) ? 0 : (sbuf->capacity - sbuf->writePos);
65 }
66 
SbufRawImplGetLeftReadSize(struct HdfSBufRaw * sbuf)67 static size_t SbufRawImplGetLeftReadSize(struct HdfSBufRaw *sbuf)
68 {
69     return (sbuf->writePos < sbuf->readPos) ? 0 : (sbuf->writePos - sbuf->readPos);
70 }
71 
SbufRawImplWriteRollback(struct HdfSBufImpl * impl,uint32_t size)72 static bool SbufRawImplWriteRollback(struct HdfSBufImpl *impl, uint32_t size)
73 {
74     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
75     size_t alignSize;
76     if (sbuf == NULL) {
77         return false;
78     }
79 
80     alignSize = SbufRawImplGetAlignSize(size);
81     if (sbuf->writePos < alignSize) {
82         return false;
83     }
84 
85     sbuf->writePos -= alignSize;
86     return true;
87 }
88 
SbufRawImplReadRollback(struct HdfSBufImpl * impl,uint32_t size)89 static bool SbufRawImplReadRollback(struct HdfSBufImpl *impl, uint32_t size)
90 {
91     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
92     size_t alignSize;
93     if (sbuf == NULL) {
94         return false;
95     }
96 
97     alignSize = SbufRawImplGetAlignSize(size);
98     if (sbuf->readPos < alignSize) {
99         return false;
100     }
101 
102     sbuf->readPos -= alignSize;
103     return true;
104 }
105 
SbufRawImplGetData(const struct HdfSBufImpl * impl)106 static const uint8_t *SbufRawImplGetData(const struct HdfSBufImpl *impl)
107 {
108     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
109     if (sbuf == NULL) {
110         HDF_LOGE("The obtained data is null, and the input Sbuf is null.");
111         return NULL;
112     }
113     return (uint8_t *)sbuf->data;
114 }
115 
SbufRawImplSetDataSize(struct HdfSBufImpl * impl,size_t size)116 static void SbufRawImplSetDataSize(struct HdfSBufImpl *impl, size_t size)
117 {
118     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
119     if (sbuf == NULL) {
120         return;
121     }
122     if (size <= sbuf->capacity) {
123         sbuf->readPos = 0;
124         sbuf->writePos = size;
125     }
126 }
127 
SbufRawImplFlush(struct HdfSBufImpl * impl)128 static void SbufRawImplFlush(struct HdfSBufImpl *impl)
129 {
130     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
131     if (sbuf != NULL) {
132         sbuf->readPos = 0;
133         sbuf->writePos = 0;
134     }
135 }
136 
SbufRawImplGetCapacity(const struct HdfSBufImpl * impl)137 static size_t SbufRawImplGetCapacity(const struct HdfSBufImpl *impl)
138 {
139     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
140     return (sbuf != NULL) ? sbuf->capacity : 0;
141 }
142 
SbufRawImplGetDataSize(const struct HdfSBufImpl * impl)143 static size_t SbufRawImplGetDataSize(const struct HdfSBufImpl *impl)
144 {
145     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
146     return (sbuf != NULL) ? sbuf->writePos : 0;
147 }
148 
SbufRawImplGrow(struct HdfSBufRaw * sbuf,uint32_t growSize)149 static bool SbufRawImplGrow(struct HdfSBufRaw *sbuf, uint32_t growSize)
150 {
151     uint32_t newSize;
152     uint8_t *newData = NULL;
153     if (sbuf->isBind) {
154         HDF_LOGE("%s: binded sbuf oom", __func__);
155         return false;
156     }
157 
158     newSize = SbufRawImplGetAlignSize(sbuf->capacity + growSize);
159     if (newSize < sbuf->capacity) {
160         HDF_LOGE("%s: grow size overflow", __func__);
161         return false;
162     }
163     if (newSize > HDF_SBUF_MAX_SIZE) {
164         HDF_LOGE("%s: buf size over limit", __func__);
165         return false;
166     }
167 
168     newData = OsalMemCalloc(newSize);
169     if (newData == NULL) {
170         HDF_LOGE("%s: oom", __func__);
171         return false;
172     }
173 
174     if (sbuf->data != NULL) {
175         if (memcpy_s(newData, newSize, sbuf->data, sbuf->writePos) != EOK) {
176             OsalMemFree(newData);
177             return false;
178         }
179         OsalMemFree(sbuf->data);
180     }
181 
182     sbuf->data = newData;
183     sbuf->capacity = newSize;
184 
185     return true;
186 }
187 
SbufRawImplWrite(struct HdfSBufImpl * impl,const uint8_t * data,uint32_t size)188 static bool SbufRawImplWrite(struct HdfSBufImpl *impl, const uint8_t *data, uint32_t size)
189 {
190     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
191     size_t alignSize;
192     size_t writeableSize;
193     uint8_t *dest = NULL;
194 
195     if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
196         return false;
197     }
198 
199     if (size == 0) {
200         return true;
201     }
202 
203     alignSize = SbufRawImplGetAlignSize(size);
204     // in case of desireCapacity overflow
205     if (alignSize < size) {
206         HDF_LOGE("desireCapacity overflow");
207         return false;
208     }
209     writeableSize = SbufRawImplGetLeftWriteSize(sbuf);
210     if (alignSize > writeableSize) {
211         size_t growSize = (alignSize > HDF_SBUF_GROW_SIZE_DEFAULT) ? (alignSize + HDF_SBUF_GROW_SIZE_DEFAULT) :
212                                                                      HDF_SBUF_GROW_SIZE_DEFAULT;
213         if (!SbufRawImplGrow(sbuf, growSize)) {
214             return false;
215         }
216         writeableSize = SbufRawImplGetLeftWriteSize(sbuf);
217     }
218 
219     dest = sbuf->data + sbuf->writePos;
220     if (memcpy_s(dest, writeableSize, data, size) != EOK) {
221         return false; /* never hits */
222     }
223 
224     sbuf->writePos += alignSize;
225     return true;
226 }
227 
SbufRawImplRead(struct HdfSBufImpl * impl,uint8_t * data,uint32_t readSize)228 static bool SbufRawImplRead(struct HdfSBufImpl *impl, uint8_t *data, uint32_t readSize)
229 {
230     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
231     size_t alignSize;
232     if (sbuf == NULL || sbuf->data == NULL || data == NULL) {
233         return false;
234     }
235 
236     if (readSize == 0) {
237         return true;
238     }
239 
240     alignSize = SbufRawImplGetAlignSize(readSize);
241     if (alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
242         HDF_LOGE("Read out of buffer range");
243         return false;
244     }
245 
246     if (memcpy_s(data, readSize, sbuf->data + sbuf->readPos, readSize) != EOK) {
247         return false; // never hit
248     }
249     sbuf->readPos += alignSize;
250     return true;
251 }
252 
SbufRawImplWriteUint64(struct HdfSBufImpl * impl,uint64_t value)253 static bool SbufRawImplWriteUint64(struct HdfSBufImpl *impl, uint64_t value)
254 {
255     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
256 }
257 
SbufRawImplWriteUint32(struct HdfSBufImpl * impl,uint32_t value)258 static bool SbufRawImplWriteUint32(struct HdfSBufImpl *impl, uint32_t value)
259 {
260     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
261 }
262 
SbufRawImplWriteUint16(struct HdfSBufImpl * impl,uint16_t value)263 static bool SbufRawImplWriteUint16(struct HdfSBufImpl *impl, uint16_t value)
264 {
265     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
266 }
267 
SbufRawImplWriteUint8(struct HdfSBufImpl * impl,uint8_t value)268 static bool SbufRawImplWriteUint8(struct HdfSBufImpl *impl, uint8_t value)
269 {
270     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
271 }
272 
SbufRawImplWriteInt64(struct HdfSBufImpl * impl,int64_t value)273 static bool SbufRawImplWriteInt64(struct HdfSBufImpl *impl, int64_t value)
274 {
275     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
276 }
277 
SbufRawImplWriteInt32(struct HdfSBufImpl * impl,int32_t value)278 static bool SbufRawImplWriteInt32(struct HdfSBufImpl *impl, int32_t value)
279 {
280     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
281 }
282 
SbufRawImplWriteInt16(struct HdfSBufImpl * impl,int16_t value)283 static bool SbufRawImplWriteInt16(struct HdfSBufImpl *impl, int16_t value)
284 {
285     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
286 }
287 
SbufRawImplWriteInt8(struct HdfSBufImpl * impl,int8_t value)288 static bool SbufRawImplWriteInt8(struct HdfSBufImpl *impl, int8_t value)
289 {
290     return SbufRawImplWrite(impl, (uint8_t *)(&value), sizeof(value));
291 }
292 
SbufRawImplWriteBuffer(struct HdfSBufImpl * impl,const uint8_t * data,uint32_t writeSize)293 static bool SbufRawImplWriteBuffer(struct HdfSBufImpl *impl, const uint8_t *data, uint32_t writeSize)
294 {
295     if (impl == NULL) {
296         HDF_LOGE("Failed to write the Sbuf, invalid input params");
297         return false;
298     }
299     if (data == NULL) {
300         return SbufRawImplWriteInt32(impl, 0);
301     }
302 
303     if (!SbufRawImplWriteInt32(impl, writeSize)) {
304         return false;
305     }
306     if (!SbufRawImplWrite(impl, data, writeSize)) {
307         (void)SbufRawImplWriteRollback(impl, sizeof(int32_t));
308         return false;
309     }
310 
311     return true;
312 }
313 
SbufRawImplWriteString(struct HdfSBufImpl * impl,const char * value)314 static bool SbufRawImplWriteString(struct HdfSBufImpl *impl, const char *value)
315 {
316     if (impl == NULL) {
317         HDF_LOGE("%s: input null", __func__);
318         return false;
319     }
320 
321     return SbufRawImplWriteBuffer(impl, (const uint8_t *)value, value ? (strlen(value) + 1) : 0);
322 }
323 
SbufRawImplReadUint64(struct HdfSBufImpl * impl,uint64_t * value)324 static bool SbufRawImplReadUint64(struct HdfSBufImpl *impl, uint64_t *value)
325 {
326     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
327 }
328 
SbufRawImplReadUint32(struct HdfSBufImpl * impl,uint32_t * value)329 static bool SbufRawImplReadUint32(struct HdfSBufImpl *impl, uint32_t *value)
330 {
331     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
332 }
333 
SbufRawImplReadUint16(struct HdfSBufImpl * impl,uint16_t * value)334 static bool SbufRawImplReadUint16(struct HdfSBufImpl *impl, uint16_t *value)
335 {
336     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
337 }
338 
SbufRawImplReadUint8(struct HdfSBufImpl * impl,uint8_t * value)339 static bool SbufRawImplReadUint8(struct HdfSBufImpl *impl, uint8_t *value)
340 {
341     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
342 }
343 
SbufRawImplReadInt64(struct HdfSBufImpl * impl,int64_t * value)344 static bool SbufRawImplReadInt64(struct HdfSBufImpl *impl, int64_t *value)
345 {
346     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
347 }
348 
SbufRawImplReadInt32(struct HdfSBufImpl * impl,int32_t * value)349 static bool SbufRawImplReadInt32(struct HdfSBufImpl *impl, int32_t *value)
350 {
351     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
352 }
353 
SbufRawImplReadInt16(struct HdfSBufImpl * impl,int16_t * value)354 static bool SbufRawImplReadInt16(struct HdfSBufImpl *impl, int16_t *value)
355 {
356     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
357 }
358 
SbufRawImplReadInt8(struct HdfSBufImpl * impl,int8_t * value)359 static bool SbufRawImplReadInt8(struct HdfSBufImpl *impl, int8_t *value)
360 {
361     return SbufRawImplRead(impl, (uint8_t *)(value), sizeof(*value));
362 }
363 
SbufRawImplReadBuffer(struct HdfSBufImpl * impl,const uint8_t ** data,uint32_t * readSize)364 static bool SbufRawImplReadBuffer(struct HdfSBufImpl *impl, const uint8_t **data, uint32_t *readSize)
365 {
366     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
367     int buffSize = 0;
368     size_t alignSize;
369     if (sbuf == NULL || sbuf->data == NULL || data == NULL || readSize == NULL) {
370         HDF_LOGE("%s: input invalid", __func__);
371         return false;
372     }
373 
374     if (!SbufRawImplReadInt32(impl, &buffSize)) {
375         return false;
376     }
377 
378     if (buffSize == 0) {
379         *data = NULL;
380         *readSize = 0;
381         return true;
382     }
383     alignSize = SbufRawImplGetAlignSize(buffSize);
384     if (alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
385         HDF_LOGE("%{public}s:readBuff out of range", __func__);
386         (void)SbufRawImplReadRollback(impl, sizeof(int32_t));
387         return false;
388     }
389 
390     *data = sbuf->data + sbuf->readPos;
391     *readSize = buffSize;
392     sbuf->readPos += alignSize;
393     return true;
394 }
395 
SbufRawImplReadString(struct HdfSBufImpl * impl)396 static const char *SbufRawImplReadString(struct HdfSBufImpl *impl)
397 {
398     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
399     int32_t strLen = 0;
400     size_t alignSize;
401     char *str = NULL;
402     if (sbuf == NULL || sbuf->data == NULL) {
403         HDF_LOGE("%s: input null", __func__);
404         return NULL;
405     }
406     /* This length contains the '\0' at the end of the string. */
407     if (!SbufRawImplReadInt32(impl, &strLen) || strLen <= 0) {
408         return NULL;
409     }
410     alignSize = SbufRawImplGetAlignSize(strLen);
411     if (strLen > INT16_MAX || alignSize > SbufRawImplGetLeftReadSize(sbuf)) {
412         (void)SbufRawImplReadRollback(impl, sizeof(int32_t));
413         return NULL;
414     }
415 
416     str = (char *)(sbuf->data + sbuf->readPos);
417     sbuf->readPos += alignSize;
418     /* Set '\0' at end of the string forcibly. */
419     str[strLen - 1] = '\0';
420     return str;
421 }
422 
SbufRawImplCopy(const struct HdfSBufImpl * impl)423 static struct HdfSBufImpl *SbufRawImplCopy(const struct HdfSBufImpl *impl)
424 {
425     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
426     struct HdfSBufRaw *new = NULL;
427     if (sbuf == NULL || sbuf->data == NULL) {
428         return NULL;
429     }
430 
431     new = SbufRawImplNewInstance(sbuf->capacity);
432     if (new == NULL) {
433         return NULL;
434     }
435     new->capacity = sbuf->capacity;
436     new->readPos = 0;
437     new->writePos = sbuf->writePos;
438     if (memcpy_s(new->data, new->capacity, sbuf->data, sbuf->capacity) != EOK) {
439         SbufRawImplRecycle(&new->infImpl);
440         return NULL;
441     }
442 
443     return &new->infImpl;
444 }
445 
SbufRawImplMove(struct HdfSBufImpl * impl)446 static struct HdfSBufImpl *SbufRawImplMove(struct HdfSBufImpl *impl)
447 {
448     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
449     struct HdfSBufRaw *new = NULL;
450     if (sbuf == NULL || sbuf->isBind) {
451         return NULL;
452     }
453 
454     new = OsalMemCalloc(sizeof(struct HdfSBufRaw));
455     if (new == NULL) {
456         return NULL;
457     }
458     new->capacity = sbuf->capacity;
459     new->readPos = 0;
460     new->writePos = sbuf->writePos;
461     new->data = sbuf->data;
462 
463     sbuf->data = NULL;
464     sbuf->capacity = 0;
465     SbufRawImplFlush(&sbuf->infImpl);
466     SbufInterfaceAssign(&new->infImpl);
467 
468     return &new->infImpl;
469 }
470 
SbufRawImplTransDataOwnership(struct HdfSBufImpl * impl)471 static void SbufRawImplTransDataOwnership(struct HdfSBufImpl *impl)
472 {
473     struct HdfSBufRaw *sbuf = SBUF_RAW_CAST(impl);
474     if (sbuf == NULL) {
475         return;
476     }
477 
478     sbuf->isBind = false;
479 }
480 
SbufInterfaceAssign(struct HdfSBufImpl * inf)481 static void SbufInterfaceAssign(struct HdfSBufImpl *inf)
482 {
483     static struct HdfSBufImpl rawImpl = {
484         .writeBuffer = SbufRawImplWriteBuffer,
485         .writeUint64 = SbufRawImplWriteUint64,
486         .writeUint32 = SbufRawImplWriteUint32,
487         .writeUint16 = SbufRawImplWriteUint16,
488         .writeUint8 = SbufRawImplWriteUint8,
489         .writeInt64 = SbufRawImplWriteInt64,
490         .writeInt32 = SbufRawImplWriteInt32,
491         .writeInt16 = SbufRawImplWriteInt16,
492         .writeInt8 = SbufRawImplWriteInt8,
493         .writeString = SbufRawImplWriteString,
494         .readBuffer = SbufRawImplReadBuffer,
495         .readUint64 = SbufRawImplReadUint64,
496         .readUint32 = SbufRawImplReadUint32,
497         .readUint16 = SbufRawImplReadUint16,
498         .readUint8 = SbufRawImplReadUint8,
499         .readInt64 = SbufRawImplReadInt64,
500         .readInt32 = SbufRawImplReadInt32,
501         .readInt16 = SbufRawImplReadInt16,
502         .readInt8 = SbufRawImplReadInt8,
503         .readString = SbufRawImplReadString,
504         .getData = SbufRawImplGetData,
505         .flush = SbufRawImplFlush,
506         .getCapacity = SbufRawImplGetCapacity,
507         .getDataSize = SbufRawImplGetDataSize,
508         .setDataSize = SbufRawImplSetDataSize,
509         .recycle = SbufRawImplRecycle,
510         .move = SbufRawImplMove,
511         .copy = SbufRawImplCopy,
512         .transDataOwnership = SbufRawImplTransDataOwnership,
513     };
514 
515     (void)memcpy_s(inf, sizeof(struct HdfSBufImpl), &rawImpl, sizeof(struct HdfSBufImpl));
516 }
517 
SbufRawImplNewInstance(size_t capacity)518 static struct HdfSBufRaw *SbufRawImplNewInstance(size_t capacity)
519 {
520     struct HdfSBufRaw *sbuf = NULL;
521     if (capacity > HDF_SBUF_MAX_SIZE) {
522         HDF_LOGE("%s: Sbuf size exceeding max limit", __func__);
523         return NULL;
524     }
525     sbuf = (struct HdfSBufRaw *)OsalMemCalloc(sizeof(struct HdfSBufRaw));
526     if (sbuf == NULL) {
527         HDF_LOGE("Sbuf instance failure");
528         return NULL;
529     }
530 
531     sbuf->data = (uint8_t *)OsalMemCalloc(capacity);
532     if (sbuf->data == NULL) {
533         OsalMemFree(sbuf);
534         HDF_LOGE("sbuf obtain memory oom, size=%u", (uint32_t)capacity);
535         return NULL;
536     }
537     sbuf->capacity = capacity;
538     sbuf->writePos = 0;
539     sbuf->readPos = 0;
540     sbuf->isBind = false;
541     SbufInterfaceAssign(&sbuf->infImpl);
542     return sbuf;
543 }
544 
SbufObtainRaw(size_t capacity)545 struct HdfSBufImpl *SbufObtainRaw(size_t capacity)
546 {
547     struct HdfSBufRaw *sbuf = SbufRawImplNewInstance(capacity);
548     if (sbuf == NULL) {
549         return NULL;
550     }
551     return &sbuf->infImpl;
552 }
553 
SbufBindRaw(uintptr_t base,size_t size)554 struct HdfSBufImpl *SbufBindRaw(uintptr_t base, size_t size)
555 {
556     struct HdfSBufRaw *sbuf = NULL;
557     if (base == 0 || size == 0) {
558         return NULL;
559     }
560     /* 4-byte alignment is required for base. */
561     if ((base & 0x3) != 0) {
562         HDF_LOGE("Base not in 4-byte alignment");
563         return NULL;
564     }
565     sbuf = (struct HdfSBufRaw *)OsalMemAlloc(sizeof(struct HdfSBufRaw));
566     if (sbuf == NULL) {
567         HDF_LOGE("%s: oom", __func__);
568         return NULL;
569     }
570 
571     sbuf->data = (uint8_t *)base;
572     sbuf->capacity = size;
573     sbuf->writePos = size;
574     sbuf->readPos = 0;
575     sbuf->isBind = true;
576     SbufInterfaceAssign(&sbuf->infImpl);
577     return &sbuf->infImpl;
578 }