Coverage Report

Created: 2025-12-14 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/libblkid/src/superblocks/jmicron_raid.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
3
 *
4
 * Inspired by libvolume_id by
5
 *     Kay Sievers <kay.sievers@vrfy.org>
6
 *
7
 * This file may be redistributed under the terms of the
8
 * GNU Lesser General Public License.
9
 */
10
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <unistd.h>
14
#include <string.h>
15
#include <stdint.h>
16
17
#include "superblocks.h"
18
19
11.4k
#define JM_SIGNATURE    "JM"
20
0
#define JM_MINOR_VERSION(_x)  (le16_to_cpu((_x)->version) & 0xFF)
21
0
#define JM_MAJOR_VERSION(_x)  (le16_to_cpu((_x)->version) >> 8)
22
#define JM_SPARES   2
23
#define JM_MEMBERS    8
24
25
struct jm_metadata {
26
  int8_t    signature[2]; /* 0x0 - 0x01 */
27
28
  uint16_t  version;  /* 0x03 - 0x04 JMicron version */
29
30
  uint16_t  checksum; /* 0x04 - 0x05 */
31
  uint8_t   filler[10];
32
33
  uint32_t  identity; /* 0x10 - 0x13 */
34
35
  struct {
36
    uint32_t  base; /* 0x14 - 0x17 */
37
    uint32_t  range;  /* 0x18 - 0x1B range */
38
    uint16_t  range2; /* 0x1C - 0x1D range2 */
39
  } segment;
40
41
  int8_t    name[16]; /* 0x20 - 0x2F */
42
43
  uint8_t   mode;   /* 0x30 RAID level */
44
  uint8_t   block;    /* 0x31 stride size (2=4K, 3=8K, ...) */
45
  uint16_t  attribute;  /* 0x32 - 0x33 */
46
  uint8_t   filler1[4];
47
48
  uint32_t  spare[JM_SPARES]; /* 0x38 - 0x3F */
49
  uint32_t  member[JM_MEMBERS]; /* 0x40 - 0x5F */
50
51
  uint8_t   filler2[0x20];
52
} __attribute__ ((packed));
53
54
static int jm_checksum(blkid_probe pr, const struct jm_metadata *jm)
55
0
{
56
0
  size_t count = sizeof(*jm) / sizeof(uint16_t);
57
0
  uint16_t sum = 0;
58
0
  unsigned char *ptr = (unsigned char *) jm;
59
60
0
  while (count--) {
61
0
    uint16_t val;
62
63
0
    memcpy(&val, ptr, sizeof(uint16_t));
64
0
    sum += le16_to_cpu(val);
65
66
0
    ptr += sizeof(uint16_t);
67
0
  }
68
69
0
  return blkid_probe_verify_csum(pr, sum == 0 || sum == 1, 1);
70
0
}
71
72
static int probe_jmraid(blkid_probe pr,
73
    const struct blkid_idmag *mag __attribute__((__unused__)))
74
5.73k
{
75
5.73k
  uint64_t off;
76
5.73k
  const struct jm_metadata *jm;
77
78
5.73k
  if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
79
0
    return 1;
80
81
5.73k
  off = ((pr->size / 0x200) - 1) * 0x200;
82
5.73k
  jm = (struct jm_metadata *)
83
5.73k
    blkid_probe_get_buffer(pr,
84
5.73k
        off,
85
5.73k
        sizeof(struct jm_metadata));
86
5.73k
  if (!jm)
87
0
    return errno ? -errno : 1;
88
89
5.73k
  if (memcmp(jm->signature, JM_SIGNATURE, sizeof(JM_SIGNATURE) - 1) != 0)
90
5.73k
    return 1;
91
92
0
  if (!jm_checksum(pr, jm))
93
0
    return 1;
94
95
0
  if (jm->mode > 5)
96
0
    return 1;
97
98
0
  if (blkid_probe_sprintf_version(pr, "%u.%u",
99
0
      JM_MAJOR_VERSION(jm), JM_MINOR_VERSION(jm)) != 0)
100
0
    return 1;
101
0
  if (blkid_probe_set_magic(pr, off, sizeof(jm->signature),
102
0
        (unsigned char *) jm->signature))
103
0
    return 1;
104
0
  return 0;
105
0
}
106
107
const struct blkid_idinfo jmraid_idinfo = {
108
  .name   = "jmicron_raid_member",
109
  .usage    = BLKID_USAGE_RAID,
110
  .minsz    = 0x10000,
111
  .probefunc  = probe_jmraid,
112
  .magics   = BLKID_NONE_MAGIC
113
};