Coverage Report

Created: 2024-05-21 06:33

/src/util-linux/libblkid/src/superblocks/cramfs.c
Line
Count
Source (jump to first uncovered line)
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
229
#define CRAMFS_FLAG_FSID_VERSION_2  0x00000001  /* fsid version #2 */
39
40
static uint32_t cfs32_to_cpu(int le, uint32_t value)
41
635
{
42
635
  if (le)
43
134
    return le32_to_cpu(value);
44
501
  else
45
501
    return be32_to_cpu(value);
46
635
}
47
48
static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
49
    const struct cramfs_super *cs, int le)
50
176
{
51
176
  uint32_t crc, expected, csummed_size;
52
176
  const unsigned char *csummed;
53
54
176
  expected = cfs32_to_cpu(le, cs->info.crc);
55
176
  csummed_size = cfs32_to_cpu(le, cs->size);
56
57
176
  if (csummed_size > (1 << 16)
58
176
      || csummed_size < sizeof(struct cramfs_super))
59
105
    return 0;
60
61
71
  csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size);
62
71
  if (!csummed)
63
0
    return 0;
64
65
71
  crc = ~ul_crc32_exclude_offset(~0LL, csummed, csummed_size,
66
71
      offsetof(struct cramfs_super, info.crc),
67
71
      sizeof_member(struct cramfs_super, info.crc));
68
69
71
  return blkid_probe_verify_csum(pr, crc, expected);
70
71
}
71
72
static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag)
73
229
{
74
229
  const struct cramfs_super *cs;
75
76
229
  cs = blkid_probe_get_sb(pr, mag, struct cramfs_super);
77
229
  if (!cs)
78
0
    return errno ? -errno : 1;
79
80
229
  int le = mag->hint == BLKID_ENDIANNESS_LITTLE;
81
229
  int v2 = cfs32_to_cpu(le, cs->flags) & CRAMFS_FLAG_FSID_VERSION_2;
82
83
229
  if (v2 && !cramfs_verify_csum(pr, mag, cs, le))
84
175
    return 1;
85
86
54
  blkid_probe_set_label(pr, cs->name, sizeof(cs->name));
87
54
  blkid_probe_set_fssize(pr, cfs32_to_cpu(le, cs->size));
88
54
  blkid_probe_sprintf_version(pr, "%d", v2 ? 2 : 1);
89
54
  blkid_probe_set_fsendianness(pr, mag->hint);
90
54
  return 0;
91
229
}
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