• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: MIT
2 /*
3  * Utility functions for libfsverity
4  *
5  * Copyright 2020 Google LLC
6  *
7  * Use of this source code is governed by an MIT-style
8  * license that can be found in the LICENSE file or at
9  * https://opensource.org/licenses/MIT.
10  */
11 
12 #include "lib_private.h"
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
xmalloc(size_t size)18 static void *xmalloc(size_t size)
19 {
20 	void *p = malloc(size);
21 
22 	if (!p)
23 		libfsverity_error_msg("out of memory (tried to allocate %zu bytes)",
24 				      size);
25 	return p;
26 }
27 
libfsverity_zalloc(size_t size)28 void *libfsverity_zalloc(size_t size)
29 {
30 	void *p = xmalloc(size);
31 
32 	if (!p)
33 		return NULL;
34 	return memset(p, 0, size);
35 }
36 
libfsverity_memdup(const void * mem,size_t size)37 void *libfsverity_memdup(const void *mem, size_t size)
38 {
39 	void *p = xmalloc(size);
40 
41 	if (!p)
42 		return NULL;
43 	return memcpy(p, mem, size);
44 }
45 
46 static void (*libfsverity_error_cb)(const char *msg);
47 
48 LIBEXPORT void
libfsverity_set_error_callback(void (* cb)(const char * msg))49 libfsverity_set_error_callback(void (*cb)(const char *msg))
50 {
51 	libfsverity_error_cb = cb;
52 }
53 
54 #ifdef _WIN32
strerror_r(int errnum,char * buf,size_t buflen)55 static char *strerror_r(int errnum, char *buf, size_t buflen)
56 {
57 	strerror_s(buf, buflen, errnum);
58 
59 	return buf;
60 }
61 #endif
62 
libfsverity_do_error_msg(const char * format,va_list va,int err)63 void libfsverity_do_error_msg(const char *format, va_list va, int err)
64 {
65 	int saved_errno = errno;
66 	char *msg = NULL;
67 
68 	if (!libfsverity_error_cb)
69 		return;
70 
71 	if (vasprintf(&msg, format, va) < 0)
72 		goto out;
73 
74 	if (err) {
75 		char *msg2 = NULL;
76 		char errbuf[64];
77 
78 		if (asprintf(&msg2, "%s: %s", msg,
79 			     strerror_r(err, errbuf, sizeof(errbuf))) < 0)
80 			goto out2;
81 		free(msg);
82 		msg = msg2;
83 	}
84 	(*libfsverity_error_cb)(msg);
85 out2:
86 	free(msg);
87 out:
88 	errno = saved_errno;
89 }
90 
libfsverity_error_msg(const char * format,...)91 void libfsverity_error_msg(const char *format, ...)
92 {
93 	va_list va;
94 
95 	va_start(va, format);
96 	libfsverity_do_error_msg(format, va, 0);
97 	va_end(va);
98 }
99 
libfsverity_error_msg_errno(const char * format,...)100 void libfsverity_error_msg_errno(const char *format, ...)
101 {
102 	va_list va;
103 
104 	va_start(va, format);
105 	libfsverity_do_error_msg(format, va, errno);
106 	va_end(va);
107 }
108 
libfsverity_warn_on(const char * condition,const char * file,int line)109 void libfsverity_warn_on(const char *condition, const char *file, int line)
110 {
111 	fprintf(stderr, "libfsverity internal error! %s at %s:%d\n",
112 		condition, file, line);
113 }
114 
libfsverity_bug_on(const char * condition,const char * file,int line)115 void libfsverity_bug_on(const char *condition, const char *file, int line)
116 {
117 	fprintf(stderr, "libfsverity internal error! %s at %s:%d\n"
118 		"Non-recoverable, aborting program.\n", condition, file, line);
119 	abort();
120 }
121 
libfsverity_mem_is_zeroed(const void * mem,size_t size)122 bool libfsverity_mem_is_zeroed(const void *mem, size_t size)
123 {
124 	const u8 *p = mem;
125 	size_t i;
126 
127 	for (i = 0; i < size; i++) {
128 		if (p[i])
129 			return false;
130 	}
131 	return true;
132 }
133