Coverage Report

Created: 2026-08-30 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptsetup/lib/utils.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * utils - miscellaneous device utilities for cryptsetup
4
 *
5
 * Copyright (C) 2004 Jana Saout <jana@saout.de>
6
 * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
7
 * Copyright (C) 2009-2026 Red Hat, Inc. All rights reserved.
8
 * Copyright (C) 2009-2026 Milan Broz
9
 */
10
11
#include <stdio.h>
12
#include <errno.h>
13
#include <sys/mman.h>
14
#include <sys/resource.h>
15
#include <sys/stat.h>
16
#include <sys/utsname.h>
17
18
#include "internal.h"
19
#include "utils_storage_wrappers.h"
20
21
#define MAX_CAPI_LEN_STR "143" /* for sscanf of crypto API string + 16  + \0 */
22
23
size_t crypt_getpagesize(void)
24
0
{
25
0
  long r = sysconf(_SC_PAGESIZE);
26
0
  return r <= 0 ? DEFAULT_MEM_ALIGNMENT : (size_t)r;
27
0
}
28
29
unsigned crypt_cpusonline(void)
30
0
{
31
0
  long r = sysconf(_SC_NPROCESSORS_ONLN);
32
0
  return r < 0 ? 1 : r;
33
0
}
34
35
uint64_t crypt_getphysmemory_kb(void)
36
0
{
37
0
  long pagesize, phys_pages;
38
0
  uint64_t phys_memory_kb, page_size_kb;
39
40
0
  pagesize = sysconf(_SC_PAGESIZE);
41
0
  phys_pages = sysconf(_SC_PHYS_PAGES);
42
43
0
  if (pagesize <= 0 || phys_pages <= 0)
44
0
    return 0;
45
46
0
  page_size_kb = pagesize / 1024;
47
0
  phys_memory_kb = page_size_kb * phys_pages;
48
49
  /* sanity check for overflow */
50
0
  if (phys_memory_kb / phys_pages != page_size_kb)
51
0
    return 0;
52
53
  /* coverity[return_overflow:FALSE] */
54
0
  return phys_memory_kb;
55
0
}
56
57
uint64_t crypt_getphysmemoryfree_kb(void)
58
0
{
59
0
  long pagesize, phys_pages;
60
0
  uint64_t phys_memoryfree_kb, page_size_kb;
61
62
0
  pagesize = sysconf(_SC_PAGESIZE);
63
0
  phys_pages = sysconf(_SC_AVPHYS_PAGES);
64
65
0
  if (pagesize <= 0 || phys_pages <= 0)
66
0
    return 0;
67
68
0
  page_size_kb = pagesize / 1024;
69
0
  phys_memoryfree_kb = page_size_kb * phys_pages;
70
71
  /* sanity check for overflow */
72
0
  if (phys_memoryfree_kb / phys_pages != page_size_kb)
73
0
    return 0;
74
75
  /* coverity[return_overflow:FALSE] */
76
0
  return phys_memoryfree_kb;
77
0
}
78
79
bool crypt_swapavailable(void)
80
0
{
81
0
  int fd;
82
0
  ssize_t size;
83
0
  char buf[4096], *p;
84
0
  uint64_t total;
85
86
0
  if ((fd = open("/proc/meminfo", O_RDONLY)) < 0)
87
0
    return true;
88
89
0
  size = read(fd, buf, sizeof(buf));
90
0
  close(fd);
91
0
  if (size < 1)
92
0
    return true;
93
94
0
  if (size < (ssize_t)sizeof(buf))
95
0
    buf[size] = 0;
96
0
  else
97
0
    buf[sizeof(buf) - 1] = 0;
98
99
0
  p = strstr(buf, "SwapTotal:");
100
0
  if (!p)
101
0
    return true;
102
103
0
  if (sscanf(p, "SwapTotal: %" PRIu64 " kB", &total) != 1)
104
0
    return true;
105
106
0
  return total > 0;
107
0
}
108
109
void crypt_process_priority(struct crypt_device *cd, int *priority, bool raise)
110
0
{
111
0
  int _priority, new_priority;
112
113
0
  if (raise) {
114
0
    _priority = getpriority(PRIO_PROCESS, 0);
115
0
    if (_priority < 0)
116
0
      _priority = 0;
117
0
    if (priority)
118
0
      *priority = _priority;
119
120
    /*
121
     * Do not bother checking CAP_SYS_NICE as device activation
122
     * requires CAP_SYSADMIN later anyway.
123
     */
124
0
    if (getuid() || geteuid())
125
0
      new_priority = 0;
126
0
    else
127
0
      new_priority = -18;
128
129
0
    if (setpriority(PRIO_PROCESS, 0, new_priority))
130
0
      log_dbg(cd, "Cannot raise process priority.");
131
0
  } else {
132
0
    _priority = priority ? *priority : 0;
133
0
    if (setpriority(PRIO_PROCESS, 0, _priority))
134
0
      log_dbg(cd, "Cannot reset process priority.");
135
0
  }
136
0
}
137
138
/* Keyfile processing */
139
140
/*
141
 * A simple call to lseek(3) might not be possible for some inputs (e.g.
142
 * reading from a pipe), so this function instead reads of up to BUFSIZ bytes
143
 * at a time until the specified number of bytes. It returns -1 on read error
144
 * or when it reaches EOF before the requested number of bytes have been
145
 * discarded.
146
 */
