Coverage Report

Created: 2026-01-09 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/libblkid/src/superblocks/cramfs.c
Line
Count
Source
1
/*
2
 * Copyright (C) 1999 by Andries Brouwer
3
 * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
4
 * Copyright (C) 2001 by Andreas Dilger
5
 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
6
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
7
 *
8
 * This file may be redistributed under the terms of the
9
 * GNU Lesser General Public License.
10
 */
11
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <unistd.h>
15
#include <string.h>
16
#include <stdint.h>
17
18
#include "superblocks.h"
19
#include "crc32.h"
20
21
struct cramfs_super
22
{
23
  uint8_t   magic[4];
24
  uint32_t  size;
25
  uint32_t  flags;
26
  uint32_t  future;
27
  uint8_t   signature[16];
28
  struct cramfs_info
29
  {
30
    uint32_t  crc;
31
    uint32_t  edition;
32
    uint32_t  blocks;
33
    uint32_t  files;
34
  } __attribute__((packed)) info;
35
  uint8_t   name[16];
36
} __attribute__((packed));
37
38
127
#define CRAMFS_FLAG_FSID_VERSION_2  0x00000001  /* fsid version #2 */
39
40
static uint32_t cfs32_to_cpu(int le, uint32_t value)
41
345
{
42
345
  if (le)
43
56
    return le32_to_cpu(value);
44
289
  else
45
289
    return be32_to_cpu(value);
46
345
}
47
48
static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
49
    const struct cramfs_super *cs, int le)
50
91
{
51
91
  uint32_t crc, expected, csummed_size;
52
91
  const unsigned char *csummed;
53
54
91
  expected = cfs32_to_cpu(le, cs->info.crc);
55
91
  csummed_size = cfs32_to_cpu(le, cs->size);
56
57
91
  if (csummed_size > (1 << 16)
58
40
      || csummed_size < sizeof(struct cramfs_super))
59
57
    return 0;
60
61
34
  csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size);
62
34
  if (!csummed)
63
0
    return 0;
64
65
34
  crc = ~ul_crc32_exclude_offset(~0LL, csummed, csummed_size,
66
34
      offsetof(struct cramfs_super, info.crc),
67
34
      sizeof_member(struct cramfs_super, info.crc), 0);
68
69
34
  return blkid_probe_verify_csum(pr, crc, expected);
70
34
}
71
72
static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag)
73
127
{
74
127
  const struct cramfs_super *cs;
75
76
127
  cs = blkid_probe_get_sb(pr, mag, struct cramfs_super);
77
127
  if (!cs)
78
0
    return errno ? -errno : 1;
79
80
127
  int le = mag->hint == BLKID_ENDIANNESS_LITTLE;
81
127
  int v2 = cfs32_to_cpu(le, cs->flags) & CRAMFS_FLAG_FSID_VERSION_2;
82
83
127
  if (v2 && !cramfs_verify_csum(pr, mag, cs, le))
84
91
    return 1;
85
86
36
  blkid_probe_set_label(pr, cs->name, sizeof(cs->name));
87
36
  blkid_probe_set_fssize(pr, cfs32_to_cpu(le, cs->size));
88
36
  blkid_probe_sprintf_version(pr, "%d", v2 ? 2 : 1);
89
36
  blkid_probe_set_fsendianness(pr, mag->hint);
90
36
  return 0;
91
127
}
92
93
const struct blkid_idinfo cramfs_idinfo =
94
{
95
  .name   = "cramfs",
96
  .usage    = BLKID_USAGE_FILESYSTEM,
97
  .probefunc  = probe_cramfs,
98
  .magics   =
99
  {
100
    { .magic = "\x45\x3d\xcd\x28", .len = 4,
101
      .hint = BLKID_ENDIANNESS_LITTLE },
102
    { .magic = "\x28\xcd\x3d\x45", .len = 4,
103
      .hint = BLKID_ENDIANNESS_BIG },
104
    { NULL }
105
  }
106
};
107
108