1ced56a00Sopenharmony_ci// SPDX-License-Identifier: MIT
2ced56a00Sopenharmony_ci/*
3ced56a00Sopenharmony_ci * Utility functions for libfsverity
4ced56a00Sopenharmony_ci *
5ced56a00Sopenharmony_ci * Copyright 2020 Google LLC
6ced56a00Sopenharmony_ci *
7ced56a00Sopenharmony_ci * Use of this source code is governed by an MIT-style
8ced56a00Sopenharmony_ci * license that can be found in the LICENSE file or at
9ced56a00Sopenharmony_ci * https://opensource.org/licenses/MIT.
10ced56a00Sopenharmony_ci */
11ced56a00Sopenharmony_ci
12ced56a00Sopenharmony_ci#include "lib_private.h"
13ced56a00Sopenharmony_ci
14ced56a00Sopenharmony_ci#include <stdio.h>
15ced56a00Sopenharmony_ci#include <stdlib.h>
16ced56a00Sopenharmony_ci#include <string.h>
17ced56a00Sopenharmony_ci
18ced56a00Sopenharmony_cistatic void *xmalloc(size_t size)
19ced56a00Sopenharmony_ci{
20ced56a00Sopenharmony_ci	void *p = malloc(size);
21ced56a00Sopenharmony_ci
22ced56a00Sopenharmony_ci	if (!p)
23ced56a00Sopenharmony_ci		libfsverity_error_msg("out of memory (tried to allocate %zu bytes)",
24ced56a00Sopenharmony_ci				      size);
25ced56a00Sopenharmony_ci	return p;
26ced56a00Sopenharmony_ci}
27ced56a00Sopenharmony_ci
28ced56a00Sopenharmony_civoid *libfsverity_zalloc(size_t size)
29ced56a00Sopenharmony_ci{
30ced56a00Sopenharmony_ci	void *p = xmalloc(size);
31ced56a00Sopenharmony_ci
32ced56a00Sopenharmony_ci	if (!p)
33ced56a00Sopenharmony_ci		return NULL;
34ced56a00Sopenharmony_ci	return memset(p, 0, size);
35ced56a00Sopenharmony_ci}
36ced56a00Sopenharmony_ci
37ced56a00Sopenharmony_civoid *libfsverity_memdup(const void *mem, size_t size)
38ced56a00Sopenharmony_ci{
39ced56a00Sopenharmony_ci	void *p = xmalloc(size);
40ced56a00Sopenharmony_ci
41ced56a00Sopenharmony_ci	if (!p)
42ced56a00Sopenharmony_ci		return NULL;
43ced56a00Sopenharmony_ci	return memcpy(p, mem, size);
44ced56a00Sopenharmony_ci}
45ced56a00Sopenharmony_ci
46ced56a00Sopenharmony_cistatic void (*libfsverity_error_cb)(const char *msg);
47ced56a00Sopenharmony_ci
48ced56a00Sopenharmony_ciLIBEXPORT void
49ced56a00Sopenharmony_cilibfsverity_set_error_callback(void (*cb)(const char *msg))
50ced56a00Sopenharmony_ci{
51ced56a00Sopenharmony_ci	libfsverity_error_cb = cb;
52ced56a00Sopenharmony_ci}
53ced56a00Sopenharmony_ci
54ced56a00Sopenharmony_civoid libfsverity_do_error_msg(const char *format, va_list va)
55ced56a00Sopenharmony_ci{
56ced56a00Sopenharmony_ci	int saved_errno = errno;
57ced56a00Sopenharmony_ci	char *msg = NULL;
58ced56a00Sopenharmony_ci
59ced56a00Sopenharmony_ci	if (!libfsverity_error_cb)
60ced56a00Sopenharmony_ci		return;
61ced56a00Sopenharmony_ci
62ced56a00Sopenharmony_ci	if (vasprintf(&msg, format, va) < 0)
63ced56a00Sopenharmony_ci		goto out;
64ced56a00Sopenharmony_ci
65ced56a00Sopenharmony_ci	(*libfsverity_error_cb)(msg);
66ced56a00Sopenharmony_ci
67ced56a00Sopenharmony_ci	free(msg);
68ced56a00Sopenharmony_ciout:
69ced56a00Sopenharmony_ci	errno = saved_errno;
70ced56a00Sopenharmony_ci}
71ced56a00Sopenharmony_ci
72ced56a00Sopenharmony_civoid libfsverity_error_msg(const char *format, ...)
73ced56a00Sopenharmony_ci{
74ced56a00Sopenharmony_ci	va_list va;
75ced56a00Sopenharmony_ci
76ced56a00Sopenharmony_ci	va_start(va, format);
77ced56a00Sopenharmony_ci	libfsverity_do_error_msg(format, va);
78ced56a00Sopenharmony_ci	va_end(va);
79ced56a00Sopenharmony_ci}
80ced56a00Sopenharmony_ci
81ced56a00Sopenharmony_civoid libfsverity_warn_on(const char *condition, const char *file, int line)
82ced56a00Sopenharmony_ci{
83ced56a00Sopenharmony_ci	fprintf(stderr, "libfsverity internal error! %s at %s:%d\n",
84ced56a00Sopenharmony_ci		condition, file, line);
85ced56a00Sopenharmony_ci}
86ced56a00Sopenharmony_ci
87ced56a00Sopenharmony_civoid libfsverity_bug_on(const char *condition, const char *file, int line)
88ced56a00Sopenharmony_ci{
89ced56a00Sopenharmony_ci	fprintf(stderr, "libfsverity internal error! %s at %s:%d\n"
90ced56a00Sopenharmony_ci		"Non-recoverable, aborting program.\n", condition, file, line);
91ced56a00Sopenharmony_ci	abort();
92ced56a00Sopenharmony_ci}
93ced56a00Sopenharmony_ci
94ced56a00Sopenharmony_cibool libfsverity_mem_is_zeroed(const void *mem, size_t size)
95ced56a00Sopenharmony_ci{
96ced56a00Sopenharmony_ci	const u8 *p = mem;
97ced56a00Sopenharmony_ci	size_t i;
98ced56a00Sopenharmony_ci
99ced56a00Sopenharmony_ci	for (i = 0; i < size; i++) {
100ced56a00Sopenharmony_ci		if (p[i])
101ced56a00Sopenharmony_ci			return false;
102ced56a00Sopenharmony_ci	}
103ced56a00Sopenharmony_ci	return true;
104ced56a00Sopenharmony_ci}
105