147
static int keyfile_seek(int fd, uint64_t bytes)
148
0
{
149
0
  char tmp[BUFSIZ];
150
0
  size_t next_read;
151
0
  ssize_t bytes_r;
152
0
  off_t r;
153
154
0
  r = lseek(fd, bytes, SEEK_CUR);
155
0
  if (r > 0)
156
0
    return 0;
157
0
  if (r < 0 && errno != ESPIPE)
158
0
    return -1;
159
160
0
  while (bytes > 0) {
161
    /* figure out how much to read */
162
0
    next_read = bytes > sizeof(tmp) ? sizeof(tmp) : (size_t)bytes;
163
164
0
    bytes_r = read(fd, tmp, next_read);
165
0
    if (bytes_r < 0) {
166
0
      if (errno == EINTR)
167
0
        continue;
168
169
0
      crypt_safe_memzero(tmp, sizeof(tmp));
170
      /* read error */
171
0
      return -1;
172
0
    }
173
174
0
    if (bytes_r == 0)
175
      /* EOF */
176
0
      break;
177
178
0
    bytes -= bytes_r;
179
0
  }
180
181
0
  crypt_safe_memzero(tmp, sizeof(tmp));
182
0
  return bytes == 0 ? 0 : -1;
183
0
}
184
185
int crypt_keyfile_device_read(struct crypt_device *cd,  const char *keyfile,
186
            char **key, size_t *key_size_read,
187
            uint64_t keyfile_offset, size_t key_size,
188
            uint32_t flags)
