Coverage Report

Created: 2025-11-24 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libbpf/src/libbpf_utils.c
Line
Count
Source
1
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2
3
/*
4
 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
5
 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
6
 * Copyright (C) 2015 Huawei Inc.
7
 * Copyright (C) 2017 Nicira, Inc.
8
 */
9
10
#undef _GNU_SOURCE
11
#include <stdio.h>
12
#include <string.h>
13
#include <errno.h>
14
#include <inttypes.h>
15
#include <linux/kernel.h>
16
17
#include "libbpf.h"
18
#include "libbpf_internal.h"
19
20
#ifndef ENOTSUPP
21
0
#define ENOTSUPP  524
22
#endif
23
24
/* make sure libbpf doesn't use kernel-only integer typedefs */
25
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
26
27
0
#define ERRNO_OFFSET(e)   ((e) - __LIBBPF_ERRNO__START)
28
#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
29
#define NR_ERRNO  (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
30
31
static const char *libbpf_strerror_table[NR_ERRNO] = {
32
  [ERRCODE_OFFSET(LIBELF)]  = "Something wrong in libelf",
33
  [ERRCODE_OFFSET(FORMAT)]  = "BPF object format invalid",
34
  [ERRCODE_OFFSET(KVERSION)]  = "'version' section incorrect or lost",
35
  [ERRCODE_OFFSET(ENDIAN)]  = "Endian mismatch",
36
  [ERRCODE_OFFSET(INTERNAL)]  = "Internal error in libbpf",
37
  [ERRCODE_OFFSET(RELOC)]   = "Relocation failed",
38
  [ERRCODE_OFFSET(VERIFY)]  = "Kernel verifier blocks program loading",
39
  [ERRCODE_OFFSET(PROG2BIG)]  = "Program too big",
40
  [ERRCODE_OFFSET(KVER)]    = "Incorrect kernel version",
41
  [ERRCODE_OFFSET(PROGTYPE)]  = "Kernel doesn't support this program type",
42
  [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message",
43
  [ERRCODE_OFFSET(INVSEQ)]  = "Invalid netlink sequence",
44
  [ERRCODE_OFFSET(NLPARSE)] = "Incorrect netlink message parsing",
45
};
46
47
int libbpf_strerror(int err, char *buf, size_t size)
48
0
{
49
0
  int ret;
50
51
0
  if (!buf || !size)
52
0
    return libbpf_err(-EINVAL);
53
54
0
  err = err > 0 ? err : -err;
55
56
0
  if (err < __LIBBPF_ERRNO__START) {
57
0
    ret = strerror_r(err, buf, size);
58
0
    buf[size - 1] = '\0';
59
0
    return libbpf_err_errno(ret);
60
0
  }
61
62
0
  if (err < __LIBBPF_ERRNO__END) {
63
0
    const char *msg;
64
65
0
    msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
66
0
    ret = snprintf(buf, size, "%s", msg);
67
0
    buf[size - 1] = '\0';
68
    /* The length of the buf and msg is positive.
69
     * A negative number may be returned only when the
70
     * size exceeds INT_MAX. Not likely to appear.
71
     */
72
0
    if (ret >= size)
73
0
      return libbpf_err(-ERANGE);
74
0
    return 0;
75
0
  }
76
77
0
  ret = snprintf(buf, size, "Unknown libbpf error %d", err);
78
0
  buf[size - 1] = '\0';
79
0
  if (ret >= size)
80
0
    return libbpf_err(-ERANGE);
81
0
  return libbpf_err(-ENOENT);
82
0
}
83
84
const char *libbpf_errstr(int err)
85
1.40k
{
86
1.40k
  static __thread char buf[12];
87
88
1.40k
  if (err > 0)
89
0
    err = -err;
90
91
1.40k
  switch (err) {
92
0
  case -E2BIG:    return "-E2BIG";
93
0
  case -EACCES:   return "-EACCES";
94
0
  case -EADDRINUSE: return "-EADDRINUSE";
95
0
  case -EADDRNOTAVAIL:  return "-EADDRNOTAVAIL";
96
0
  case -EAGAIN:   return "-EAGAIN";
97
0
  case -EALREADY:   return "-EALREADY";
98
0
  case -EBADF:    return "-EBADF";
99
0
  case -EBADFD:   return "-EBADFD";
100
0
  case -EBUSY:    return "-EBUSY";
101
0
  case -ECANCELED:  return "-ECANCELED";
102
0
  case -ECHILD:   return "-ECHILD";
103
0
  case -EDEADLK:    return "-EDEADLK";
104
0
  case -EDOM:   return "-EDOM";
105
0
  case -EEXIST:   return "-EEXIST";
106
0
  case -EFAULT:   return "-EFAULT";
107
0
  case -EFBIG:    return "-EFBIG";
108
0
  case -EILSEQ:   return "-EILSEQ";
109
0
  case -EINPROGRESS:  return "-EINPROGRESS";
110
0
  case -EINTR:    return "-EINTR";
111
1.17k
  case -EINVAL:   return "-EINVAL";
112
0
  case -EIO:    return "-EIO";
113
0
  case -EISDIR:   return "-EISDIR";
114
0
  case -ELOOP:    return "-ELOOP";
115
0
  case -EMFILE:   return "-EMFILE";
116
0
  case -EMLINK:   return "-EMLINK";
117
0
  case -EMSGSIZE:   return "-EMSGSIZE";
118
0
  case -ENAMETOOLONG: return "-ENAMETOOLONG";
119
0
  case -ENFILE:   return "-ENFILE";
120
0
  case -ENODATA:    return "-ENODATA";
121
0
  case -ENODEV:   return "-ENODEV";
122
173
  case -ENOENT:   return "-ENOENT";
123
0
  case -ENOEXEC:    return "-ENOEXEC";
124
0
  case -ENOLINK:    return "-ENOLINK";
125
0
  case -ENOMEM:   return "-ENOMEM";
126
0
  case -ENOSPC:   return "-ENOSPC";
127
0
  case -ENOTBLK:    return "-ENOTBLK";
128
0
  case -ENOTDIR:    return "-ENOTDIR";
129
0
  case -ENOTSUPP:   return "-ENOTSUPP";
130
0
  case -ENOTTY:   return "-ENOTTY";
131
0
  case -ENXIO:    return "-ENXIO";
132
47
  case -EOPNOTSUPP: return "-EOPNOTSUPP";
133
0
  case -EOVERFLOW:  return "-EOVERFLOW";
134
0
  case -EPERM:    return "-EPERM";
135
0
  case -EPIPE:    return "-EPIPE";
136
0
  case -EPROTO:   return "-EPROTO";
137
0
  case -EPROTONOSUPPORT:  return "-EPROTONOSUPPORT";
138
0
  case -ERANGE:   return "-ERANGE";
139
0
  case -EROFS:    return "-EROFS";
140
0
  case -ESPIPE:   return "-ESPIPE";
141
0
  case -ESRCH:    return "-ESRCH";
142
0
  case -ETXTBSY:    return "-ETXTBSY";
143
0
  case -EUCLEAN:    return "-EUCLEAN";
144
0
  case -EXDEV:    return "-EXDEV";
145
12
  default:
146
12
    snprintf(buf, sizeof(buf), "%d", err);
147
12
    return buf;
148
1.40k
  }
149
1.40k
}
150
151
static inline __u32 get_unaligned_be32(const void *p)
152
0
{
153
0
  __be32 val;
154
155
0
  memcpy(&val, p, sizeof(val));
156
0
  return be32_to_cpu(val);
157
0
}
158
159
static inline void put_unaligned_be32(__u32 val, void *p)
160
0
{
161
0
  __be32 be_val = cpu_to_be32(val);
162
163
0
  memcpy(p, &be_val, sizeof(be_val));
164
0
}
165
166
0
#define SHA256_BLOCK_LENGTH 64
167
0
#define Ch(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
168
0
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
169
0
#define Sigma_0(x) (ror32((x), 2) ^ ror32((x), 13) ^ ror32((x), 22))
170
0
#define Sigma_1(x) (ror32((x), 6) ^ ror32((x), 11) ^ ror32((x), 25))
171
0
#define sigma_0(x) (ror32((x), 7) ^ ror32((x), 18) ^ ((x) >> 3))
172
0
#define sigma_1(x) (ror32((x), 17) ^ ror32((x), 19) ^ ((x) >> 10))
173
174
static const __u32 sha256_K[64] = {
175
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
176
  0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
177
  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
178
  0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
179
  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
180
  0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
181
  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
182
  0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
183
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
184
  0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
185
  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
186
};
187
188
#define SHA256_ROUND(i, a, b, c, d, e, f, g, h)                                \
189
0
  {                                                                      \
190
0
    __u32 tmp = h + Sigma_1(e) + Ch(e, f, g) + sha256_K[i] + w[i]; \
191
0
    d += tmp;                                                      \
192
0
    h = tmp + Sigma_0(a) + Maj(a, b, c);                           \
193
0
  }
194
195
static void sha256_blocks(__u32 state[8], const __u8 *data, size_t nblocks)
196
0
{
197
0
  while (nblocks--) {
198
0
    __u32 a = state[0];
199
0
    __u32 b = state[1];
200
0
    __u32 c = state[2];
201
0
    __u32 d = state[3];
202
0
    __u32 e = state[4];
203
0
    __u32 f = state[5];
204
0
    __u32 g = state[6];
205
0
    __u32 h = state[7];
206
0
    __u32 w[64];
207
0
    int i;
208
209
0
    for (i = 0; i < 16; i++)
210
0
      w[i] = get_unaligned_be32(&data[4 * i]);
211
0
    for (; i < ARRAY_SIZE(w); i++)
212
0
      w[i] = sigma_1(w[i - 2]) + w[i - 7] +
213
0
             sigma_0(w[i - 15]) + w[i - 16];
214
0
    for (i = 0; i < ARRAY_SIZE(w); i += 8) {
215
0
      SHA256_ROUND(i + 0, a, b, c, d, e, f, g, h);
216
0
      SHA256_ROUND(i + 1, h, a, b, c, d, e, f, g);
217
0
      SHA256_ROUND(i + 2, g, h, a, b, c, d, e, f);
218
0
      SHA256_ROUND(i + 3, f, g, h, a, b, c, d, e);
219
0
      SHA256_ROUND(i + 4, e, f, g, h, a, b, c, d);
220
0
      SHA256_ROUND(i + 5, d, e, f, g, h, a, b, c);
221
0
      SHA256_ROUND(i + 6, c, d, e, f, g, h, a, b);
222
0
      SHA256_ROUND(i + 7, b, c, d, e, f, g, h, a);
223
0
    }
224
0
    state[0] += a;
225
0
    state[1] += b;
226
0
    state[2] += c;
227
0
    state[3] += d;
228
0
    state[4] += e;
229
0
    state[5] += f;
230
0
    state[6] += g;
231
0
    state[7] += h;
232
0
    data += SHA256_BLOCK_LENGTH;
233
0
  }
234
0
}
235
236
void libbpf_sha256(const void *data, size_t len, __u8 out[SHA256_DIGEST_LENGTH])
237
0
{
238
0
  __u32 state[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
239
0
         0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
240
0
  const __be64 bitcount = cpu_to_be64((__u64)len * 8);
241
0
  __u8 final_data[2 * SHA256_BLOCK_LENGTH] = { 0 };
242
0
  size_t final_len = len % SHA256_BLOCK_LENGTH;
243
0
  int i;
244
245
0
  sha256_blocks(state, data, len / SHA256_BLOCK_LENGTH);
246
247
0
  memcpy(final_data, data + len - final_len, final_len);
248
0
  final_data[final_len] = 0x80;
249
0
  final_len = roundup(final_len + 9, SHA256_BLOCK_LENGTH);
250
0
  memcpy(&final_data[final_len - 8], &bitcount, 8);
251
252
0
  sha256_blocks(state, final_data, final_len / SHA256_BLOCK_LENGTH);
253
254
0
  for (i = 0; i < ARRAY_SIZE(state); i++)
255
0
    put_unaligned_be32(state[i], &out[4 * i]);
256
0
}