189
0
{
190
0
  int fd, regular_file, char_to_read = 0, char_read = 0, unlimited_read = 0;
191
0
  int r = -EINVAL, newline;
192
0
  char *pass = NULL;
193
0
  size_t buflen, i;
194
0
  uint64_t file_read_size;
195
0
  struct stat st;
196
0
  bool close_fd = false;
197
198
0
  if (!key || !key_size_read)
199
0
    return -EINVAL;
200
201
0
  *key = NULL;
202
0
  *key_size_read = 0;
203
204
0
  if (keyfile) {
205
0
    fd = open(keyfile, O_RDONLY);
206
0
    if (fd < 0) {
207
0
      log_err(cd, _("Failed to open key file."));
208
0
      return -EINVAL;
209
0
    }
210
0
    close_fd = true;
211
0
  } else
212
0
    fd = STDIN_FILENO;
213
214
0
  if (isatty(fd)) {
215
0
    log_err(cd, _("Cannot read keyfile from a terminal."));
216
0
    goto out;
217
0
  }
218
219
  /* If not requested otherwise, we limit input to prevent memory exhaustion */
220
0
  if (key_size == 0) {
221
0
    key_size = DEFAULT_KEYFILE_SIZE_MAXKB * 1024 + 1;
222
0
    unlimited_read = 1;
223
    /* use 4k for buffer (page divisor but avoid huge pages) */
224
0
    buflen = 4096 - 16; /* sizeof(struct safe_allocation); */
225
0
  } else
226
0
    buflen = key_size;
227
228
0
  regular_file = 0;
229
0
  if (keyfile) {
230
0
    if (stat(keyfile, &st) < 0) {
231
0
      log_err(cd, _("Failed to stat key file."));
232
0
      goto out;
233
0
    }
234
0
    if (S_ISREG(st.st_mode)) {
235
0
      regular_file = 1;
236
0
      file_read_size = (uint64_t)st.st_size;
237
238
0
      if (keyfile_offset > file_read_size) {
239
0
        log_err(cd, _("Cannot seek to requested keyfile offset."));
240
0
        goto out;
241
0
      }
242
0
      file_read_size -= keyfile_offset;
243
244
      /* known keyfile size, alloc it in one step */
245
0
      if (file_read_size >= (uint64_t)key_size)
246
0
        buflen = key_size;
247
0
      else if (file_read_size)
248
0
        buflen = file_read_size;
249
0
    }
250
0
  }
251
252
0
  pass = crypt_safe_alloc(buflen);
253
0
  if (!pass) {
254
0
    log_err(cd, _("Out of memory while reading passphrase."));
255
0
    goto out;
256
0
  }
257
258
  /* Discard keyfile_offset bytes on input */
259
0
  if (keyfile_offset && keyfile_seek(fd, keyfile_offset) < 0) {
260
0
    log_err(cd, _("Cannot seek to requested keyfile offset."));
261
0
    goto out;
262
0
  }
263
264
0
  for (i = 0, newline = 0; i < key_size; i += char_read) {
265
0
    if (i == buflen) {
266
0
      buflen += 4096;
267
0
      pass = crypt_safe_realloc(pass, buflen);
268
0
      if (!pass) {
269
0
        log_err(cd, _("Out of memory while reading passphrase."));
270
0
        r = -ENOMEM;
271
0
        goto out;
272
0
      }
273
0
    }
274
275
0
    if (flags & CRYPT_KEYFILE_STOP_EOL) {
276
      /* If we should stop on newline, we must read the input
277
       * one character at the time. Otherwise we might end up
278
       * having read some bytes after the newline, which we
279
       * promised not to do.
280
       */
281
0
      char_to_read = 1;
282
0
    } else {
283
      /* char_to_read = min(key_size - i, buflen - i) */
284
0
      char_to_read = key_size < buflen ?
285
0
        key_size - i : buflen - i;
286
0
    }
287
0
    char_read = read_buffer(fd, &pass[i], char_to_read);
288
0
    if (char_read < 0) {
289
0
      log_err(cd, _("Error reading passphrase."));
290
0
      r = -EPIPE;
291
0
      goto out;
292
0
    }
293
294
0
    if (char_read == 0)
295
0
      break;
296
    /* Stop on newline only if not requested read from keyfile */
297
0
    if ((flags & CRYPT_KEYFILE_STOP_EOL) && pass[i] == '\n') {
298
0
      newline = 1;
299
0
      pass[i] = '\0';
300
0
      break;
301
0
    }
302
0
  }
303
304
  /* Fail if piped input dies reading nothing */
305
0
  if (!i && !regular_file && !newline) {
306
0
    log_err(cd, _("Nothing to read on input."));
307
0
    r = -EPIPE;
308
0
    goto out;
309
0
  }
310
311
  /* Fail if we exceeded internal default (no specified size) */
312
0
  if (unlimited_read && i == key_size) {
313
0
    log_err(cd, _("Maximum keyfile size exceeded."));
314
0
    goto out;
315
0
  }
316
317
0
  if (!unlimited_read && i != key_size) {
318
0
    log_err(cd, _("Cannot read requested amount of data."));
319
0
    goto out;
320
0
  }
321
322
0
  *key = pass;
323
0
  *key_size_read = i;
324
0
  r = 0;
325
0
out:
326
0
  if (close_fd)
327
0
    close(fd);
328
329
0
  if (r)
330
0
    crypt_safe_free(pass);
331
0
  return r;
332
0
}
333
334
int crypt_keyfile_read(struct crypt_device *cd,  const char *keyfile,
335
           char **key, size_t *key_size_read,
336
           size_t keyfile_offset, size_t keyfile_size_max,
337
           uint32_t flags)
338
0
{
339
0
  return crypt_keyfile_device_read(cd, keyfile, key, key_size_read,
340
0
           keyfile_offset, keyfile_size_max, flags);
341
0
}
342
343
int kernel_version(uint64_t *kversion)
344
0
{
345
0
  struct utsname uts;
346
0
  uint16_t maj, min, patch, rel;
347
0
  int r = -EINVAL;
348
349
0
  if (uname(&uts) < 0)
350
0
    return r;
351
352
0
  if (sscanf(uts.release, "%" SCNu16  ".%" SCNu16 ".%" SCNu16 "-%" SCNu16,
353
0
       &maj, &min, &patch, &rel) == 4)
354
0
    r = 0;
355
0
  else if (sscanf(uts.release,  "%" SCNu16 ".%" SCNu16 ".%" SCNu16,
356
0
      &maj, &min, &patch) == 3) {
357
0
    rel = 0;
358
0
    r = 0;
359
0
  }
360
361
0
  if (!r)
362
0
    *kversion = compact_version(maj, min, patch, rel);
363
364
0
  return r;
365
0
}
366
367
bool crypt_string_in(const char *str, char **list, size_t list_size)
368
0
{
369
0
  size_t i;
370
371
0
  for (i = 0; *list && i < list_size; i++, list++)
372
0
    if (!strcmp(str, *list))
373
0
      return true;
374
375
0
  return false;
376
0
}
377
378
/* compare two strings (allows NULL values) */
379
int crypt_strcmp(const char *a, const char *b)
380
0
{
381
0
  if (!a && !b)
382
0
    return 0;
383
0
  else if (!a || !b)
384
0
    return 1;
385
0
  return strcmp(a, b);
386
0
}
387
388
int crypt_check_cipher(struct crypt_device *cd,
389
           size_t keylength,
390
           const char *cipher,
391
           const char *cipher_mode)
392
0
{
393
0
  int r;
394
0
  char cipher_spec[2*MAX_CAPI_ONE_LEN], buf[SECTOR_SIZE], *empty_key;
395
0
  struct crypt_storage *s = NULL;
396
0
  struct volume_key *empty_vk = NULL;
397
0
  struct crypt_storage_wrapper *csw = NULL;
398
399
0
  log_dbg(cd, "Checking if cipher %s-%s is usable (storage wrapper).", cipher, cipher_mode);
400
401
0
  empty_key = malloc(keylength);
402
0
  if (!empty_key)
403
0
    return -ENOMEM;
404
405
  /* No need to get KEY quality random but it must avoid known weak keys. */
406
0
  r = crypt_random_get(cd, empty_key, keylength, CRYPT_RND_NORMAL);
407
0
  if (r < 0)
408
0
    goto out;
409
410
0
  r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, empty_key, keylength, false);
411
0
  if (!r) {
412
0
    memset(buf, 0, sizeof(buf));
413
0
    r = crypt_storage_decrypt(s, 0, sizeof(buf), buf);
414
0
  }
415
416
  /* dm-crypt backend requires root access */
417
0
  if (!r || (getuid() || geteuid()))
418
0
    goto out;
419
420
0
  if (*cipher_mode != '\0')
421
0
    r = snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", cipher, cipher_mode);
422
0
  else
423
0
    r = snprintf(cipher_spec, sizeof(cipher_spec), "%s", cipher);
424
0
  if (r < 0 || (size_t)r >= sizeof(cipher_spec)) {
425
0
    r = -EINVAL;
426
0
    goto out;
427
0
  }
428
429
0
  empty_vk = crypt_alloc_volume_key(keylength, empty_key);
430
0
  if (!empty_vk) {
431
0
    r = -ENOMEM;
432
0
    goto out;
433
0
  }
434
435
0
  r = crypt_storage_wrapper_init(cd, &csw, crypt_metadata_device(cd), 0, 0, SECTOR_SIZE,
436
0
               cipher_spec, empty_vk, CSW_DMCRYPT_ONLY | CSW_OPEN_READONLY);
437
0
  if (r)
438
0
    goto out;
439
440
0
  memset(buf, 0, sizeof(buf));
441
0
  r = crypt_storage_wrapper_read_decrypt(csw, 0, &buf, sizeof(buf));
442
0
  crypt_safe_memzero(buf, sizeof(buf));
443
0
  if (r < 0 || (size_t)r != sizeof(buf))
444
0
    r = -EIO;
445
0
  else
446
0
    r = 0;
447
0
out:
448
0
  crypt_storage_destroy(s);
449
0
  free(empty_key);
450
0
  crypt_storage_wrapper_destroy(csw);
451
0
  crypt_free_volume_key(empty_vk);
452
0
  return r;
453
0
}
454
455
int crypt_capi_to_cipher(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
456
0
{
457
0
  char cipher[MAX_CAPI_ONE_LEN], mode[MAX_CAPI_ONE_LEN], iv[MAX_CAPI_ONE_LEN],
458
0
       auth[MAX_CAPI_ONE_LEN], tmp[MAX_CAPI_LEN], dmcrypt_tmp[MAX_CAPI_LEN*2],
459
0
       capi[MAX_CAPI_LEN+1];
460
0
  size_t len;
461
0
  int i;
462
463
0
  if (!c_dm)
464
0
    return -EINVAL;
465
466
  /* legacy mode */
467
0
  if (strncmp(c_dm, "capi:", 5)) {
468
0
    if (!(*org_c = strdup(c_dm)))
469
0
      return -ENOMEM;
470
0
    if (i_dm) {
471
0
      if (!(*org_i = strdup(i_dm))) {
472
0
        free(*org_c);
473
0
        *org_c = NULL;
474
0
        return -ENOMEM;
475
0
      }
476
0
    } else
477
0
      *org_i = NULL;
478
0
    return 0;
479
0
  }
480
481
  /* modes with capi: prefix */
482
0
  i = sscanf(c_dm, "capi:%" MAX_CAPI_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", tmp, iv);
483
0
  if (i != 2)
484
0
    return -EINVAL;
485
486
  /* non-cryptsetup compatible mode (generic driver with dash?) */
487
0
  if (strrchr(iv, ')')) {
488
0
    if (i_dm)
489
0
      return -EINVAL;
490
0
    if (!(*org_c = strdup(c_dm)))
491
0
      return -ENOMEM;
492
0
    return 0;
493
0
  }
494
495
0
  len = strlen(tmp);
496
0
  if (len < 2)
497
0
    return -EINVAL;
498
499
0
  if (tmp[len-1] == ')')
500
0
    tmp[len-1] = '\0';
501
502
0
  if (sscanf(tmp, "rfc4309(%" MAX_CAPI_LEN_STR "s", capi) == 1) {
503
0
    if (!(*org_i = strdup("aead")))
504
0
      return -ENOMEM;
505
0
  } else if (sscanf(tmp, "rfc7539(%" MAX_CAPI_LEN_STR "[^,],%" MAX_CAPI_ONE_LEN_STR "s", capi, auth) == 2) {
506
0
    if (!(*org_i = strdup(auth)))
507
0
      return -ENOMEM;
508
0
  } else if (sscanf(tmp, "authenc(%" MAX_CAPI_ONE_LEN_STR "[^,],%" MAX_CAPI_LEN_STR "s", auth, capi) == 2) {
509
0
    if (!(*org_i = strdup(auth)))
510
0
      return -ENOMEM;
511
0
  } else {
512
0
    if (i_dm) {
513
0
      if (!(*org_i = strdup(i_dm)))
514
0
        return -ENOMEM;
515
0
    } else
516
0
      *org_i = NULL;
517
0
    memset(capi, 0, sizeof(capi));
518
0
    strncpy(capi, tmp, sizeof(capi)-1);
519
0
  }
520
521
0
  i = sscanf(capi, "%" MAX_CAPI_ONE_LEN_STR "[^(](%" MAX_CAPI_ONE_LEN_STR "[^)])", mode, cipher);
522
0
  if (i == 2)
523
0
    i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
524
0
  else
525
0
    i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
526
0
  if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) {
527
0
    free(*org_i);
528
0
    *org_i = NULL;
529
0
    return -EINVAL;
530
0
  }
531
532
0
  if (!(*org_c = strdup(dmcrypt_tmp))) {
533
0
    free(*org_i);
534
0
    *org_i = NULL;
535
0
    return -ENOMEM;
536
0
  }
537
538
0
  return 0;
539
0
}