summaryrefslogtreecommitdiffstats
path: root/libblkid/src
diff options
context:
space:
mode:
Diffstat (limited to 'libblkid/src')
-rw-r--r--libblkid/src/Makemodule.am3
-rw-r--r--libblkid/src/blkid.h.in2
-rw-r--r--libblkid/src/blkidP.h16
-rw-r--r--libblkid/src/config.c107
-rw-r--r--libblkid/src/dev.c6
-rw-r--r--libblkid/src/libblkid.sym4
-rw-r--r--libblkid/src/partitions/bsd.c2
-rw-r--r--libblkid/src/partitions/dos.c14
-rw-r--r--libblkid/src/partitions/gpt.c6
-rw-r--r--libblkid/src/partitions/mac.c2
-rw-r--r--libblkid/src/partitions/minix.c4
-rw-r--r--libblkid/src/partitions/partitions.c5
-rw-r--r--libblkid/src/partitions/ultrix.c6
-rw-r--r--libblkid/src/probe.c213
-rw-r--r--libblkid/src/superblocks/adaptec_raid.c4
-rw-r--r--libblkid/src/superblocks/apfs.c2
-rw-r--r--libblkid/src/superblocks/bcache.c48
-rw-r--r--libblkid/src/superblocks/befs.c6
-rw-r--r--libblkid/src/superblocks/bluestore.c2
-rw-r--r--libblkid/src/superblocks/btrfs.c2
-rw-r--r--libblkid/src/superblocks/cramfs.c28
-rw-r--r--libblkid/src/superblocks/cs_fvault2.c2
-rw-r--r--libblkid/src/superblocks/ddf_raid.c6
-rw-r--r--libblkid/src/superblocks/drbd.c147
-rw-r--r--libblkid/src/superblocks/erofs.c4
-rw-r--r--libblkid/src/superblocks/exfat.c8
-rw-r--r--libblkid/src/superblocks/exfs.c6
-rw-r--r--libblkid/src/superblocks/f2fs.c6
-rw-r--r--libblkid/src/superblocks/gfs.c4
-rw-r--r--libblkid/src/superblocks/hfs.c38
-rw-r--r--libblkid/src/superblocks/highpoint_raid.c3
-rw-r--r--libblkid/src/superblocks/hpfs.c6
-rw-r--r--libblkid/src/superblocks/iso9660.c195
-rw-r--r--libblkid/src/superblocks/isw_raid.c3
-rw-r--r--libblkid/src/superblocks/jfs.c2
-rw-r--r--libblkid/src/superblocks/jmicron_raid.c3
-rw-r--r--libblkid/src/superblocks/linux_raid.c7
-rw-r--r--libblkid/src/superblocks/lsi_raid.c3
-rw-r--r--libblkid/src/superblocks/luks.c20
-rw-r--r--libblkid/src/superblocks/lvm.c10
-rw-r--r--libblkid/src/superblocks/minix.c2
-rw-r--r--libblkid/src/superblocks/mpool.c2
-rw-r--r--libblkid/src/superblocks/netware.c2
-rw-r--r--libblkid/src/superblocks/ntfs.c6
-rw-r--r--libblkid/src/superblocks/nvidia_raid.c3
-rw-r--r--libblkid/src/superblocks/ocfs.c6
-rw-r--r--libblkid/src/superblocks/promise_raid.c3
-rw-r--r--libblkid/src/superblocks/reiserfs.c4
-rw-r--r--libblkid/src/superblocks/romfs.c4
-rw-r--r--libblkid/src/superblocks/silicon_raid.c3
-rw-r--r--libblkid/src/superblocks/squashfs.c6
-rw-r--r--libblkid/src/superblocks/stratis.c6
-rw-r--r--libblkid/src/superblocks/superblocks.c9
-rw-r--r--libblkid/src/superblocks/superblocks.h16
-rw-r--r--libblkid/src/superblocks/swap.c4
-rw-r--r--libblkid/src/superblocks/sysv.c2
-rw-r--r--libblkid/src/superblocks/ubi.c2
-rw-r--r--libblkid/src/superblocks/ubifs.c2
-rw-r--r--libblkid/src/superblocks/udf.c27
-rw-r--r--libblkid/src/superblocks/vdo.c2
-rw-r--r--libblkid/src/superblocks/vfat.c17
-rw-r--r--libblkid/src/superblocks/via_raid.c3
-rw-r--r--libblkid/src/superblocks/vmfs.c6
-rw-r--r--libblkid/src/superblocks/vxfs.c26
-rw-r--r--libblkid/src/superblocks/xfs.c12
-rw-r--r--libblkid/src/superblocks/zfs.c28
-rw-r--r--libblkid/src/superblocks/zonefs.c2
-rw-r--r--libblkid/src/topology/sysfs.c2
-rw-r--r--libblkid/src/topology/topology.c6
69 files changed, 776 insertions, 392 deletions
diff --git a/libblkid/src/Makemodule.am b/libblkid/src/Makemodule.am
index bc90eb8..3fae3f0 100644
--- a/libblkid/src/Makemodule.am
+++ b/libblkid/src/Makemodule.am
@@ -118,6 +118,9 @@ libblkid_la_SOURCES += \
endif
libblkid_la_LIBADD = libcommon.la
+if HAVE_ECONF
+libblkid_la_LIBADD += -leconf
+endif
EXTRA_libblkid_la_DEPENDENCIES = \
libblkid/src/libblkid.sym
diff --git a/libblkid/src/blkid.h.in b/libblkid/src/blkid.h.in
index c232d72..8f6ec97 100644
--- a/libblkid/src/blkid.h.in
+++ b/libblkid/src/blkid.h.in
@@ -458,6 +458,8 @@ extern int blkid_probe_has_value(blkid_probe pr, const char *name)
__ul_attribute__((nonnull));
extern int blkid_do_wipe(blkid_probe pr, int dryrun)
__ul_attribute__((nonnull));
+extern int blkid_wipe_all(blkid_probe pr)
+ __ul_attribute__((nonnull));
extern int blkid_probe_step_back(blkid_probe pr)
__ul_attribute__((nonnull));
diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h
index 007cc35..ea7d81b 100644
--- a/libblkid/src/blkidP.h
+++ b/libblkid/src/blkidP.h
@@ -146,6 +146,7 @@ struct blkid_idmag
{
const char *magic; /* magic string */
unsigned int len; /* length of magic */
+ unsigned int hint; /* hint for prober */
const char *hoff; /* hint which contains byte offset to kboff */
long kboff; /* kilobyte offset of superblock */
@@ -205,6 +206,7 @@ struct blkid_struct_probe
int fd; /* device file descriptor */
uint64_t off; /* begin of data on the device */
uint64_t size; /* end of data on the device */
+ uint64_t io_size; /* optimal size of IO */
dev_t devno; /* device number (st.st_rdev) */
dev_t disk_devno; /* devno of the whole-disk or 0 */
@@ -220,6 +222,7 @@ struct blkid_struct_probe
struct blkid_chain *wipe_chain; /* superblock, partition, ... */
struct list_head buffers; /* list of buffers */
+ struct list_head prunable_buffers; /* list of prunable buffers */
struct list_head hints;
struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */
@@ -412,12 +415,12 @@ extern int blkdid_probe_is_opal_locked(blkid_probe pr)
__attribute__((nonnull))
__attribute__((warn_unused_result));
-extern unsigned char *blkid_probe_get_buffer(blkid_probe pr,
+extern const unsigned char *blkid_probe_get_buffer(blkid_probe pr,
uint64_t off, uint64_t len)
__attribute__((nonnull))
__attribute__((warn_unused_result));
-extern unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
+extern const unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
__attribute__((nonnull))
__attribute__((warn_unused_result));
@@ -433,10 +436,15 @@ extern int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
uint64_t *offset, const struct blkid_idmag **res)
__attribute__((nonnull(1)));
+extern void blkid_probe_prune_buffers(blkid_probe pr);
+
/* returns superblock according to 'struct blkid_idmag' */
-extern unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size);
+extern const unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size);
#define blkid_probe_get_sb(_pr, _mag, type) \
- ((type *) blkid_probe_get_sb_buffer((_pr), _mag, sizeof(type)))
+ ((const type *) blkid_probe_get_sb_buffer((_pr), _mag, sizeof(type)))
+
+extern uint64_t blkid_probe_get_idmag_off(blkid_probe pr, const struct blkid_idmag *mag)
+ __attribute__((nonnull));
extern blkid_partlist blkid_probe_get_partlist(blkid_probe pr)
__attribute__((nonnull))
diff --git a/libblkid/src/config.c b/libblkid/src/config.c
index d3f5eea..7b8b04f 100644
--- a/libblkid/src/config.c
+++ b/libblkid/src/config.c
@@ -22,6 +22,9 @@
#endif
#include <stdint.h>
#include <stdarg.h>
+#if defined (HAVE_LIBECONF)
+#include <libeconf.h>
+#endif
#include "blkidP.h"
#include "env.h"
@@ -55,6 +58,7 @@ err:
return -1;
}
+#ifndef HAVE_LIBECONF
static int parse_next(FILE *fd, struct blkid_config *conf)
{
char buf[BUFSIZ];
@@ -111,25 +115,29 @@ static int parse_next(FILE *fd, struct blkid_config *conf)
}
return 0;
}
+#endif /* !HAVE_LIBECONF */
/* return real config data or built-in default */
struct blkid_config *blkid_read_config(const char *filename)
{
struct blkid_config *conf;
- FILE *f;
-
- if (!filename)
- filename = safe_getenv("BLKID_CONF");
- if (!filename)
- filename = BLKID_CONFIG_FILE;
conf = calloc(1, sizeof(*conf));
if (!conf)
return NULL;
conf->uevent = -1;
- DBG(CONFIG, ul_debug("reading config file: %s.", filename));
+ if (!filename)
+ filename = safe_getenv("BLKID_CONF");
+
+#ifndef HAVE_LIBECONF
+
+ FILE *f;
+ if (!filename)
+ filename = BLKID_CONFIG_FILE;
+
+ DBG(CONFIG, ul_debug("reading config file: %s.", filename));
f = fopen(filename, "r" UL_CLOEXECSTR);
if (!f) {
DBG(CONFIG, ul_debug("%s: does not exist, using built-in default", filename));
@@ -141,6 +149,81 @@ struct blkid_config *blkid_read_config(const char *filename)
goto err;
}
}
+
+#else /* !HAVE_LIBECONF */
+
+ static econf_file *file = NULL;
+ econf_err error;
+
+ if (filename) {
+ DBG(CONFIG, ul_debug("reading config file: %s.", filename));
+ error = econf_readFile(&file, filename, "= \t", "#");
+ } else {
+ error = econf_readDirs(&file,
+#if USE_VENDORDIR
+ _PATH_VENDORDIR,
+#else
+ NULL,
+#endif
+ "/etc", "blkid", "conf", "= \t", "#");
+ }
+
+ if (error) {
+ if (error == ECONF_NOFILE) {
+ if (filename)
+ DBG(CONFIG,
+ ul_debug("%s: does not exist, using built-in default", filename));
+ else
+ DBG(CONFIG,
+ ul_debug("No configuration file blkid.conf found, using built-in default "));
+ goto dflt;
+ } else {
+ if (filename)
+ DBG(CONFIG, ul_debug("%s: parse error:%s", filename, econf_errString(error)));
+ else
+ DBG(CONFIG, ul_debug("parse error:%s", econf_errString(error)));
+
+ goto err;
+ }
+ }
+
+ bool uevent = false;
+ if ((error = econf_getBoolValue(file, NULL, "SEND_UEVENT", &uevent))) {
+ if (error != ECONF_NOKEY) {
+ DBG(CONFIG, ul_debug("couldn't fetch SEND_UEVENT corrently: %s", econf_errString(error)));
+ goto err;
+ } else {
+ DBG(CONFIG, ul_debug("key SEND_UEVENT not found, using built-in default "));
+ }
+ } else {
+ conf->uevent = uevent ? TRUE : FALSE;
+ }
+
+ if ((error = econf_getStringValue(file, NULL, "CACHE_FILE", &(conf->cachefile)))) {
+ conf->cachefile = NULL;
+ if (error != ECONF_NOKEY) {
+ DBG(CONFIG, ul_debug("couldn't fetch CACHE_FILE correctly: %s", econf_errString(error)));
+ goto err;
+ } else {
+ DBG(CONFIG, ul_debug("key CACHE_FILE not found, using built-in default "));
+ }
+ }
+
+ char *line = NULL;
+ if ((error = econf_getStringValue(file, NULL, "EVALUATE", &line))) {
+ conf->nevals = 0;
+ if (error != ECONF_NOKEY) {
+ DBG(CONFIG, ul_debug("couldn't fetch EVALUATE correctly: %s", econf_errString(error)));
+ goto err;
+ } else {
+ DBG(CONFIG, ul_debug("key CACHE_FILE not found, using built-in default "));
+ }
+ } else {
+ if (*line && parse_evaluate(conf, line) == -1)
+ goto err;
+ }
+
+#endif /* HAVE_LIBECONF */
dflt:
if (!conf->nevals) {
conf->eval[0] = BLKID_EVAL_UDEV;
@@ -151,13 +234,23 @@ dflt:
conf->cachefile = strdup(BLKID_CACHE_FILE);
if (conf->uevent == -1)
conf->uevent = TRUE;
+#ifndef HAVE_LIBECONF
if (f)
fclose(f);
+#else
+ econf_free (file);
+ free (line);
+#endif
return conf;
err:
free(conf->cachefile);
free(conf);
+#ifndef HAVE_LIBECONF
fclose(f);
+#else
+ econf_free (file);
+ free (line);
+#endif
return NULL;
}
diff --git a/libblkid/src/dev.c b/libblkid/src/dev.c
index c38ec3d..ca13f39 100644
--- a/libblkid/src/dev.c
+++ b/libblkid/src/dev.c
@@ -155,15 +155,13 @@ int blkid_dev_set_search(blkid_dev_iterate iter,
if (!iter || iter->magic != DEV_ITERATE_MAGIC || !search_type ||
!search_value)
return -1;
- new_type = malloc(strlen(search_type)+1);
- new_value = malloc(strlen(search_value)+1);
+ new_type = strdup(search_type);
+ new_value = strdup(search_value);
if (!new_type || !new_value) {
free(new_type);
free(new_value);
return -1;
}
- strcpy(new_type, search_type);
- strcpy(new_value, search_value);
free(iter->search_type);
free(iter->search_value);
iter->search_type = new_type;
diff --git a/libblkid/src/libblkid.sym b/libblkid/src/libblkid.sym
index 775b024..7b2263a 100644
--- a/libblkid/src/libblkid.sym
+++ b/libblkid/src/libblkid.sym
@@ -187,3 +187,7 @@ BLKID_2_37 {
BLKID_2_39 {
blkid_topology_get_diskseq;
} BLKID_2_37;
+
+BLKID_2_40 {
+ blkid_wipe_all;
+} BLKID_2_39;
diff --git a/libblkid/src/partitions/bsd.c b/libblkid/src/partitions/bsd.c
index ba12019..20dab6b 100644
--- a/libblkid/src/partitions/bsd.c
+++ b/libblkid/src/partitions/bsd.c
@@ -47,7 +47,7 @@ static int probe_bsd_pt(blkid_probe pr, const struct blkid_idmag *mag)
blkid_partition parent;
blkid_partlist ls;
int i, nparts = BSD_MAXPARTITIONS;
- unsigned char *data;
+ const unsigned char *data;
int rc = BLKID_PROBE_NONE;
uint32_t abs_offset = 0;
diff --git a/libblkid/src/partitions/dos.c b/libblkid/src/partitions/dos.c
index 5c7718c..d5a8aa3 100644
--- a/libblkid/src/partitions/dos.c
+++ b/libblkid/src/partitions/dos.c
@@ -34,7 +34,7 @@ static const struct dos_subtypes {
{ MBR_MINIX_PARTITION, &minix_pt_idinfo }
};
-static inline int is_extended(struct dos_partition *p)
+static inline int is_extended(const struct dos_partition *p)
{
return (p->sys_ind == MBR_DOS_EXTENDED_PARTITION ||
p->sys_ind == MBR_W95_EXTENDED_PARTITION ||
@@ -46,7 +46,7 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
{
blkid_partlist ls = blkid_probe_get_partlist(pr);
uint32_t cur_start = ex_start, cur_size = ex_size;
- unsigned char *data;
+ const unsigned char *data;
int ct_nodata = 0; /* count ext.partitions without data partitions */
int i;
@@ -57,7 +57,7 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
}
while (1) {
- struct dos_partition *p, *p0;
+ const struct dos_partition *p, *p0;
uint32_t start = 0, size;
if (++ct_nodata > 100)
@@ -156,9 +156,9 @@ static inline int is_lvm(blkid_probe pr)
return (v && v->data && strcmp((char *) v->data, "LVM2_member") == 0);
}
-static inline int is_empty_mbr(unsigned char *mbr)
+static inline int is_empty_mbr(const unsigned char *mbr)
{
- struct dos_partition *p = mbr_get_partition(mbr, 0);
+ const struct dos_partition *p = mbr_get_partition(mbr, 0);
int i, nparts = 0;
for (i = 0; i < 4; i++) {
@@ -177,8 +177,8 @@ static int probe_dos_pt(blkid_probe pr,
int ssf;
blkid_parttable tab = NULL;
blkid_partlist ls;
- struct dos_partition *p0, *p;
- unsigned char *data;
+ const struct dos_partition *p0, *p;
+ const unsigned char *data;
uint32_t start, size, id;
char idstr[UUID_STR_LEN];
diff --git a/libblkid/src/partitions/gpt.c b/libblkid/src/partitions/gpt.c
index 89e7bb6..473bf5c 100644
--- a/libblkid/src/partitions/gpt.c
+++ b/libblkid/src/partitions/gpt.c
@@ -109,7 +109,7 @@ static inline uint32_t count_crc32(const unsigned char *buf, size_t len,
return (ul_crc32_exclude_offset(~0L, buf, len, exclude_off, exclude_len) ^ ~0L);
}
-static inline unsigned char *get_lba_buffer(blkid_probe pr,
+static inline const unsigned char *get_lba_buffer(blkid_probe pr,
uint64_t lba, size_t bytes)
{
return blkid_probe_get_buffer(pr,
@@ -161,8 +161,8 @@ static int last_lba(blkid_probe pr, uint64_t *lba)
static int is_pmbr_valid(blkid_probe pr, int *has)
{
int flags = blkid_partitions_get_flags(pr);
- unsigned char *data;
- struct dos_partition *p;
+ const unsigned char *data;
+ const struct dos_partition *p;
int i;
if (has)
diff --git a/libblkid/src/partitions/mac.c b/libblkid/src/partitions/mac.c
index 75a558b..36ce74e 100644
--- a/libblkid/src/partitions/mac.c
+++ b/libblkid/src/partitions/mac.c
@@ -56,7 +56,7 @@ struct mac_driver_desc {
/* there is more stuff after this that we don't need */
} __attribute__((packed));
-static inline unsigned char *get_mac_block(
+static inline const unsigned char *get_mac_block(
blkid_probe pr,
uint16_t block_size,
uint32_t num)
diff --git a/libblkid/src/partitions/minix.c b/libblkid/src/partitions/minix.c
index 43c9d9a..dee7df9 100644
--- a/libblkid/src/partitions/minix.c
+++ b/libblkid/src/partitions/minix.c
@@ -17,11 +17,11 @@
static int probe_minix_pt(blkid_probe pr,
const struct blkid_idmag *mag __attribute__((__unused__)))
{
- struct dos_partition *p;
+ const struct dos_partition *p;
blkid_parttable tab = NULL;
blkid_partition parent;
blkid_partlist ls;
- unsigned char *data;
+ const unsigned char *data;
int i;
data = blkid_probe_get_sector(pr, 0);
diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c
index 8ebf480..e096cf8 100644
--- a/libblkid/src/partitions/partitions.c
+++ b/libblkid/src/partitions/partitions.c
@@ -436,8 +436,8 @@ static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab)
/* Linux kernel has DISK_MAX_PARTS=256, but it's too much for
* generic Linux machine -- let start with 32 partitions.
*/
- void *tmp = realloc(ls->parts, (ls->nparts_max + 32) *
- sizeof(struct blkid_struct_partition));
+ void *tmp = reallocarray(ls->parts, ls->nparts_max + 32,
+ sizeof(struct blkid_struct_partition));
if (!tmp)
return NULL;
ls->parts = tmp;
@@ -557,6 +557,7 @@ static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id,
"%s: ---> call probefunc()", id->name));
errno = 0;
rc = id->probefunc(pr, mag);
+ blkid_probe_prune_buffers(pr);
if (rc < 0) {
/* reset after error */
reset_partlist(blkid_probe_get_partlist(pr));
diff --git a/libblkid/src/partitions/ultrix.c b/libblkid/src/partitions/ultrix.c
index 9c060be..a85712f 100644
--- a/libblkid/src/partitions/ultrix.c
+++ b/libblkid/src/partitions/ultrix.c
@@ -37,8 +37,8 @@ struct ultrix_disklabel {
static int probe_ultrix_pt(blkid_probe pr,
const struct blkid_idmag *mag __attribute__((__unused__)))
{
- unsigned char *data;
- struct ultrix_disklabel *l;
+ const unsigned char *data;
+ const struct ultrix_disklabel *l;
blkid_parttable tab = NULL;
blkid_partlist ls;
int i;
@@ -50,7 +50,7 @@ static int probe_ultrix_pt(blkid_probe pr,
goto nothing;
}
- l = (struct ultrix_disklabel *) (data + ULTRIX_OFFSET);
+ l = (const struct ultrix_disklabel *) (data + ULTRIX_OFFSET);
if (l->pt_magic != ULTRIX_MAGIC || l->pt_valid != 1)
goto nothing;
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c
index fbf504a..76905e1 100644
--- a/libblkid/src/probe.c
+++ b/libblkid/src/probe.c
@@ -90,6 +90,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
+#include <sys/mman.h>
#include <sys/types.h>
#ifdef HAVE_LINUX_CDROM_H
#include <linux/cdrom.h>
@@ -155,6 +156,7 @@ blkid_probe blkid_new_probe(void)
pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
}
INIT_LIST_HEAD(&pr->buffers);
+ INIT_LIST_HEAD(&pr->prunable_buffers);
INIT_LIST_HEAD(&pr->values);
INIT_LIST_HEAD(&pr->hints);
return pr;
@@ -182,6 +184,7 @@ blkid_probe blkid_clone_probe(blkid_probe parent)
pr->fd = parent->fd;
pr->off = parent->off;
pr->size = parent->size;
+ pr->io_size = parent->io_size;
pr->devno = parent->devno;
pr->disk_devno = parent->disk_devno;
pr->blkssz = parent->blkssz;
@@ -543,6 +546,16 @@ int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[
return 0;
}
+static void remove_buffer(struct blkid_bufinfo *bf)
+{
+ list_del(&bf->bufs);
+
+ DBG(BUFFER, ul_debug(" remove buffer: [off=%"PRIu64", len=%"PRIu64"]",
+ bf->off, bf->len));
+ munmap(bf->data, bf->len);
+ free(bf);
+}
+
static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint64_t len)
{
ssize_t ret;
@@ -560,13 +573,20 @@ static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint
}
/* allocate info and space for data by one malloc call */
- bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
+ bf = calloc(1, sizeof(struct blkid_bufinfo));
if (!bf) {
errno = ENOMEM;
return NULL;
}
- bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo);
+ bf->data = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (bf->data == MAP_FAILED) {
+ free(bf);
+ errno = ENOMEM;
+ return NULL;
+ }
+
bf->len = len;
bf->off = real_off;
INIT_LIST_HEAD(&bf->bufs);
@@ -577,7 +597,7 @@ static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint
ret = read(pr->fd, bf->data, len);
if (ret != (ssize_t) len) {
DBG(LOWPROBE, ul_debug("\tread failed: %m"));
- free(bf);
+ remove_buffer(bf);
/* I/O errors on CDROMs are non-fatal to work with hybrid
* audio+data disks */
@@ -601,6 +621,9 @@ static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint
return NULL;
}
+ if (mprotect(bf->data, len, PROT_READ))
+ DBG(LOWPROBE, ul_debug("\tmprotect failed: %m"));
+
return bf;
}
@@ -626,6 +649,39 @@ static struct blkid_bufinfo *get_cached_buffer(blkid_probe pr, uint64_t off, uin
}
/*
+ * Mark smaller buffers that can be satisfied by bf as prunable
+ */
+static void mark_prunable_buffers(blkid_probe pr, const struct blkid_bufinfo *bf)
+{
+ struct list_head *p, *next;
+
+ list_for_each_safe(p, next, &pr->buffers) {
+ struct blkid_bufinfo *x =
+ list_entry(p, struct blkid_bufinfo, bufs);
+
+ if (bf->off <= x->off && bf->off + bf->len >= x->off + x->len) {
+ list_del(&x->bufs);
+ list_add(&x->bufs, &pr->prunable_buffers);
+ }
+ }
+}
+
+/*
+ * Remove buffers that are marked as prunable
+ */
+void blkid_probe_prune_buffers(blkid_probe pr)
+{
+ struct list_head *p, *next;
+
+ list_for_each_safe(p, next, &pr->prunable_buffers) {
+ struct blkid_bufinfo *x =
+ list_entry(p, struct blkid_bufinfo, bufs);
+
+ remove_buffer(x);
+ }
+}
+
+/*
* Zeroize in-memory data in already read buffer. The next blkid_probe_get_buffer()
* will return modified buffer. This is usable when you want to call the same probing
* function more than once and hide previously detected magic strings.
@@ -657,7 +713,9 @@ static int hide_buffer(blkid_probe pr, uint64_t off, uint64_t len)
DBG(BUFFER, ul_debug("\thiding: off=%"PRIu64" len=%"PRIu64,
off, len));
+ mprotect(x->data, x->len, PROT_READ | PROT_WRITE);
memset(data, 0, len);
+ mprotect(x->data, x->len, PROT_READ);
ct++;
}
}
@@ -669,16 +727,29 @@ static int hide_buffer(blkid_probe pr, uint64_t off, uint64_t len)
* Note that @off is offset within probing area, the probing area is defined by
* pr->off and pr->size.
*/
-unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len)
+const unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len)
{
struct blkid_bufinfo *bf = NULL;
- uint64_t real_off = pr->off + off;
+ uint64_t real_off, bias, len_align;
+
+ bias = off % pr->io_size;
+ off -= bias;
+ len += bias;
+
+ if (len % pr->io_size) {
+ len_align = pr->io_size - (len % pr->io_size);
+
+ if (pr->off + off + len + len_align <= pr->size)
+ len += len_align;
+ }
+
+ real_off = pr->off + off;
/*
DBG(BUFFER, ul_debug("\t>>>> off=%ju, real-off=%ju (probe <%ju..%ju>, len=%ju",
off, real_off, pr->off, pr->off + pr->size, len));
*/
- if (pr->size == 0) {
+ if (pr->size == 0 || pr->io_size == 0) {
errno = EINVAL;
return NULL;
}
@@ -688,6 +759,11 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len
return NULL;
}
+ if (len > 8388608 /* 8 Mib */ ) {
+ DBG(BUFFER, ul_debug("\t too large read request (ignore)"));
+ return NULL;
+ }
+
if (len == 0
|| (!S_ISCHR(pr->mode) && (pr->size < off || pr->size < len))
|| (!S_ISCHR(pr->mode) && (pr->off + pr->size < real_off + len))) {
@@ -718,6 +794,7 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len
if (!bf)
return NULL;
+ mark_prunable_buffers(pr, bf);
list_add_tail(&bf->bufs, &pr->buffers);
}
@@ -725,7 +802,7 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len
assert(bf->off + bf->len >= real_off + len);
errno = 0;
- return real_off ? bf->data + (real_off - bf->off) : bf->data;
+ return real_off ? bf->data + (real_off - bf->off + bias) : bf->data + bias;
}
/**
@@ -747,6 +824,8 @@ int blkid_probe_reset_buffers(blkid_probe pr)
pr->flags &= ~BLKID_FL_MODIF_BUFF;
+ blkid_probe_prune_buffers(pr);
+
if (list_empty(&pr->buffers))
return 0;
@@ -757,11 +836,8 @@ int blkid_probe_reset_buffers(blkid_probe pr)
struct blkid_bufinfo, bufs);
ct++;
len += bf->len;
- list_del(&bf->bufs);
- DBG(BUFFER, ul_debug(" remove buffer: [off=%"PRIu64", len=%"PRIu64"]",
- bf->off, bf->len));
- free(bf);
+ remove_buffer(bf);
}
DBG(LOWPROBE, ul_debug(" buffers summary: %"PRIu64" bytes by %"PRIu64" read() calls",
@@ -891,6 +967,24 @@ failed:
#endif
+#ifdef BLKIOOPT
+static uint64_t blkid_get_io_size(int fd)
+{
+ static const int ioctls[] = { BLKIOOPT, BLKIOMIN, BLKBSZGET };
+ unsigned int s;
+ size_t i;
+ int r;
+
+ for (i = 0; i < ARRAY_SIZE(ioctls); i++) {
+ r = ioctl(fd, ioctls[i], &s);
+ if (r == 0 && is_power_of_2(s) && s >= DEFAULT_SECTOR_SIZE)
+ return min(s, 1U << 16);
+ }
+
+ return DEFAULT_SECTOR_SIZE;
+}
+#endif
+
/**
* blkid_probe_set_device:
* @pr: probe
@@ -934,6 +1028,7 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
pr->fd = fd;
pr->off = (uint64_t) off;
pr->size = 0;
+ pr->io_size = DEFAULT_SECTOR_SIZE;
pr->devno = 0;
pr->disk_devno = 0;
pr->mode = 0;
@@ -1097,8 +1192,13 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
}
# endif
- DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64", zonesize=%"PRIu64,
- pr->off, pr->size, pr->zone_size));
+#ifdef BLKIOOPT
+ if (S_ISBLK(sb.st_mode) && !is_floppy && !blkid_probe_is_tiny(pr))
+ pr->io_size = blkid_get_io_size(fd);
+#endif
+
+ DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64", zonesize=%"PRIu64", iosize=%"PRIu64,
+ pr->off, pr->size, pr->zone_size, pr->io_size));
DBG(LOWPROBE, ul_debug("whole-disk: %s, regfile: %s",
blkid_probe_is_wholedisk(pr) ?"YES" : "NO",
S_ISREG(pr->mode) ? "YES" : "NO"));
@@ -1136,14 +1236,28 @@ int blkid_probe_set_dimension(blkid_probe pr, uint64_t off, uint64_t size)
return 0;
}
-unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size)
+const unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size)
{
- uint64_t hint_offset;
+ uint64_t hint_offset, off;
+
+ if (mag->kboff >= 0) {
+ if (!mag->hoff || blkid_probe_get_hint(pr, mag->hoff, &hint_offset) < 0)
+ hint_offset = 0;
- if (!mag->hoff || blkid_probe_get_hint(pr, mag->hoff, &hint_offset) < 0)
- hint_offset = 0;
+ off = hint_offset + (mag->kboff << 10);
+ } else {
+ off = pr->size - (-mag->kboff << 10);
+ }
+
+ return blkid_probe_get_buffer(pr, off, size);
+}
- return blkid_probe_get_buffer(pr, hint_offset + (mag->kboff << 10), size);
+uint64_t blkid_probe_get_idmag_off(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ if (mag->kboff >= 0)
+ return mag->kboff << 10;
+ else
+ return pr->size - (-mag->kboff << 10);
}
/*
@@ -1164,8 +1278,8 @@ int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
/* try to detect by magic string */
while(mag && mag->magic) {
- unsigned char *buf;
- uint64_t kboff;
+ const unsigned char *buf;
+ long kboff;
uint64_t hint_offset;
if (!mag->hoff || blkid_probe_get_hint(pr, mag->hoff, &hint_offset) < 0)
@@ -1182,19 +1296,20 @@ int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
else
kboff = ((mag->zonenum * pr->zone_size) >> 10) + mag->kboff_inzone;
- off = hint_offset + ((kboff + (mag->sboff >> 10)) << 10);
- buf = blkid_probe_get_buffer(pr, off, 1024);
+ if (kboff >= 0)
+ off = hint_offset + (kboff << 10) + mag->sboff;
+ else
+ off = pr->size - (-kboff << 10) + mag->sboff;
+ buf = blkid_probe_get_buffer(pr, off, mag->len);
if (!buf && errno)
return -errno;
- if (buf && !memcmp(mag->magic,
- buf + (mag->sboff & 0x3ff), mag->len)) {
-
- DBG(LOWPROBE, ul_debug("\tmagic sboff=%u, kboff=%" PRIu64,
+ if (buf && !memcmp(mag->magic, buf, mag->len)) {
+ DBG(LOWPROBE, ul_debug("\tmagic sboff=%u, kboff=%ld",
mag->sboff, kboff));
if (offset)
- *offset = off + (mag->sboff & 0x3ff);
+ *offset = off;
if (res)
*res = mag;
return BLKID_PROBE_OK;
@@ -1384,6 +1499,8 @@ static inline int is_conventional(blkid_probe pr __attribute__((__unused__)),
* See also blkid_probe_step_back() if you cannot use this built-in wipe
* function, but you want to use libblkid probing as a source for wiping.
*
+ * See also blkid_wipe_all() which works the same as the example above.
+ *
* Returns: 0 on success, and -1 in case of error.
*/
int blkid_do_wipe(blkid_probe pr, int dryrun)
@@ -1485,6 +1602,46 @@ int blkid_do_wipe(blkid_probe pr, int dryrun)
}
/**
+ * blkid_wipe_all:
+ * @pr: prober
+ *
+ * This function erases all detectable signatures from &pr.
+ * The @pr has to be open in O_RDWR mode. All other necessary configurations
+ * will be enabled automatically.
+ *
+ * <example>
+ * <title>wipe all filesystems or raids from the device</title>
+ * <programlisting>
+ * fd = open(devname, O_RDWR|O_CLOEXEC);
+ * blkid_probe_set_device(pr, fd, 0, 0);
+ *
+ * blkid_wipe_all(pr);
+ * </programlisting>
+ * </example>
+ *
+ * Returns: 0 on success, and -1 in case of error.
+ */
+int blkid_wipe_all(blkid_probe pr)
+{
+ DBG(LOWPROBE, ul_debug("wiping all signatures"));
+
+ blkid_probe_enable_superblocks(pr, 1);
+ blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC |
+ BLKID_SUBLKS_BADCSUM);
+
+ blkid_probe_enable_partitions(pr, 1);
+ blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC |
+ BLKID_PARTS_FORCE_GPT);
+
+ while (blkid_do_probe(pr) == 0) {
+ DBG(LOWPROBE, ul_debug("wiping one signature"));
+ blkid_do_wipe(pr, 0);
+ }
+
+ return BLKID_PROBE_OK;
+}
+
+/**
* blkid_probe_step_back:
* @pr: prober
*
@@ -1690,7 +1847,7 @@ done:
}
/* same sa blkid_probe_get_buffer() but works with 512-sectors */
-unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
+const unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
{
return blkid_probe_get_buffer(pr, ((uint64_t) sector) << 9, 0x200);
}
diff --git a/libblkid/src/superblocks/adaptec_raid.c b/libblkid/src/superblocks/adaptec_raid.c
index 5fc5fc4..813d30e 100644
--- a/libblkid/src/superblocks/adaptec_raid.c
+++ b/libblkid/src/superblocks/adaptec_raid.c
@@ -79,9 +79,6 @@ static int probe_adraid(blkid_probe pr,
uint64_t off;
struct adaptec_metadata *ad;
- if (pr->size < 0x10000)
- return BLKID_PROBE_NONE;
-
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return BLKID_PROBE_NONE;
@@ -109,6 +106,7 @@ static int probe_adraid(blkid_probe pr,
const struct blkid_idinfo adraid_idinfo = {
.name = "adaptec_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_adraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/apfs.c b/libblkid/src/superblocks/apfs.c
index 048423a..b7f09f3 100644
--- a/libblkid/src/superblocks/apfs.c
+++ b/libblkid/src/superblocks/apfs.c
@@ -39,7 +39,7 @@ struct apfs_super_block {
static int probe_apfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct apfs_super_block *sb;
+ const struct apfs_super_block *sb;
sb = blkid_probe_get_sb(pr, mag, struct apfs_super_block);
if (!sb)
diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c
index d3afc41..47d9060 100644
--- a/libblkid/src/superblocks/bcache.c
+++ b/libblkid/src/superblocks/bcache.c
@@ -189,7 +189,7 @@ static int bcache_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag,
return 0;
/* up to the end of bcs->d[] */
- csummed_size = offsetof(typeof(*bcs), d) +
+ csummed_size = offsetof(__typeof__(*bcs), d) +
sizeof(bcs->d[0]) * le16_to_cpu(bcs->keys);
csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size);
csum = ul_crc64_we(csummed + BCACHE_SB_CSUMMED_START,
@@ -199,7 +199,7 @@ static int bcache_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag,
static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag)
{
- struct bcache_super_block *bcs;
+ const struct bcache_super_block *bcs;
bcs = blkid_probe_get_sb(pr, mag, struct bcache_super_block);
if (!bcs)
@@ -211,9 +211,18 @@ static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag)
if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / 512)
return BLKID_PROBE_NONE;
+ if (blkid_probe_sprintf_version(pr, "%"PRIu64, le64_to_cpu(bcs->version)) < 0)
+ return BLKID_PROBE_NONE;
+
if (blkid_probe_set_uuid(pr, bcs->uuid) < 0)
return BLKID_PROBE_NONE;
+ if (blkid_probe_set_label(pr, bcs->label, sizeof(bcs->label)) < 0)
+ return BLKID_PROBE_NONE;
+
+ if (blkid_probe_set_block_size(pr, le16_to_cpu(bcs->block_size) * 512))
+ return BLKID_PROBE_NONE;
+
blkid_probe_set_wiper(pr, 0, BCACHE_SB_OFF);
return BLKID_PROBE_OK;
@@ -229,7 +238,7 @@ static void probe_bcachefs_sb_members(blkid_probe pr,
uint64_t sectors = 0;
uint8_t i;
- if (BYTES(field) != offsetof(typeof(*members), members[bcs->nr_devices]))
+ if (BYTES(field) != offsetof(__typeof__(*members), members[bcs->nr_devices]))
return;
blkid_probe_set_uuid_as(pr, members->members[dev_idx].uuid, "UUID_SUB");
@@ -249,7 +258,7 @@ static void probe_bcachefs_sb_disk_groups(blkid_probe pr,
struct bcachefs_sb_field_disk_groups *disk_groups =
(struct bcachefs_sb_field_disk_groups *) field;
- if (BYTES(field) != offsetof(typeof(*disk_groups), disk_groups[bcs->nr_devices]))
+ if (BYTES(field) != offsetof(__typeof__(*disk_groups), disk_groups[bcs->nr_devices]))
return;
blkid_probe_set_id_label(pr, "LABEL_SUB",
@@ -257,7 +266,7 @@ static void probe_bcachefs_sb_disk_groups(blkid_probe pr,
sizeof(disk_groups->disk_groups[dev_idx].label));
}
-static int is_within_range(void *start, uint64_t size, void *end)
+static int is_within_range(const void *start, uint64_t size, const void *end)
{
ptrdiff_t diff;
@@ -269,9 +278,9 @@ static int is_within_range(void *start, uint64_t size, void *end)
}
static void probe_bcachefs_sb_fields(blkid_probe pr, const struct bcachefs_super_block *bcs,
- unsigned char *sb_start, unsigned char *sb_end)
+ const unsigned char *sb_start, const unsigned char *sb_end)
{
- unsigned char *field_addr = sb_start + BCACHEFS_SB_FIELDS_OFF;
+ const unsigned char *field_addr = sb_start + BCACHEFS_SB_FIELDS_OFF;
while (1) {
struct bcachefs_sb_field *field = (struct bcachefs_sb_field *) field_addr;
@@ -304,10 +313,10 @@ static void probe_bcachefs_sb_fields(blkid_probe pr, const struct bcachefs_super
}
static int bcachefs_validate_checksum(blkid_probe pr, const struct bcachefs_super_block *bcs,
- unsigned char *sb, unsigned char *sb_end)
+ const unsigned char *sb, const unsigned char *sb_end)
{
uint8_t checksum_type = be64_to_cpu(bcs->flags[0]) >> 58;
- unsigned char *checksummed_data_start = sb + sizeof(bcs->csum);
+ const unsigned char *checksummed_data_start = sb + sizeof(bcs->csum);
size_t checksummed_data_size = sb_end - checksummed_data_start;
switch (checksum_type) {
@@ -333,16 +342,17 @@ static int bcachefs_validate_checksum(blkid_probe pr, const struct bcachefs_supe
static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct bcachefs_super_block *bcs;
- unsigned char *sb, *sb_end;
- uint64_t sb_size, blocksize;
+ const struct bcachefs_super_block *bcs;
+ const unsigned char *sb, *sb_end;
+ uint64_t sb_size, blocksize, offset_sectors;
uint16_t version;
bcs = blkid_probe_get_sb(pr, mag, struct bcachefs_super_block);
if (!bcs)
return errno ? -errno : BLKID_PROBE_NONE;
- if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / BCACHEFS_SECTOR_SIZE)
+ offset_sectors = blkid_probe_get_idmag_off(pr, mag) / BCACHEFS_SECTOR_SIZE;
+ if (le64_to_cpu(bcs->offset) != offset_sectors)
return BLKID_PROBE_NONE;
if (bcs->nr_devices == 0 || bcs->dev_idx >= bcs->nr_devices)
@@ -420,6 +430,18 @@ const struct blkid_idinfo bcachefs_idinfo =
.kboff = BCACHE_SB_KBOFF,
.sboff = BCACHE_SB_MAGIC_OFF,
},
+ {
+ .magic = BCACHEFS_SB_MAGIC,
+ .len = BCACHE_SB_MAGIC_LEN,
+ .kboff = 1 << 11,
+ .sboff = BCACHE_SB_MAGIC_OFF,
+ },
+ {
+ .magic = BCACHEFS_SB_MAGIC,
+ .len = BCACHE_SB_MAGIC_LEN,
+ .kboff = -(1 << 10),
+ .sboff = BCACHE_SB_MAGIC_OFF,
+ },
{ NULL }
}
};
diff --git a/libblkid/src/superblocks/befs.c b/libblkid/src/superblocks/befs.c
index 5112d44..d501eb1 100644
--- a/libblkid/src/superblocks/befs.c
+++ b/libblkid/src/superblocks/befs.c
@@ -122,7 +122,7 @@ struct bplustree_node {
char name[0];
} __attribute__((packed));
-static unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs,
+static const unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs,
const struct block_run *br, int fs_le)
{
return blkid_probe_get_buffer(pr,
@@ -135,7 +135,7 @@ static unsigned char *get_block_run(blkid_probe pr, const struct befs_super_bloc
<< FS32_TO_CPU(bs->block_shift, fs_le));
}
-static unsigned char *get_custom_block_run(blkid_probe pr,
+static const unsigned char *get_custom_block_run(blkid_probe pr,
const struct befs_super_block *bs,
const struct block_run *br,
int64_t offset, uint32_t length, int fs_le)
@@ -154,7 +154,7 @@ static unsigned char *get_custom_block_run(blkid_probe pr,
length);
}
-static unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs,
+static const unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs,
const struct data_stream *ds,
int64_t start, uint32_t length, int fs_le)
{
diff --git a/libblkid/src/superblocks/bluestore.c b/libblkid/src/superblocks/bluestore.c
index 2ff1f35..f9178d9 100644
--- a/libblkid/src/superblocks/bluestore.c
+++ b/libblkid/src/superblocks/bluestore.c
@@ -31,7 +31,7 @@ struct bluestore_phdr {
static int probe_bluestore(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct bluestore_phdr *header;
+ const struct bluestore_phdr *header;
header = blkid_probe_get_sb(pr, mag, struct bluestore_phdr);
if (header == NULL)
diff --git a/libblkid/src/superblocks/btrfs.c b/libblkid/src/superblocks/btrfs.c
index b9cf4bd..114d348 100644
--- a/libblkid/src/superblocks/btrfs.c
+++ b/libblkid/src/superblocks/btrfs.c
@@ -250,7 +250,7 @@ static int btrfs_verify_csum(blkid_probe pr, const struct btrfs_super_block *bfs
static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct btrfs_super_block *bfs;
+ const struct btrfs_super_block *bfs;
if (pr->zone_size) {
#ifdef HAVE_LINUX_BLKZONED_H
diff --git a/libblkid/src/superblocks/cramfs.c b/libblkid/src/superblocks/cramfs.c
index 2a87acd..6a8731f 100644
--- a/libblkid/src/superblocks/cramfs.c
+++ b/libblkid/src/superblocks/cramfs.c
@@ -37,12 +37,6 @@ struct cramfs_super
#define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */
-static int cramfs_is_little_endian(const struct blkid_idmag *mag)
-{
- assert(mag->len == 4);
- return memcmp(mag->magic, "\x45\x3d\xcd\x28", 4) == 0;
-}
-
static uint32_t cfs32_to_cpu(int le, uint32_t value)
{
if (le)
@@ -52,10 +46,10 @@ static uint32_t cfs32_to_cpu(int le, uint32_t value)
}
static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
- struct cramfs_super *cs, int le)
+ const struct cramfs_super *cs, int le)
{
uint32_t crc, expected, csummed_size;
- unsigned char *csummed;
+ const unsigned char *csummed;
expected = cfs32_to_cpu(le, cs->info.crc);
csummed_size = cfs32_to_cpu(le, cs->size);
@@ -67,22 +61,23 @@ static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size);
if (!csummed)
return 0;
- memset(csummed + offsetof(struct cramfs_super, info.crc), 0, sizeof(uint32_t));
- crc = ~ul_crc32(~0LL, csummed, csummed_size);
+ crc = ~ul_crc32_exclude_offset(~0LL, csummed, csummed_size,
+ offsetof(struct cramfs_super, info.crc),
+ sizeof_member(struct cramfs_super, info.crc));
return blkid_probe_verify_csum(pr, crc, expected);
}
static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct cramfs_super *cs;
+ const struct cramfs_super *cs;
cs = blkid_probe_get_sb(pr, mag, struct cramfs_super);
if (!cs)
return errno ? -errno : 1;
- int le = cramfs_is_little_endian(mag);
+ int le = mag->hint == BLKID_ENDIANNESS_LITTLE;
int v2 = cfs32_to_cpu(le, cs->flags) & CRAMFS_FLAG_FSID_VERSION_2;
if (v2 && !cramfs_verify_csum(pr, mag, cs, le))
@@ -91,8 +86,7 @@ static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag)
blkid_probe_set_label(pr, cs->name, sizeof(cs->name));
blkid_probe_set_fssize(pr, cfs32_to_cpu(le, cs->size));
blkid_probe_sprintf_version(pr, "%d", v2 ? 2 : 1);
- blkid_probe_set_fsendianness(pr,
- le ? BLKID_ENDIANNESS_LITTLE : BLKID_ENDIANNESS_BIG);
+ blkid_probe_set_fsendianness(pr, mag->hint);
return 0;
}
@@ -103,8 +97,10 @@ const struct blkid_idinfo cramfs_idinfo =
.probefunc = probe_cramfs,
.magics =
{
- { .magic = "\x45\x3d\xcd\x28", .len = 4 },
- { .magic = "\x28\xcd\x3d\x45", .len = 4 },
+ { .magic = "\x45\x3d\xcd\x28", .len = 4,
+ .hint = BLKID_ENDIANNESS_LITTLE },
+ { .magic = "\x28\xcd\x3d\x45", .len = 4,
+ .hint = BLKID_ENDIANNESS_BIG },
{ NULL }
}
};
diff --git a/libblkid/src/superblocks/cs_fvault2.c b/libblkid/src/superblocks/cs_fvault2.c
index ef2b567..187258d 100644
--- a/libblkid/src/superblocks/cs_fvault2.c
+++ b/libblkid/src/superblocks/cs_fvault2.c
@@ -65,7 +65,7 @@ static int cs_fvault2_verify_csum(blkid_probe pr, const struct cs_fvault2_sb *sb
static int probe_cs_fvault2(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct cs_fvault2_sb *sb;
+ const struct cs_fvault2_sb *sb;
sb = blkid_probe_get_sb(pr, mag, struct cs_fvault2_sb);
if (!sb)
diff --git a/libblkid/src/superblocks/ddf_raid.c b/libblkid/src/superblocks/ddf_raid.c
index 0b82e73..a7cf32c 100644
--- a/libblkid/src/superblocks/ddf_raid.c
+++ b/libblkid/src/superblocks/ddf_raid.c
@@ -80,9 +80,6 @@ static int probe_ddf(blkid_probe pr,
char version[DDF_REV_LENGTH + 1];
uint64_t off = 0, lba;
- if (pr->size < 0x30000)
- return 1;
-
for (i = 0; i < ARRAY_SIZE(hdrs); i++) {
off = ((pr->size / 0x200) - hdrs[i]) * 0x200;
@@ -106,7 +103,7 @@ static int probe_ddf(blkid_probe pr,
if (lba > 0) {
/* check primary header */
- unsigned char *buf;
+ const unsigned char *buf;
buf = blkid_probe_get_buffer(pr,
lba << 9, sizeof(ddf->signature));
@@ -134,6 +131,7 @@ static int probe_ddf(blkid_probe pr,
const struct blkid_idinfo ddfraid_idinfo = {
.name = "ddf_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x30000,
.probefunc = probe_ddf,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/drbd.c b/libblkid/src/superblocks/drbd.c
index f360186..96a2168 100644
--- a/libblkid/src/superblocks/drbd.c
+++ b/libblkid/src/superblocks/drbd.c
@@ -18,18 +18,24 @@
#include "superblocks.h"
+enum {
+ DRBD_VERSION_08,
+ DRBD_VERSION_09,
+};
+
/*
- * drbd/linux/drbd.h
+ * drbd/drbd_int.h
*/
-#define DRBD_MAGIC 0x83740267
+#define BM_BLOCK_SHIFT 12 /* 4k per bit */
+#define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT)
/*
* user/drbdmeta.c
* We support v08 and v09
*/
-#define DRBD_MD_MAGIC_08 (DRBD_MAGIC+4)
-#define DRBD_MD_MAGIC_84_UNCLEAN (DRBD_MAGIC+5)
-#define DRBD_MD_MAGIC_09 (DRBD_MAGIC+6)
+#define DRBD_MD_MAGIC_08 "\x83\x74\x02\x6b"
+#define DRBD_MD_MAGIC_84_UNCLEAN "\x83\x74\x02\x6c"
+#define DRBD_MD_MAGIC_09 "\x83\x74\x02\x6d"
/* there is no DRBD_MD_MAGIC_09_UNCLEAN */
/*
@@ -70,9 +76,8 @@ struct md_on_disk_08 {
uint32_t bm_bytes_per_bit;
uint32_t reserved_u32[4];
- /* Unnecessary for libblkid **
- * char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)];
- */
+ unsigned char padding_start[0];
+ unsigned char padding_end[0] __attribute__((aligned(4096)));
};
/*
@@ -118,32 +123,34 @@ struct meta_data_on_disk_9 {
struct peer_dev_md_on_disk_9 peers[DRBD_PEERS_MAX];
uint64_t history_uuids[HISTORY_UUIDS];
- /* Unnecessary for libblkid **
- * char padding[0] __attribute__((aligned(4096)));
- */
+ unsigned char padding_start[0];
+ unsigned char padding_end[0] __attribute__((aligned(4096)));
} __attribute__((packed));
-static int probe_drbd_84(blkid_probe pr)
+static int is_zero_padded(const unsigned char *padding_start,
+ const unsigned char *padding_end)
{
- struct md_on_disk_08 *md;
- off_t off;
-
- off = pr->size - DRBD_MD_OFFSET;
+ for (; padding_start < padding_end; padding_start++) {
+ if (*padding_start != 0)
+ return 0;
+ }
+ return 1;
+}
- /* Small devices cannot be drbd (?) */
- if (pr->size < 0x10000)
- return 1;
+static int probe_drbd_84(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ const struct md_on_disk_08 *md;
- md = (struct md_on_disk_08 *)
- blkid_probe_get_buffer(pr,
- off,
- sizeof(struct md_on_disk_08));
+ md = blkid_probe_get_sb(pr, mag, struct md_on_disk_08);
if (!md)
return errno ? -errno : 1;
- if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_08 &&
- be32_to_cpu(md->magic) != DRBD_MD_MAGIC_84_UNCLEAN)
+ if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE)
+ return 1;
+
+ if (!is_zero_padded(member_ptr(md, padding_start),
+ member_ptr(md, padding_end)))
return 1;
/*
@@ -151,43 +158,27 @@ static int probe_drbd_84(blkid_probe pr)
* notion of uuids (64 bit, see struct above)
*/
blkid_probe_sprintf_uuid(pr,
- (unsigned char *) &md->device_uuid, sizeof(md->device_uuid),
- "%" PRIx64, be64_to_cpu(md->device_uuid));
+ member_ptr(md, device_uuid), sizeof(md->device_uuid),
+ "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid)));
blkid_probe_set_version(pr, "v08");
- if (blkid_probe_set_magic(pr,
- off + offsetof(struct md_on_disk_08, magic),
- sizeof(md->magic),
- (unsigned char *) &md->magic))
- return 1;
-
return 0;
}
-static int probe_drbd_90(blkid_probe pr)
+static int probe_drbd_90(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct meta_data_on_disk_9 *md;
- off_t off;
-
- off = pr->size - DRBD_MD_OFFSET;
-
- /*
- * Smaller ones are certainly not DRBD9 devices.
- * Recent utils even refuse to generate larger ones,
- * keep this as a sufficient lower bound.
- */
- if (pr->size < 0x10000)
- return 1;
+ const struct meta_data_on_disk_9 *md;
- md = (struct meta_data_on_disk_9 *)
- blkid_probe_get_buffer(pr,
- off,
- sizeof(struct meta_data_on_disk_9));
+ md = blkid_probe_get_sb(pr, mag, struct meta_data_on_disk_9);
if (!md)
return errno ? -errno : 1;
- if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_09)
+ if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE)
+ return 1;
+
+ if (!is_zero_padded(member_ptr(md, padding_start),
+ member_ptr(md, padding_end)))
return 1;
/*
@@ -195,30 +186,23 @@ static int probe_drbd_90(blkid_probe pr)
* notion of uuids (64 bit, see struct above)
*/
blkid_probe_sprintf_uuid(pr,
- (unsigned char *) &md->device_uuid, sizeof(md->device_uuid),
- "%" PRIx64, be64_to_cpu(md->device_uuid));
+ member_ptr(md, device_uuid), sizeof(md->device_uuid),
+ "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid)));
blkid_probe_set_version(pr, "v09");
- if (blkid_probe_set_magic(pr,
- off + offsetof(struct meta_data_on_disk_9, magic),
- sizeof(md->magic),
- (unsigned char *) &md->magic))
- return 1;
-
return 0;
}
-static int probe_drbd(blkid_probe pr,
- const struct blkid_idmag *mag __attribute__((__unused__)))
+static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag)
{
- int ret;
+ if (mag->hint == DRBD_VERSION_08)
+ return probe_drbd_84(pr, mag);
- ret = probe_drbd_84(pr);
- if (ret <= 0) /* success or fatal (-errno) */
- return ret;
+ if (mag->hint == DRBD_VERSION_09)
+ return probe_drbd_90(pr, mag);
- return probe_drbd_90(pr);
+ return 1;
}
const struct blkid_idinfo drbd_idinfo =
@@ -226,6 +210,35 @@ const struct blkid_idinfo drbd_idinfo =
.name = "drbd",
.usage = BLKID_USAGE_RAID,
.probefunc = probe_drbd,
- .magics = BLKID_NONE_MAGIC
+ /*
+ * Smaller ones are certainly not DRBD9 devices.
+ * Recent utils even refuse to generate larger ones,
+ * keep this as a sufficient lower bound.
+ */
+ .minsz = 0x10000,
+ .magics = {
+ {
+ .magic = DRBD_MD_MAGIC_08,
+ .len = sizeof(DRBD_MD_MAGIC_08) - 1,
+ .hint = DRBD_VERSION_08,
+ .kboff = -(DRBD_MD_OFFSET >> 10),
+ .sboff = offsetof(struct md_on_disk_08, magic),
+ },
+ {
+ .magic = DRBD_MD_MAGIC_84_UNCLEAN,
+ .len = sizeof(DRBD_MD_MAGIC_84_UNCLEAN) - 1,
+ .hint = DRBD_VERSION_08,
+ .kboff = -(DRBD_MD_OFFSET >> 10),
+ .sboff = offsetof(struct md_on_disk_08, magic),
+ },
+ {
+ .magic = DRBD_MD_MAGIC_09,
+ .len = sizeof(DRBD_MD_MAGIC_09) - 1,
+ .hint = DRBD_VERSION_09,
+ .kboff = -(DRBD_MD_OFFSET >> 10),
+ .sboff = offsetof(struct meta_data_on_disk_9, magic),
+ },
+ { NULL }
+ }
};
diff --git a/libblkid/src/superblocks/erofs.c b/libblkid/src/superblocks/erofs.c
index 14d272e..0582246 100644
--- a/libblkid/src/superblocks/erofs.c
+++ b/libblkid/src/superblocks/erofs.c
@@ -46,7 +46,7 @@ static int erofs_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag,
{
uint32_t expected, csum;
size_t csummed_size;
- unsigned char *csummed;
+ const unsigned char *csummed;
if (!(le32_to_cpu(sb->feature_compat) & EROFS_FEATURE_SB_CSUM))
return 1;
@@ -67,7 +67,7 @@ static int erofs_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag,
static int probe_erofs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct erofs_super_block *sb;
+ const struct erofs_super_block *sb;
sb = blkid_probe_get_sb(pr, mag, struct erofs_super_block);
if (!sb)
diff --git a/libblkid/src/superblocks/exfat.c b/libblkid/src/superblocks/exfat.c
index fda1ecd..18a3e07 100644
--- a/libblkid/src/superblocks/exfat.c
+++ b/libblkid/src/superblocks/exfat.c
@@ -121,7 +121,7 @@ static struct exfat_entry_label *find_label(blkid_probe pr,
}
/* From https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#34-main-and-backup-boot-checksum-sub-regions */
-static uint32_t exfat_boot_checksum(unsigned char *sectors,
+static uint32_t exfat_boot_checksum(const unsigned char *sectors,
size_t sector_size)
{
uint32_t n_bytes = sector_size * 11;
@@ -143,7 +143,7 @@ static int exfat_validate_checksum(blkid_probe pr,
{
size_t sector_size = BLOCK_SIZE(sb);
/* 11 sectors will be checksummed, the 12th contains the expected */
- unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12);
+ const unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12);
if (!data)
return 0;
@@ -191,7 +191,7 @@ extern int blkid_probe_is_exfat(blkid_probe pr);
*/
int blkid_probe_is_exfat(blkid_probe pr)
{
- struct exfat_super_block *sb;
+ const struct exfat_super_block *sb;
const struct blkid_idmag *mag = NULL;
int rc;
@@ -213,7 +213,7 @@ int blkid_probe_is_exfat(blkid_probe pr)
static int probe_exfat(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct exfat_super_block *sb;
+ const struct exfat_super_block *sb;
struct exfat_entry_label *label;
sb = blkid_probe_get_sb(pr, mag, struct exfat_super_block);
diff --git a/libblkid/src/superblocks/exfs.c b/libblkid/src/superblocks/exfs.c
index 87dc0a0..0a169bd 100644
--- a/libblkid/src/superblocks/exfs.c
+++ b/libblkid/src/superblocks/exfs.c
@@ -85,7 +85,7 @@ struct exfs_super_block {
(s)->sb_agblocks + EXFS_MIN_AG_BLOCKS)
-static void sb_from_disk(struct exfs_super_block *from,
+static void sb_from_disk(const struct exfs_super_block *from,
struct exfs_super_block *to)
{
@@ -121,7 +121,7 @@ static void sb_from_disk(struct exfs_super_block *from,
to->sb_frextents = be64_to_cpu(from->sb_frextents);
}
-static int exfs_verify_sb(struct exfs_super_block *ondisk)
+static int exfs_verify_sb(const struct exfs_super_block *ondisk)
{
struct exfs_super_block sb, *sbp = &sb;
@@ -158,7 +158,7 @@ static int exfs_verify_sb(struct exfs_super_block *ondisk)
static int probe_exfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct exfs_super_block *xs;
+ const struct exfs_super_block *xs;
xs = blkid_probe_get_sb(pr, mag, struct exfs_super_block);
if (!xs)
diff --git a/libblkid/src/superblocks/f2fs.c b/libblkid/src/superblocks/f2fs.c
index 980111e..4e0fdbf 100644
--- a/libblkid/src/superblocks/f2fs.c
+++ b/libblkid/src/superblocks/f2fs.c
@@ -67,14 +67,14 @@ static int f2fs_validate_checksum(blkid_probe pr, size_t sb_off,
if (csum_off + sizeof(uint32_t) > 4096)
return 0;
- unsigned char *csum_data = blkid_probe_get_buffer(pr,
+ const unsigned char *csum_data = blkid_probe_get_buffer(pr,
sb_off + csum_off, sizeof(uint32_t));
if (!csum_data)
return 0;
uint32_t expected = le32_to_cpu(*(uint32_t *) csum_data);
- unsigned char *csummed = blkid_probe_get_buffer(pr, sb_off, csum_off);
+ const unsigned char *csummed = blkid_probe_get_buffer(pr, sb_off, csum_off);
if (!csummed)
return 0;
@@ -85,7 +85,7 @@ static int f2fs_validate_checksum(blkid_probe pr, size_t sb_off,
static int probe_f2fs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct f2fs_super_block *sb;
+ const struct f2fs_super_block *sb;
uint16_t vermaj, vermin;
sb = blkid_probe_get_sb(pr, mag, struct f2fs_super_block);
diff --git a/libblkid/src/superblocks/gfs.c b/libblkid/src/superblocks/gfs.c
index 445c0da..18d978a 100644
--- a/libblkid/src/superblocks/gfs.c
+++ b/libblkid/src/superblocks/gfs.c
@@ -59,7 +59,7 @@ struct gfs2_sb {
static int probe_gfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct gfs2_sb *sbd;
+ const struct gfs2_sb *sbd;
sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
if (!sbd)
@@ -91,7 +91,7 @@ static inline int gfs2_multiformat_is_valid(uint32_t multi)
static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct gfs2_sb *sbd;
+ const struct gfs2_sb *sbd;
sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
if (!sbd)
diff --git a/libblkid/src/superblocks/hfs.c b/libblkid/src/superblocks/hfs.c
index 68cb30e..49a0e60 100644
--- a/libblkid/src/superblocks/hfs.c
+++ b/libblkid/src/superblocks/hfs.c
@@ -154,7 +154,7 @@ static int hfs_set_uuid(blkid_probe pr, unsigned char const *hfs_info, size_t le
static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct hfs_mdb *hfs;
+ const struct hfs_mdb *hfs;
int size;
hfs = blkid_probe_get_sb(pr, mag, struct hfs_mdb);
@@ -183,11 +183,11 @@ static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag)
static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
{
struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
- struct hfsplus_bnode_descriptor *descr;
- struct hfsplus_bheader_record *bnode;
- struct hfsplus_catalog_key *key;
- struct hfsplus_vol_header *hfsplus;
- struct hfs_mdb *sbd;
+ const struct hfsplus_bnode_descriptor *descr;
+ const struct hfsplus_bheader_record *bnode;
+ const struct hfsplus_catalog_key *key;
+ const struct hfsplus_vol_header *hfsplus;
+ const struct hfs_mdb *sbd;
unsigned int alloc_block_size;
unsigned int alloc_first_block;
unsigned int embed_first_block;
@@ -203,7 +203,7 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
unsigned int leaf_block;
int ext;
uint64_t leaf_off;
- unsigned char *buf;
+ const unsigned char *buf;
sbd = blkid_probe_get_sb(pr, mag, struct hfs_mdb);
if (!sbd)
@@ -217,6 +217,10 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
return 1;
alloc_block_size = be32_to_cpu(sbd->al_blk_size);
+ if (alloc_block_size < HFSPLUS_SECTOR_SIZE ||
+ alloc_block_size % HFSPLUS_SECTOR_SIZE)
+ return 1;
+
alloc_first_block = be16_to_cpu(sbd->al_bl_st);
embed_first_block = be16_to_cpu(sbd->embed_startblock);
off = (alloc_first_block * 512) +
@@ -225,7 +229,7 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
buf = blkid_probe_get_buffer(pr,
off + (mag->kboff * 1024),
sizeof(struct hfsplus_vol_header));
- hfsplus = (struct hfsplus_vol_header *) buf;
+ hfsplus = (const struct hfsplus_vol_header *) buf;
} else
hfsplus = blkid_probe_get_sb(pr, mag,
@@ -238,17 +242,23 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
(memcmp(hfsplus->signature, "HX", 2) != 0))
return 1;
- hfs_set_uuid(pr, hfsplus->finder_info.id, sizeof(hfsplus->finder_info.id));
-
+ /* Verify blocksize is initialized */
blocksize = be32_to_cpu(hfsplus->blocksize);
- if (blocksize < HFSPLUS_SECTOR_SIZE)
+ if (blocksize < HFSPLUS_SECTOR_SIZE || !is_power_of_2(blocksize))
return 1;
- blkid_probe_set_fsblocksize(pr, blocksize);
- blkid_probe_set_block_size(pr, blocksize);
-
+ /* Save extends (hfsplus buffer may be later overwritten) */
memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
+
+ /* Make sure start_block is properly initialized */
cat_block = be32_to_cpu(extents[0].start_block);
+ if (off + ((uint64_t) cat_block * blocksize) > pr->size)
+ return 1;
+
+ hfs_set_uuid(pr, hfsplus->finder_info.id, sizeof(hfsplus->finder_info.id));
+
+ blkid_probe_set_fsblocksize(pr, blocksize);
+ blkid_probe_set_block_size(pr, blocksize);
buf = blkid_probe_get_buffer(pr,
off + ((uint64_t) cat_block * blocksize), 0x2000);
diff --git a/libblkid/src/superblocks/highpoint_raid.c b/libblkid/src/superblocks/highpoint_raid.c
index 2487930..c8b1297 100644
--- a/libblkid/src/superblocks/highpoint_raid.c
+++ b/libblkid/src/superblocks/highpoint_raid.c
@@ -29,8 +29,6 @@ static int probe_highpoint45x(blkid_probe pr,
uint64_t off;
uint32_t magic;
- if (pr->size < 0x10000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -62,6 +60,7 @@ static int probe_highpoint37x(blkid_probe pr,
const struct blkid_idinfo highpoint45x_idinfo = {
.name = "hpt45x_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_highpoint45x,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/hpfs.c b/libblkid/src/superblocks/hpfs.c
index 09bf975..f7ee02d 100644
--- a/libblkid/src/superblocks/hpfs.c
+++ b/libblkid/src/superblocks/hpfs.c
@@ -60,9 +60,9 @@ struct hpfs_spare_super
static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct hpfs_super_block *hs;
- struct hpfs_spare_super *hss;
- struct hpfs_boot_block *hbb;
+ const struct hpfs_super_block *hs;
+ const struct hpfs_spare_super *hss;
+ const struct hpfs_boot_block *hbb;
uint8_t version;
/* super block */
diff --git a/libblkid/src/superblocks/iso9660.c b/libblkid/src/superblocks/iso9660.c
index 536704b..a7a364f 100644
--- a/libblkid/src/superblocks/iso9660.c
+++ b/libblkid/src/superblocks/iso9660.c
@@ -22,7 +22,7 @@
#include "cctype.h"
#include "iso9660.h"
-struct iso9660_date {
+struct hs_date {
unsigned char year[4];
unsigned char month[2];
unsigned char day[2];
@@ -30,11 +30,16 @@ struct iso9660_date {
unsigned char minute[2];
unsigned char second[2];
unsigned char hundredth[2];
+} __attribute__ ((packed));
+
+struct iso9660_date {
+ struct hs_date common;
unsigned char offset;
} __attribute__ ((packed));
/* PVD - Primary volume descriptor */
struct iso_volume_descriptor {
+ /* High Sierra has 8 bytes before descriptor with Volume Descriptor LBN value, those are skipped by blkid_probe_get_buffer() */
unsigned char vd_type;
unsigned char vd_id[5];
unsigned char vd_version;
@@ -43,21 +48,59 @@ struct iso_volume_descriptor {
unsigned char volume_id[32];
unsigned char unused[8];
unsigned char space_size[8];
- unsigned char escape_sequences[8];
- unsigned char unused2[32];
+ unsigned char escape_sequences[32];
+ unsigned char set_size[4];
+ unsigned char vol_seq_num[4];
unsigned char logical_block_size[4];
- unsigned char unused3[58];
- unsigned char volume_set_id[128];
- unsigned char publisher_id[128];
- unsigned char data_preparer_id[128];
- unsigned char application_id[128];
- unsigned char unused4[111];
- struct iso9660_date created;
- struct iso9660_date modified;
+ unsigned char path_table_size[8];
+ union {
+ struct {
+ unsigned char type_l_path_table[4];
+ unsigned char opt_type_l_path_table[4];
+ unsigned char type_m_path_table[4];
+ unsigned char opt_type_m_path_table[4];
+ unsigned char root_dir_record[34];
+ unsigned char volume_set_id[128];
+ unsigned char publisher_id[128];
+ unsigned char data_preparer_id[128];
+ unsigned char application_id[128];
+ unsigned char copyright_file_id[37];
+ unsigned char abstract_file_id[37];
+ unsigned char bibliographic_file_id[37];
+ struct iso9660_date created;
+ struct iso9660_date modified;
+ struct iso9660_date expiration;
+ struct iso9660_date effective;
+ unsigned char std_version;
+ } iso; /* ISO9660 */
+ struct {
+ unsigned char type_l_path_table[4];
+ unsigned char opt1_type_l_path_table[4];
+ unsigned char opt2_type_l_path_table[4];
+ unsigned char opt3_type_l_path_table[4];
+ unsigned char type_m_path_table[4];
+ unsigned char opt1_type_m_path_table[4];
+ unsigned char opt2_type_m_path_table[4];
+ unsigned char opt3_type_m_path_table[4];
+ unsigned char root_dir_record[34];
+ unsigned char volume_set_id[128];
+ unsigned char publisher_id[128];
+ unsigned char data_preparer_id[128];
+ unsigned char application_id[128];
+ unsigned char copyright_file_id[32];
+ unsigned char abstract_file_id[32];
+ struct hs_date created;
+ struct hs_date modified;
+ struct hs_date expiration;
+ struct hs_date effective;
+ unsigned char std_version;
+ } hs; /* High Sierra */
+ };
} __attribute__((packed));
/* Boot Record */
struct boot_record {
+ /* High Sierra has 8 bytes before descriptor with Volume Descriptor LBN value, those are skipped by blkid_probe_get_buffer() */
unsigned char vd_type;
unsigned char vd_id[5];
unsigned char vd_version;
@@ -74,35 +117,9 @@ struct boot_record {
#define ISO_VD_END 0xff
#define ISO_VD_MAX 16
/* maximal string field size used anywhere in ISO; update if necessary */
-#define ISO_MAX_FIELDSIZ sizeof_member(struct iso_volume_descriptor, volume_set_id)
-
-struct high_sierra_volume_descriptor {
- unsigned char foo[8];
- unsigned char type;
- unsigned char id[5];
- unsigned char version;
- unsigned char unused1;
- unsigned char system_id[32];
- unsigned char volume_id[32];
-} __attribute__((packed));
-
-/* old High Sierra format */
-static int probe_iso9660_hsfs(blkid_probe pr, const struct blkid_idmag *mag)
-{
- struct high_sierra_volume_descriptor *iso;
+#define ISO_MAX_FIELDSIZ sizeof_member(struct iso_volume_descriptor, iso.volume_set_id)
- iso = blkid_probe_get_sb(pr, mag, struct high_sierra_volume_descriptor);
- if (!iso)
- return errno ? -errno : 1;
-
- blkid_probe_set_fsblocksize(pr, ISO_SECTOR_SIZE);
- blkid_probe_set_block_size(pr, ISO_SECTOR_SIZE);
- blkid_probe_set_version(pr, "High Sierra");
- blkid_probe_set_label(pr, iso->volume_id, sizeof(iso->volume_id));
- return 0;
-}
-
-static int probe_iso9660_set_uuid (blkid_probe pr, const struct iso9660_date *date)
+static int probe_iso9660_set_uuid (blkid_probe pr, const struct hs_date *date, unsigned char offset)
{
unsigned char buffer[16];
unsigned int i, zeros = 0;
@@ -130,7 +147,7 @@ static int probe_iso9660_set_uuid (blkid_probe pr, const struct iso9660_date *da
zeros++;
/* due to the iso9660 standard if all date fields are '0' and offset is 0, the date is unset */
- if (zeros == sizeof(buffer) && date->offset == 0)
+ if (zeros == sizeof(buffer) && offset == 0)
return 0;
/* generate an UUID using this date and return success */
@@ -216,9 +233,15 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
struct iso_volume_descriptor *joliet = NULL;
/* space for merge_utf16be_ascii(ISO_ID_BUFSIZ bytes) */
unsigned char buf[ISO_MAX_FIELDSIZ * 5 / 2];
+ const struct hs_date *modified;
+ const struct hs_date *created;
+ unsigned char modified_offset;
+ unsigned char created_offset;
size_t len;
+ int is_hs;
int is_unicode_empty;
- int is_ascii_empty;
+ int is_ascii_hs_empty;
+ int is_ascii_iso_empty;
int i;
uint64_t off;
@@ -228,13 +251,12 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
if (off % ISO_SECTOR_SIZE)
return 1;
- if (strcmp(mag->magic, "CDROM") == 0)
- return probe_iso9660_hsfs(pr, mag);
+ is_hs = (strcmp(mag->magic, "CDROM") == 0);
- for (i = 0, off += ISO_SUPERBLOCK_OFFSET; i < ISO_VD_MAX && (!boot || !pvd || !joliet); i++, off += ISO_SECTOR_SIZE) {
- unsigned char *desc =
+ for (i = 0, off += ISO_SUPERBLOCK_OFFSET; i < ISO_VD_MAX && (!boot || !pvd || (!is_hs && !joliet)); i++, off += ISO_SECTOR_SIZE) {
+ const unsigned char *desc =
blkid_probe_get_buffer(pr,
- off,
+ off + (is_hs ? 8 : 0), /* High Sierra has 8 bytes before descriptor with Volume Descriptor LBN value */
max(sizeof(struct boot_record),
sizeof(struct iso_volume_descriptor)));
@@ -244,7 +266,7 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
boot = (struct boot_record *)desc;
else if (!pvd && desc[0] == ISO_VD_PRIMARY)
pvd = (struct iso_volume_descriptor *)desc;
- else if (!joliet && desc[0] == ISO_VD_SUPPLEMENTARY) {
+ else if (!is_hs && !joliet && desc[0] == ISO_VD_SUPPLEMENTARY) {
joliet = (struct iso_volume_descriptor *)desc;
if (memcmp(joliet->escape_sequences, "%/@", 3) != 0 &&
memcmp(joliet->escape_sequences, "%/C", 3) != 0 &&
@@ -270,43 +292,66 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
else
blkid_probe_set_id_label(pr, "SYSTEM_ID", pvd->system_id, sizeof(pvd->system_id));
- if (joliet && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->volume_set_id, pvd->volume_set_id, sizeof(pvd->volume_set_id))) != 0)
+ if (joliet && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.volume_set_id, pvd->iso.volume_set_id, sizeof(pvd->iso.volume_set_id))) != 0)
blkid_probe_set_utf8_id_label(pr, "VOLUME_SET_ID", buf, len, UL_ENCODE_UTF16BE);
else if (joliet)
- blkid_probe_set_utf8_id_label(pr, "VOLUME_SET_ID", joliet->volume_set_id, sizeof(joliet->volume_set_id), UL_ENCODE_UTF16BE);
+ blkid_probe_set_utf8_id_label(pr, "VOLUME_SET_ID", joliet->iso.volume_set_id, sizeof(joliet->iso.volume_set_id), UL_ENCODE_UTF16BE);
+ else if (is_hs)
+ blkid_probe_set_id_label(pr, "VOLUME_SET_ID", pvd->hs.volume_set_id, sizeof(pvd->hs.volume_set_id));
else
- blkid_probe_set_id_label(pr, "VOLUME_SET_ID", pvd->volume_set_id, sizeof(pvd->volume_set_id));
+ blkid_probe_set_id_label(pr, "VOLUME_SET_ID", pvd->iso.volume_set_id, sizeof(pvd->iso.volume_set_id));
- is_ascii_empty = (is_str_empty(pvd->publisher_id, sizeof(pvd->publisher_id)) || pvd->publisher_id[0] == '_');
- is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->publisher_id, sizeof(joliet->publisher_id)) || (joliet->publisher_id[0] == 0x00 && joliet->publisher_id[1] == '_'));
- if (!is_unicode_empty && !is_ascii_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->publisher_id, pvd->publisher_id, sizeof(pvd->publisher_id))) != 0)
+ is_ascii_hs_empty = (!is_hs || is_str_empty(pvd->hs.publisher_id, sizeof(pvd->hs.publisher_id)) || pvd->hs.publisher_id[0] == '_');
+ is_ascii_iso_empty = (is_hs || is_str_empty(pvd->iso.publisher_id, sizeof(pvd->iso.publisher_id)) || pvd->iso.publisher_id[0] == '_');
+ is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->iso.publisher_id, sizeof(joliet->iso.publisher_id)) || (joliet->iso.publisher_id[0] == 0x00 && joliet->iso.publisher_id[1] == '_'));
+ if (!is_unicode_empty && !is_ascii_iso_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.publisher_id, pvd->iso.publisher_id, sizeof(pvd->iso.publisher_id))) != 0)
blkid_probe_set_utf8_id_label(pr, "PUBLISHER_ID", buf, len, UL_ENCODE_UTF16BE);
else if (!is_unicode_empty)
- blkid_probe_set_utf8_id_label(pr, "PUBLISHER_ID", joliet->publisher_id, sizeof(joliet->publisher_id), UL_ENCODE_UTF16BE);
- else if (!is_ascii_empty)
- blkid_probe_set_id_label(pr, "PUBLISHER_ID", pvd->publisher_id, sizeof(pvd->publisher_id));
-
- is_ascii_empty = (is_str_empty(pvd->data_preparer_id, sizeof(pvd->data_preparer_id)) || pvd->data_preparer_id[0] == '_');
- is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->data_preparer_id, sizeof(joliet->data_preparer_id)) || (joliet->data_preparer_id[0] == 0x00 && joliet->data_preparer_id[1] == '_'));
- if (!is_unicode_empty && !is_ascii_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->data_preparer_id, pvd->data_preparer_id, sizeof(pvd->data_preparer_id))) != 0)
+ blkid_probe_set_utf8_id_label(pr, "PUBLISHER_ID", joliet->iso.publisher_id, sizeof(joliet->iso.publisher_id), UL_ENCODE_UTF16BE);
+ else if (!is_ascii_hs_empty)
+ blkid_probe_set_id_label(pr, "PUBLISHER_ID", pvd->hs.publisher_id, sizeof(pvd->hs.publisher_id));
+ else if (!is_ascii_iso_empty)
+ blkid_probe_set_id_label(pr, "PUBLISHER_ID", pvd->iso.publisher_id, sizeof(pvd->iso.publisher_id));
+
+ is_ascii_hs_empty = (!is_hs || is_str_empty(pvd->hs.data_preparer_id, sizeof(pvd->hs.data_preparer_id)) || pvd->hs.data_preparer_id[0] == '_');
+ is_ascii_iso_empty = (is_hs || is_str_empty(pvd->iso.data_preparer_id, sizeof(pvd->iso.data_preparer_id)) || pvd->iso.data_preparer_id[0] == '_');
+ is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->iso.data_preparer_id, sizeof(joliet->iso.data_preparer_id)) || (joliet->iso.data_preparer_id[0] == 0x00 && joliet->iso.data_preparer_id[1] == '_'));
+ if (!is_unicode_empty && !is_ascii_iso_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.data_preparer_id, pvd->iso.data_preparer_id, sizeof(pvd->iso.data_preparer_id))) != 0)
blkid_probe_set_utf8_id_label(pr, "DATA_PREPARER_ID", buf, len, UL_ENCODE_UTF16BE);
else if (!is_unicode_empty)
- blkid_probe_set_utf8_id_label(pr, "DATA_PREPARER_ID", joliet->data_preparer_id, sizeof(joliet->data_preparer_id), UL_ENCODE_UTF16BE);
- else if (!is_ascii_empty)
- blkid_probe_set_id_label(pr, "DATA_PREPARER_ID", pvd->data_preparer_id, sizeof(pvd->data_preparer_id));
-
- is_ascii_empty = (is_str_empty(pvd->application_id, sizeof(pvd->application_id)) || pvd->application_id[0] == '_');
- is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->application_id, sizeof(joliet->application_id)) || (joliet->application_id[0] == 0x00 && joliet->application_id[1] == '_'));
- if (!is_unicode_empty && !is_ascii_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->application_id, pvd->application_id, sizeof(pvd->application_id))) != 0)
+ blkid_probe_set_utf8_id_label(pr, "DATA_PREPARER_ID", joliet->iso.data_preparer_id, sizeof(joliet->iso.data_preparer_id), UL_ENCODE_UTF16BE);
+ else if (!is_ascii_hs_empty)
+ blkid_probe_set_id_label(pr, "DATA_PREPARER_ID", pvd->hs.data_preparer_id, sizeof(pvd->hs.data_preparer_id));
+ else if (!is_ascii_iso_empty)
+ blkid_probe_set_id_label(pr, "DATA_PREPARER_ID", pvd->iso.data_preparer_id, sizeof(pvd->iso.data_preparer_id));
+
+ is_ascii_hs_empty = (!is_hs || is_str_empty(pvd->hs.application_id, sizeof(pvd->hs.application_id)) || pvd->hs.application_id[0] == '_');
+ is_ascii_iso_empty = (is_hs || is_str_empty(pvd->iso.application_id, sizeof(pvd->iso.application_id)) || pvd->iso.application_id[0] == '_');
+ is_unicode_empty = (!joliet || is_utf16be_str_empty(joliet->iso.application_id, sizeof(joliet->iso.application_id)) || (joliet->iso.application_id[0] == 0x00 && joliet->iso.application_id[1] == '_'));
+ if (!is_unicode_empty && !is_ascii_iso_empty && (len = merge_utf16be_ascii(buf, sizeof(buf), joliet->iso.application_id, pvd->iso.application_id, sizeof(pvd->iso.application_id))) != 0)
blkid_probe_set_utf8_id_label(pr, "APPLICATION_ID", buf, len, UL_ENCODE_UTF16BE);
else if (!is_unicode_empty)
- blkid_probe_set_utf8_id_label(pr, "APPLICATION_ID", joliet->application_id, sizeof(joliet->application_id), UL_ENCODE_UTF16BE);
- else if (!is_ascii_empty)
- blkid_probe_set_id_label(pr, "APPLICATION_ID", pvd->application_id, sizeof(pvd->application_id));
+ blkid_probe_set_utf8_id_label(pr, "APPLICATION_ID", joliet->iso.application_id, sizeof(joliet->iso.application_id), UL_ENCODE_UTF16BE);
+ else if (!is_ascii_hs_empty)
+ blkid_probe_set_id_label(pr, "APPLICATION_ID", pvd->hs.application_id, sizeof(pvd->hs.application_id));
+ else if (!is_ascii_iso_empty)
+ blkid_probe_set_id_label(pr, "APPLICATION_ID", pvd->iso.application_id, sizeof(pvd->iso.application_id));
+
+ if (is_hs) {
+ modified = &pvd->hs.modified;
+ created = &pvd->hs.created;
+ modified_offset = 0;
+ created_offset = 0;
+ } else {
+ modified = &pvd->iso.modified.common;
+ created = &pvd->iso.created.common;
+ modified_offset = pvd->iso.modified.offset;
+ created_offset = pvd->iso.created.offset;
+ }
/* create an UUID using the modified/created date */
- if (! probe_iso9660_set_uuid(pr, &pvd->modified))
- probe_iso9660_set_uuid(pr, &pvd->created);
+ if (! probe_iso9660_set_uuid(pr, modified, modified_offset))
+ probe_iso9660_set_uuid(pr, created, created_offset);
if (boot)
blkid_probe_set_id_label(pr, "BOOT_SYSTEM_ID",
@@ -315,6 +360,8 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
if (joliet)
blkid_probe_set_version(pr, "Joliet Extension");
+ else if (is_hs)
+ blkid_probe_set_version(pr, "High Sierra");
/* Label in Joliet is UNICODE (UTF16BE) but can contain only 16 characters. Label in PVD is
* subset of ASCII but can contain up to the 32 characters. Non-representable characters are
@@ -340,6 +387,10 @@ const struct blkid_idinfo iso9660_idinfo =
.flags = BLKID_IDINFO_TOLERANT,
.magics =
{
+ /*
+ * Due to different location of vd_id[] in ISO9660 and High Sierra, IS9660 can match
+ * also High Sierra vd_id[]. So always check ISO9660 (CD001) before High Sierra (CDROM).
+ */
{ .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" },
{ .magic = "CDROM", .len = 5, .kboff = 32, .sboff = 9, .hoff = "session_offset" },
{ NULL }
diff --git a/libblkid/src/superblocks/isw_raid.c b/libblkid/src/superblocks/isw_raid.c
index 81d53a1..aa03bcd 100644
--- a/libblkid/src/superblocks/isw_raid.c
+++ b/libblkid/src/superblocks/isw_raid.c
@@ -32,8 +32,6 @@ static int probe_iswraid(blkid_probe pr,
unsigned int sector_size;
struct isw_metadata *isw;
- if (pr->size < 0x10000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -60,6 +58,7 @@ static int probe_iswraid(blkid_probe pr,
const struct blkid_idinfo iswraid_idinfo = {
.name = "isw_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_iswraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/jfs.c b/libblkid/src/superblocks/jfs.c
index 7b75ecb..c277375 100644
--- a/libblkid/src/superblocks/jfs.c
+++ b/libblkid/src/superblocks/jfs.c
@@ -36,7 +36,7 @@ struct jfs_super_block {
static int probe_jfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct jfs_super_block *js;
+ const struct jfs_super_block *js;
js = blkid_probe_get_sb(pr, mag, struct jfs_super_block);
if (!js)
diff --git a/libblkid/src/superblocks/jmicron_raid.c b/libblkid/src/superblocks/jmicron_raid.c
index 65e05b6..4587075 100644
--- a/libblkid/src/superblocks/jmicron_raid.c
+++ b/libblkid/src/superblocks/jmicron_raid.c
@@ -75,8 +75,6 @@ static int probe_jmraid(blkid_probe pr,
uint64_t off;
const struct jm_metadata *jm;
- if (pr->size < 0x10000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -109,6 +107,7 @@ static int probe_jmraid(blkid_probe pr,
const struct blkid_idinfo jmraid_idinfo = {
.name = "jmicron_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_jmraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/linux_raid.c b/libblkid/src/superblocks/linux_raid.c
index 360cd4e..156b0bf 100644
--- a/libblkid/src/superblocks/linux_raid.c
+++ b/libblkid/src/superblocks/linux_raid.c
@@ -187,15 +187,14 @@ static int raid1_verify_csum(blkid_probe pr, off_t off,
{
size_t csummed_size = sizeof(struct mdp1_super_block)
+ le32_to_cpu(mdp1->max_dev) * sizeof(mdp1->dev_roles[0]);
- unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size);
+ const unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size);
if (!csummed)
return 1;
- memset(csummed + offsetof(struct mdp1_super_block, sb_csum), 0,
- sizeof(mdp1->sb_csum));
-
uint64_t csum = 0;
+ csum -= le32_to_cpu(*(uint32_t *) (csummed + offsetof(struct mdp1_super_block, sb_csum)));
+
while (csummed_size >= 4) {
csum += le32_to_cpu(*(uint32_t *) csummed);
csummed_size -= 4;
diff --git a/libblkid/src/superblocks/lsi_raid.c b/libblkid/src/superblocks/lsi_raid.c
index 697b0fe..2ceed9b 100644
--- a/libblkid/src/superblocks/lsi_raid.c
+++ b/libblkid/src/superblocks/lsi_raid.c
@@ -29,8 +29,6 @@ static int probe_lsiraid(blkid_probe pr,
uint64_t off;
struct lsi_metadata *lsi;
- if (pr->size < 0x10000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -53,6 +51,7 @@ static int probe_lsiraid(blkid_probe pr,
const struct blkid_idinfo lsiraid_idinfo = {
.name = "lsi_mega_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_lsiraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/luks.c b/libblkid/src/superblocks/luks.c
index 0230b34..4623c98 100644
--- a/libblkid/src/superblocks/luks.c
+++ b/libblkid/src/superblocks/luks.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 Karel Zak <kzak@redhat.com>
- * Copyright (C) 2018 Milan Broz <gmazyland@gmail.com>
+ * Copyright (C) 2018-2024 Milan Broz <gmazyland@gmail.com>
*
* Inspired by libvolume_id by
* Kay Sievers <kay.sievers@vrfy.org>
@@ -15,6 +15,7 @@
#include <errno.h>
#include <ctype.h>
#include <stdint.h>
+#include <stdbool.h>
#include "superblocks.h"
@@ -96,6 +97,19 @@ static int luks_attributes(blkid_probe pr, struct luks2_phdr *header, uint64_t o
return BLKID_PROBE_OK;
}
+static bool luks_valid(struct luks2_phdr *header, const char *magic, uint64_t offset)
+{
+ if (memcmp(header->magic, magic, LUKS_MAGIC_L))
+ return false;
+
+ /* LUKS2 header is not at expected offset */
+ if (be16_to_cpu(header->version) == 2 &&
+ be64_to_cpu(header->hdr_offset) != offset)
+ return false;
+
+ return true;
+}
+
static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__)))
{
struct luks2_phdr *header;
@@ -105,7 +119,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_
if (!header)
return errno ? -errno : BLKID_PROBE_NONE;
- if (!memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) {
+ if (luks_valid(header, LUKS_MAGIC, 0)) {
/* LUKS primary header was found. */
return luks_attributes(pr, header, 0);
}
@@ -118,7 +132,7 @@ static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute_
if (!header)
return errno ? -errno : BLKID_PROBE_NONE;
- if (!memcmp(header->magic, LUKS_MAGIC_2, LUKS_MAGIC_L))
+ if (luks_valid(header, LUKS_MAGIC_2, secondary_offsets[i]))
return luks_attributes(pr, header, secondary_offsets[i]);
}
diff --git a/libblkid/src/superblocks/lvm.c b/libblkid/src/superblocks/lvm.c
index eea74d6..0a3d505 100644
--- a/libblkid/src/superblocks/lvm.c
+++ b/libblkid/src/superblocks/lvm.c
@@ -76,11 +76,11 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
int sector = mag->kboff << 1;
struct lvm2_pv_label_header *label;
char uuid[LVM2_ID_LEN + 7];
- unsigned char *buf;
+ const unsigned char *buf;
buf = blkid_probe_get_buffer(pr,
mag->kboff << 10,
- 512 + sizeof(struct lvm2_pv_label_header));
+ 512 + LVM2_LABEL_SIZE);
if (!buf)
return errno ? -errno : 1;
@@ -122,7 +122,7 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
static int probe_lvm1(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct lvm1_pv_label_header *label;
+ const struct lvm1_pv_label_header *label;
char uuid[LVM2_ID_LEN + 7];
unsigned int version;
@@ -158,7 +158,7 @@ struct verity_sb {
static int probe_verity(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct verity_sb *sb;
+ const struct verity_sb *sb;
unsigned int version;
sb = blkid_probe_get_sb(pr, mag, struct verity_sb);
@@ -187,7 +187,7 @@ struct integrity_sb {
static int probe_integrity(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct integrity_sb *sb;
+ const struct integrity_sb *sb;
sb = blkid_probe_get_sb(pr, mag, struct integrity_sb);
if (sb == NULL)
diff --git a/libblkid/src/superblocks/minix.c b/libblkid/src/superblocks/minix.c
index c68ade9..dba299d 100644
--- a/libblkid/src/superblocks/minix.c
+++ b/libblkid/src/superblocks/minix.c
@@ -74,7 +74,7 @@ static int get_minix_version(const unsigned char *data, int *other_endian)
static int probe_minix(blkid_probe pr,
const struct blkid_idmag *mag __attribute__((__unused__)))
{
- unsigned char *ext;
+ const unsigned char *ext;
const unsigned char *data;
int version = 0, swabme = 0;
unsigned long zones, ninodes, imaps, zmaps;
diff --git a/libblkid/src/superblocks/mpool.c b/libblkid/src/superblocks/mpool.c
index b27569e..8a2e29c 100644
--- a/libblkid/src/superblocks/mpool.c
+++ b/libblkid/src/superblocks/mpool.c
@@ -26,7 +26,7 @@ struct omf_sb_descriptor {
static int probe_mpool(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct omf_sb_descriptor *osd;
+ const struct omf_sb_descriptor *osd;
uint32_t sb_crc;
osd = blkid_probe_get_sb(pr, mag, struct omf_sb_descriptor);
diff --git a/libblkid/src/superblocks/netware.c b/libblkid/src/superblocks/netware.c
index af81cf5..a8c20cb 100644
--- a/libblkid/src/superblocks/netware.c
+++ b/libblkid/src/superblocks/netware.c
@@ -67,7 +67,7 @@ struct netware_super_block {
static int probe_netware(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct netware_super_block *nw;
+ const struct netware_super_block *nw;
nw = blkid_probe_get_sb(pr, mag, struct netware_super_block);
if (!nw)
diff --git a/libblkid/src/superblocks/ntfs.c b/libblkid/src/superblocks/ntfs.c
index ab8c921..8ce557a 100644
--- a/libblkid/src/superblocks/ntfs.c
+++ b/libblkid/src/superblocks/ntfs.c
@@ -80,13 +80,13 @@ struct file_attribute {
static int __probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag, int save_info)
{
- struct ntfs_super_block *ns;
- struct master_file_table_record *mft;
+ const struct ntfs_super_block *ns;
+ const struct master_file_table_record *mft;
uint32_t sectors_per_cluster, mft_record_size;
uint16_t sector_size;
uint64_t nr_clusters, off, attr_off;
- unsigned char *buf_mft;
+ const unsigned char *buf_mft;
ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block);
if (!ns)
diff --git a/libblkid/src/superblocks/nvidia_raid.c b/libblkid/src/superblocks/nvidia_raid.c
index d930f72..1a88dbd 100644
--- a/libblkid/src/superblocks/nvidia_raid.c
+++ b/libblkid/src/superblocks/nvidia_raid.c
@@ -41,8 +41,6 @@ static int probe_nvraid(blkid_probe pr,
uint64_t off;
struct nv_metadata *nv;
- if (pr->size < 0x10000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -71,6 +69,7 @@ static int probe_nvraid(blkid_probe pr,
const struct blkid_idinfo nvraid_idinfo = {
.name = "nvidia_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_nvraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/ocfs.c b/libblkid/src/superblocks/ocfs.c
index e213d66..f2b2ca2 100644
--- a/libblkid/src/superblocks/ocfs.c
+++ b/libblkid/src/superblocks/ocfs.c
@@ -100,7 +100,7 @@ struct oracle_asm_disk_label {
static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- unsigned char *buf;
+ const unsigned char *buf;
struct ocfs_volume_header ovh;
struct ocfs_volume_label ovl;
uint32_t maj, min;
@@ -142,7 +142,7 @@ static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag)
static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct ocfs2_super_block *osb;
+ const struct ocfs2_super_block *osb;
osb = blkid_probe_get_sb(pr, mag, struct ocfs2_super_block);
if (!osb)
@@ -165,7 +165,7 @@ static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag)
static int probe_oracleasm(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct oracle_asm_disk_label *dl;
+ const struct oracle_asm_disk_label *dl;
dl = blkid_probe_get_sb(pr, mag, struct oracle_asm_disk_label);
if (!dl)
diff --git a/libblkid/src/superblocks/promise_raid.c b/libblkid/src/superblocks/promise_raid.c
index 75f3a20..f891b37 100644
--- a/libblkid/src/superblocks/promise_raid.c
+++ b/libblkid/src/superblocks/promise_raid.c
@@ -33,8 +33,6 @@ static int probe_pdcraid(blkid_probe pr,
};
uint64_t nsectors;
- if (pr->size < 0x40000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -70,6 +68,7 @@ static int probe_pdcraid(blkid_probe pr,
const struct blkid_idinfo pdcraid_idinfo = {
.name = "promise_fasttrack_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x40000,
.probefunc = probe_pdcraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/reiserfs.c b/libblkid/src/superblocks/reiserfs.c
index 23d10e2..dac5f0c 100644
--- a/libblkid/src/superblocks/reiserfs.c
+++ b/libblkid/src/superblocks/reiserfs.c
@@ -41,7 +41,7 @@ struct reiser4_super_block {
static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct reiserfs_super_block *rs;
+ const struct reiserfs_super_block *rs;
unsigned int blocksize;
rs = blkid_probe_get_sb(pr, mag, struct reiserfs_super_block);
@@ -82,7 +82,7 @@ static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag)
static int probe_reiser4(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct reiser4_super_block *rs4;
+ const struct reiser4_super_block *rs4;
unsigned int blocksize;
rs4 = blkid_probe_get_sb(pr, mag, struct reiser4_super_block);
diff --git a/libblkid/src/superblocks/romfs.c b/libblkid/src/superblocks/romfs.c
index 456cbfb..86c09ad 100644
--- a/libblkid/src/superblocks/romfs.c
+++ b/libblkid/src/superblocks/romfs.c
@@ -29,7 +29,7 @@ static int romfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
{
uint32_t csummed_size = min((uint32_t) 512,
be32_to_cpu(ros->ros_full_size));
- unsigned char *csummed;
+ const unsigned char *csummed;
uint32_t csum;
if (csummed_size % sizeof(uint32_t) != 0)
@@ -50,7 +50,7 @@ static int romfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
static int probe_romfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct romfs_super_block *ros;
+ const struct romfs_super_block *ros;
ros = blkid_probe_get_sb(pr, mag, struct romfs_super_block);
if (!ros)
diff --git a/libblkid/src/superblocks/silicon_raid.c b/libblkid/src/superblocks/silicon_raid.c
index 399eea8..0fc223d 100644
--- a/libblkid/src/superblocks/silicon_raid.c
+++ b/libblkid/src/superblocks/silicon_raid.c
@@ -91,8 +91,6 @@ static int probe_silraid(blkid_probe pr,
uint64_t off;
struct silicon_metadata *sil;
- if (pr->size < 0x10000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -127,6 +125,7 @@ static int probe_silraid(blkid_probe pr,
const struct blkid_idinfo silraid_idinfo = {
.name = "silicon_medley_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_silraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/squashfs.c b/libblkid/src/superblocks/squashfs.c
index 92ab77a..8246583 100644
--- a/libblkid/src/superblocks/squashfs.c
+++ b/libblkid/src/superblocks/squashfs.c
@@ -40,7 +40,7 @@ struct sqsh_super_block {
static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct sqsh_super_block *sq;
+ const struct sqsh_super_block *sq;
uint16_t vermaj;
uint16_t vermin;
@@ -63,10 +63,10 @@ static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag)
static int probe_squashfs3(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct sqsh_super_block *sq;
+ const struct sqsh_super_block *sq;
uint16_t vermaj;
uint16_t vermin;
- enum BLKID_ENDIANNESS endianness;
+ enum blkid_endianness endianness;
sq = blkid_probe_get_sb(pr, mag, struct sqsh_super_block);
if (!sq)
diff --git a/libblkid/src/superblocks/stratis.c b/libblkid/src/superblocks/stratis.c
index fe4a452..2651107 100644
--- a/libblkid/src/superblocks/stratis.c
+++ b/libblkid/src/superblocks/stratis.c
@@ -22,7 +22,7 @@
/* Macro to avoid error in struct declaration. */
#define STRATIS_UUID_LEN 32
/* Contains 4 hyphens and trailing null byte. */
-const int STRATIS_UUID_STR_LEN = 37;
+#define STRATIS_UUID_STR_LEN 37
struct stratis_sb {
uint32_t crc32;
@@ -49,7 +49,7 @@ const char STRATIS_MAGIC[] = "!Stra0tis\x86\xff\x02^\x41rh";
#define MAGIC_OFFSET_COPY_1 (FIRST_COPY_OFFSET + _MAGIC_OFFSET)
#define MAGIC_OFFSET_COPY_2 (SECOND_COPY_OFFSET + _MAGIC_OFFSET)
-static int stratis_valid_sb(uint8_t *p)
+static int stratis_valid_sb(const uint8_t *p)
{
const struct stratis_sb *stratis = (const struct stratis_sb *)p;
uint32_t crc = 0;
@@ -83,7 +83,7 @@ static int probe_stratis(blkid_probe pr,
const struct blkid_idmag *mag __attribute__((__unused__)))
{
const struct stratis_sb *stratis = NULL;
- uint8_t *buf = blkid_probe_get_buffer(pr, 0, SB_AREA_SIZE);
+ const uint8_t *buf = blkid_probe_get_buffer(pr, 0, SB_AREA_SIZE);
unsigned char uuid[STRATIS_UUID_STR_LEN];
if (!buf)
diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c
index 96bc0ef..dd1e6dc 100644
--- a/libblkid/src/superblocks/superblocks.c
+++ b/libblkid/src/superblocks/superblocks.c
@@ -94,11 +94,6 @@ static int blkid_probe_set_usage(blkid_probe pr, int usage);
*/
static const struct blkid_idinfo *idinfos[] =
{
- /* In case the volume is locked with OPAL we are going to get
- * an I/O error when reading past the LUKS header, so try it
- * first. */
- &luks_idinfo,
-
/* RAIDs */
&linuxraid_idinfo,
&ddfraid_idinfo,
@@ -124,6 +119,7 @@ static const struct blkid_idinfo *idinfos[] =
&snapcow_idinfo,
&verity_hash_idinfo,
&integrity_idinfo,
+ &luks_idinfo,
&vmfs_volume_idinfo,
&ubi_idinfo,
&vdo_idinfo,
@@ -423,6 +419,7 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
DBG(LOWPROBE, ul_debug("\tcall probefunc()"));
errno = 0;
rc = id->probefunc(pr, mag);
+ blkid_probe_prune_buffers(pr);
if (rc != BLKID_PROBE_OK) {
blkid_probe_chain_reset_values(pr, chn);
if (rc < 0)
@@ -629,7 +626,7 @@ int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size)
block_size);
}
-int blkid_probe_set_fsendianness(blkid_probe pr, enum BLKID_ENDIANNESS endianness)
+int blkid_probe_set_fsendianness(blkid_probe pr, enum blkid_endianness endianness)
{
struct blkid_chain *chn = blkid_probe_get_chain(pr);
const char *value;
diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h
index a990058..dc669e0 100644
--- a/libblkid/src/superblocks/superblocks.h
+++ b/libblkid/src/superblocks/superblocks.h
@@ -9,7 +9,7 @@
#include "blkidP.h"
-enum BLKID_ENDIANNESS {
+enum blkid_endianness {
BLKID_ENDIANNESS_LITTLE,
BLKID_ENDIANNESS_BIG,
};
@@ -128,9 +128,21 @@ int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size);
int blkid_probe_set_fssize(blkid_probe pr, uint64_t size);
int blkid_probe_set_fslastblock(blkid_probe pr, uint64_t lastblock);
int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size);
-int blkid_probe_set_fsendianness(blkid_probe pr, enum BLKID_ENDIANNESS endianness);
+int blkid_probe_set_fsendianness(blkid_probe pr, enum blkid_endianness endianness);
extern int blkid_probe_is_bitlocker(blkid_probe pr);
extern int blkid_probe_is_ntfs(blkid_probe pr);
+/*
+ * utility functions
+ */
+static inline int blkid32_to_cpu(enum blkid_endianness e, uint32_t i)
+{
+ if (e == BLKID_ENDIANNESS_LITTLE)
+ return le32_to_cpu(i);
+ else if (e == BLKID_ENDIANNESS_BIG)
+ return be32_to_cpu(i);
+ abort();
+}
+
#endif /* _BLKID_SUPERBLOCKS_H */
diff --git a/libblkid/src/superblocks/swap.c b/libblkid/src/superblocks/swap.c
index 67224bc..4876905 100644
--- a/libblkid/src/superblocks/swap.c
+++ b/libblkid/src/superblocks/swap.c
@@ -40,7 +40,7 @@ static void swap_set_info_swap1(blkid_probe pr,
const struct blkid_idmag *mag,
const struct swap_header_v1_2 *hdr)
{
- enum BLKID_ENDIANNESS endianness = le32_to_cpu(hdr->version) == 1 ?
+ enum blkid_endianness endianness = le32_to_cpu(hdr->version) == 1 ?
BLKID_ENDIANNESS_LITTLE : BLKID_ENDIANNESS_BIG;
blkid_probe_set_fsendianness(pr, endianness);
@@ -91,7 +91,7 @@ static int swap_set_info(blkid_probe pr, const struct blkid_idmag *mag,
static int probe_swap(blkid_probe pr, const struct blkid_idmag *mag)
{
- unsigned char *buf;
+ const unsigned char *buf;
if (!mag)
return 1;
diff --git a/libblkid/src/superblocks/sysv.c b/libblkid/src/superblocks/sysv.c
index 421660e..a9085c4 100644
--- a/libblkid/src/superblocks/sysv.c
+++ b/libblkid/src/superblocks/sysv.c
@@ -76,7 +76,7 @@ struct sysv_super_block
static int probe_xenix(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct xenix_super_block *sb;
+ const struct xenix_super_block *sb;
sb = blkid_probe_get_sb(pr, mag, struct xenix_super_block);
if (!sb)
diff --git a/libblkid/src/superblocks/ubi.c b/libblkid/src/superblocks/ubi.c
index fbb7c5e..b15199b 100644
--- a/libblkid/src/superblocks/ubi.c
+++ b/libblkid/src/superblocks/ubi.c
@@ -35,7 +35,7 @@ static int ubi_verify_csum(blkid_probe pr, const struct ubi_ec_hdr *hdr)
static int probe_ubi(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct ubi_ec_hdr *hdr;
+ const struct ubi_ec_hdr *hdr;
hdr = blkid_probe_get_sb(pr, mag, struct ubi_ec_hdr);
if (!hdr)
diff --git a/libblkid/src/superblocks/ubifs.c b/libblkid/src/superblocks/ubifs.c
index 8dece28..c9733a9 100644
--- a/libblkid/src/superblocks/ubifs.c
+++ b/libblkid/src/superblocks/ubifs.c
@@ -105,7 +105,7 @@ static int ubifs_verify_csum(blkid_probe pr, const struct ubifs_sb_node *sb)
static int probe_ubifs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct ubifs_sb_node *sb;
+ const struct ubifs_sb_node *sb;
sb = blkid_probe_get_sb(pr, mag, struct ubifs_sb_node);
if (!sb)
diff --git a/libblkid/src/superblocks/udf.c b/libblkid/src/superblocks/udf.c
index 36adf60..76d4236 100644
--- a/libblkid/src/superblocks/udf.c
+++ b/libblkid/src/superblocks/udf.c
@@ -233,6 +233,7 @@ static int probe_udf(blkid_probe pr,
size_t i;
uint32_t vsd_len;
uint16_t udf_rev = 0;
+ int is_udf = 0;
int vsd_2048_valid = -1;
int have_label = 0;
int have_uuid = 0;
@@ -343,6 +344,8 @@ anchor:
return 1;
real_blksz:
+ /* At this stage we detected ISO/IEC 13346 or ECMA-167 filesystem recognition sequence, it does not have to be UDF */
+
/* Use the actual block size from here on out */
bs = pbs[i];
@@ -454,11 +457,17 @@ real_blksz:
lvid_loc = le32_to_cpu(vd->type.logical.lvid_location);
}
}
- if (!udf_rev) {
- /* UDF-2.60: 2.1.5.3: UDF revision field shall indicate revision of UDF document
- * We use maximal value from this field and from LVIDIU fields for ID_FS_VERSION */
- if (strncmp(vd->type.logical.domain_id, "*OSTA UDF Compliant", sizeof(vd->type.logical.domain_id)) == 0)
- udf_rev = le16_to_cpu(vd->type.logical.udf_rev);
+ if (!is_udf || !udf_rev) {
+ /* UDF-2.60: 2.2.4.3: This field shall indicate that the contents of
+ * this logical volume conforms to the domain defined in this document.
+ * This distinguish UDF from all other ISO/IEC 13346 and ECMA-167 filesystems. */
+ if (strncmp(vd->type.logical.domain_id, "*OSTA UDF Compliant", sizeof(vd->type.logical.domain_id)) == 0) {
+ is_udf = 1;
+ /* UDF-2.60: 2.1.5.3: UDF revision field shall indicate revision of UDF document
+ * We use maximal value from this field and from LVIDIU fields for ID_FS_VERSION */
+ if (!udf_rev)
+ udf_rev = le16_to_cpu(vd->type.logical.udf_rev);
+ }
}
if ((!have_logvolid || !have_label) && is_charset_udf(vd->type.logical.desc_charset)) {
/* LogicalVolumeIdentifier in UDF 2.01 specification:
@@ -520,10 +529,15 @@ real_blksz:
vd->type.imp_use_volume.lvinfo1.c, clen, enc);
}
}
- if (have_volid && have_uuid && have_volsetid && have_logvolid && have_label && lvid_len && lvid_loc && have_applicationid && have_publisherid)
+ if (is_udf && have_volid && have_uuid && have_volsetid && have_logvolid && have_label && lvid_len && lvid_loc && have_applicationid && have_publisherid)
break;
}
+ if (!is_udf) {
+ /* We detected some other ISO/IEC 13346 or ECMA-167 filesystem, not UDF */
+ return 1;
+ }
+
/* Pick the first logical volume integrity descriptor and read UDF revision */
if (lvid_loc && lvid_len >= sizeof(*vd)) {
vd = (struct volume_descriptor *)
@@ -584,6 +598,7 @@ const struct blkid_idinfo udf_idinfo =
.flags = BLKID_IDINFO_TOLERANT,
.magics =
{
+ /* These magics are generic to all ISO/IEC 13346 and ECMA-167 filesystems, not just UDF */
{ .magic = "BEA01", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" },
{ .magic = "BOOT2", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" },
{ .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1, .hoff = "session_offset" },
diff --git a/libblkid/src/superblocks/vdo.c b/libblkid/src/superblocks/vdo.c
index bec686f..4e9f445 100644
--- a/libblkid/src/superblocks/vdo.c
+++ b/libblkid/src/superblocks/vdo.c
@@ -25,7 +25,7 @@ struct vdo_super_block {
static int probe_vdo(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct vdo_super_block *vsb;
+ const struct vdo_super_block *vsb;
vsb = blkid_probe_get_sb(pr, mag, struct vdo_super_block);
if (!vsb)
diff --git a/libblkid/src/superblocks/vfat.c b/libblkid/src/superblocks/vfat.c
index 6b4a3ad..5644d89 100644
--- a/libblkid/src/superblocks/vfat.c
+++ b/libblkid/src/superblocks/vfat.c
@@ -183,8 +183,8 @@ static int search_fat_label(blkid_probe pr, uint64_t offset, uint32_t entries, u
static int fat_valid_superblock(blkid_probe pr,
const struct blkid_idmag *mag,
- struct msdos_super_block *ms,
- struct vfat_super_block *vs,
+ const struct msdos_super_block *ms,
+ const struct vfat_super_block *vs,
uint32_t *cluster_count, uint32_t *fat_size,
uint32_t *sect_count)
{
@@ -276,8 +276,8 @@ extern int blkid_probe_is_vfat(blkid_probe pr);
*/
int blkid_probe_is_vfat(blkid_probe pr)
{
- struct vfat_super_block *vs;
- struct msdos_super_block *ms;
+ const struct vfat_super_block *vs;
+ const struct msdos_super_block *ms;
const struct blkid_idmag *mag = NULL;
int rc;
@@ -301,11 +301,12 @@ int blkid_probe_is_vfat(blkid_probe pr)
* Sievers's volume_id library */
static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct vfat_super_block *vs;
- struct msdos_super_block *ms;
+ const struct vfat_super_block *vs;
+ const struct msdos_super_block *ms;
const unsigned char *vol_label = NULL;
const unsigned char *boot_label = NULL;
- unsigned char *vol_serno = NULL, vol_label_buf[11];
+ const unsigned char *vol_serno = NULL;
+ unsigned char vol_label_buf[11];
uint16_t sector_size = 0, reserved;
uint32_t cluster_count, fat_size, sect_count;
const char *version = NULL;
@@ -348,7 +349,7 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
version = "FAT16";
} else if (vs->vs_fat32_length) {
- unsigned char *buf;
+ const unsigned char *buf;
uint16_t fsinfo_sect;
int maxloop = 100;
diff --git a/libblkid/src/superblocks/via_raid.c b/libblkid/src/superblocks/via_raid.c
index ee3ab65..16e7fc2 100644
--- a/libblkid/src/superblocks/via_raid.c
+++ b/libblkid/src/superblocks/via_raid.c
@@ -51,8 +51,6 @@ static int probe_viaraid(blkid_probe pr,
uint64_t off;
struct via_metadata *v;
- if (pr->size < 0x10000)
- return 1;
if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
return 1;
@@ -84,6 +82,7 @@ static int probe_viaraid(blkid_probe pr,
const struct blkid_idinfo viaraid_idinfo = {
.name = "via_raid_member",
.usage = BLKID_USAGE_RAID,
+ .minsz = 0x10000,
.probefunc = probe_viaraid,
.magics = BLKID_NONE_MAGIC
};
diff --git a/libblkid/src/superblocks/vmfs.c b/libblkid/src/superblocks/vmfs.c
index fac87ab..3017768 100644
--- a/libblkid/src/superblocks/vmfs.c
+++ b/libblkid/src/superblocks/vmfs.c
@@ -24,7 +24,7 @@ struct vmfs_volume_info {
static int probe_vmfs_fs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct vmfs_fs_info *header;
+ const struct vmfs_fs_info *header;
header = blkid_probe_get_sb(pr, mag, struct vmfs_fs_info);
if (header == NULL)
@@ -48,8 +48,8 @@ static int probe_vmfs_fs(blkid_probe pr, const struct blkid_idmag *mag)
static int probe_vmfs_volume(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct vmfs_volume_info *header;
- unsigned char *lvm_uuid;
+ const struct vmfs_volume_info *header;
+ const unsigned char *lvm_uuid;
header = blkid_probe_get_sb(pr, mag, struct vmfs_volume_info);
if (header == NULL)
diff --git a/libblkid/src/superblocks/vxfs.c b/libblkid/src/superblocks/vxfs.c
index be66831..c933861 100644
--- a/libblkid/src/superblocks/vxfs.c
+++ b/libblkid/src/superblocks/vxfs.c
@@ -25,23 +25,19 @@ struct vxfs_super_block {
static int probe_vxfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct vxfs_super_block *vxs;
+ const struct vxfs_super_block *vxs;
+ enum blkid_endianness e = mag->hint;
vxs = blkid_probe_get_sb(pr, mag, struct vxfs_super_block);
if (!vxs)
return errno ? -errno : 1;
- if (le32_to_cpu(vxs->vs_magic) == 0xa501fcf5) {
- blkid_probe_sprintf_version(pr, "%u", (unsigned int)le32_to_cpu(vxs->vs_version));
- blkid_probe_set_fsblocksize(pr, le32_to_cpu(vxs->vs_bsize));
- blkid_probe_set_block_size(pr, le32_to_cpu(vxs->vs_bsize));
- blkid_probe_set_fsendianness(pr, BLKID_ENDIANNESS_LITTLE);
- } else if (be32_to_cpu(vxs->vs_magic) == 0xa501fcf5) {
- blkid_probe_sprintf_version(pr, "%u", (unsigned int)be32_to_cpu(vxs->vs_version));
- blkid_probe_set_fsblocksize(pr, be32_to_cpu(vxs->vs_bsize));
- blkid_probe_set_block_size(pr, be32_to_cpu(vxs->vs_bsize));
- blkid_probe_set_fsendianness(pr, BLKID_ENDIANNESS_BIG);
- }
+ blkid_probe_sprintf_version(pr, "%d",
+ (unsigned int)blkid32_to_cpu(e, vxs->vs_version));
+ blkid_probe_set_fsblocksize(pr, blkid32_to_cpu(e, vxs->vs_bsize));
+ blkid_probe_set_block_size(pr, blkid32_to_cpu(e, vxs->vs_bsize));
+ blkid_probe_set_fsendianness(pr, e);
+
return 0;
}
@@ -53,8 +49,10 @@ const struct blkid_idinfo vxfs_idinfo =
.probefunc = probe_vxfs,
.magics =
{
- { .magic = "\365\374\001\245", .len = 4, .kboff = 1 },
- { .magic = "\245\001\374\365", .len = 4, .kboff = 8 },
+ { .magic = "\xf5\xfc\x01\xa5", .len = 4, .kboff = 1,
+ .hint = BLKID_ENDIANNESS_LITTLE },
+ { .magic = "\xa5\x01\xfc\xf5", .len = 4, .kboff = 8,
+ .hint = BLKID_ENDIANNESS_BIG },
{ NULL }
}
};
diff --git a/libblkid/src/superblocks/xfs.c b/libblkid/src/superblocks/xfs.c
index f0e099e..0c35982 100644
--- a/libblkid/src/superblocks/xfs.c
+++ b/libblkid/src/superblocks/xfs.c
@@ -111,7 +111,7 @@ struct xfs_super_block {
#define XFS_SB_VERSION2_CRCBIT 0x00000100
-static void sb_from_disk(struct xfs_super_block *from,
+static void sb_from_disk(const struct xfs_super_block *from,
struct xfs_super_block *to)
{
@@ -170,7 +170,7 @@ static void sb_from_disk(struct xfs_super_block *from,
to->sb_rrmapino = be64_to_cpu(from->sb_rrmapino);
}
-static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr,
+static int xfs_verify_sb(const struct xfs_super_block *ondisk, blkid_probe pr,
const struct blkid_idmag *mag)
{
struct xfs_super_block sb, *sbp = &sb;
@@ -206,7 +206,7 @@ static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr,
if ((sbp->sb_versionnum & 0x0f) == 5) {
uint32_t expected, crc;
- unsigned char *csummed;
+ const unsigned char *csummed;
if (!(sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT))
return 0;
@@ -230,7 +230,7 @@ static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr,
return 1;
}
-static uint64_t xfs_fssize(struct xfs_super_block *xs)
+static uint64_t xfs_fssize(const struct xfs_super_block *xs)
{
uint32_t lsize = xs->sb_logstart ? xs->sb_logblocks : 0;
uint64_t avail_blocks = be64_to_cpu(xs->sb_dblocks) - be32_to_cpu(lsize);
@@ -241,7 +241,7 @@ static uint64_t xfs_fssize(struct xfs_super_block *xs)
static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct xfs_super_block *xs;
+ const struct xfs_super_block *xs;
xs = blkid_probe_get_sb(pr, mag, struct xfs_super_block);
if (!xs)
@@ -331,7 +331,7 @@ static int probe_xfs_log(blkid_probe pr,
{
int i;
struct xlog_rec_header *rhead;
- unsigned char *buf;
+ const unsigned char *buf;
buf = blkid_probe_get_buffer(pr, 0, 256*1024);
if (!buf)
diff --git a/libblkid/src/superblocks/zfs.c b/libblkid/src/superblocks/zfs.c
index 1fcc384..008a200 100644
--- a/libblkid/src/superblocks/zfs.c
+++ b/libblkid/src/superblocks/zfs.c
@@ -71,13 +71,13 @@ struct nvlist {
struct nvpair nvl_nvpair;
};
-static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
- void *value, size_t max_value_size, unsigned directory_level)
+static void zfs_process_value(blkid_probe pr, const char *name, size_t namelen,
+ const void *value, size_t max_value_size, unsigned directory_level)
{
if (strncmp(name, "name", namelen) == 0 &&
sizeof(struct nvstring) <= max_value_size &&
!directory_level) {
- struct nvstring *nvs = value;
+ const struct nvstring *nvs = value;
uint32_t nvs_type = be32_to_cpu(nvs->nvs_type);
uint32_t nvs_strlen = be32_to_cpu(nvs->nvs_strlen);
@@ -92,7 +92,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
} else if (strncmp(name, "guid", namelen) == 0 &&
sizeof(struct nvuint64) <= max_value_size &&
!directory_level) {
- struct nvuint64 *nvu = value;
+ const struct nvuint64 *nvu = value;
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
uint64_t nvu_value;
@@ -110,7 +110,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
} else if (strncmp(name, "pool_guid", namelen) == 0 &&
sizeof(struct nvuint64) <= max_value_size &&
!directory_level) {
- struct nvuint64 *nvu = value;
+ const struct nvuint64 *nvu = value;
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
uint64_t nvu_value;
@@ -128,7 +128,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
"%"PRIu64, nvu_value);
} else if (strncmp(name, "ashift", namelen) == 0 &&
sizeof(struct nvuint64) <= max_value_size) {
- struct nvuint64 *nvu = value;
+ const struct nvuint64 *nvu = value;
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
uint64_t nvu_value;
@@ -147,9 +147,9 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
{
- unsigned char *p;
- struct nvlist *nvl;
- struct nvpair *nvp;
+ const unsigned char *p;
+ const struct nvlist *nvl;
+ const struct nvpair *nvp;
size_t left = 4096;
unsigned directory_level = 0;
@@ -166,16 +166,16 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
DBG(LOWPROBE, ul_debug("zfs_extract: nvlist offset %jd",
(intmax_t)offset));
- nvl = (struct nvlist *) p;
+ nvl = (const struct nvlist *) p;
nvp = &nvl->nvl_nvpair;
- left -= (unsigned char *)nvp - p; /* Already used up 12 bytes */
+ left -= (const unsigned char *)nvp - p; /* Already used up 12 bytes */
while (left > sizeof(*nvp)) {
uint32_t nvp_size = be32_to_cpu(nvp->nvp_size);
uint32_t nvp_namelen = be32_to_cpu(nvp->nvp_namelen);
uint64_t namesize = ((uint64_t)nvp_namelen + 3) & ~3;
size_t max_value_size;
- void *value;
+ const void *value;
if (!nvp->nvp_size) {
if (!directory_level)
@@ -201,7 +201,7 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
value = nvp->nvp_name + namesize;
if (sizeof(struct nvdirectory) <= max_value_size) {
- struct nvdirectory *nvu = value;
+ const struct nvdirectory *nvu = value;
if (be32_to_cpu(nvu->nvd_type) == DATA_TYPE_DIRECTORY) {
nvp_size = sizeof(*nvp) + namesize + sizeof(*nvu);
directory_level++;
@@ -259,7 +259,7 @@ static int probe_zfs(blkid_probe pr,
struct zfs_uberblock *ub = NULL;
loff_t offset = 0, ub_offset = 0;
int label_no, found = 0, found_in_label;
- void *label;
+ const void *label;
loff_t blk_align = (pr->size % (256 * 1024ULL));
DBG(PROBE, ul_debug("probe_zfs"));
diff --git a/libblkid/src/superblocks/zonefs.c b/libblkid/src/superblocks/zonefs.c
index 8aa45b0..e8fcab3 100644
--- a/libblkid/src/superblocks/zonefs.c
+++ b/libblkid/src/superblocks/zonefs.c
@@ -54,7 +54,7 @@ static int zonefs_verify_csum(blkid_probe pr, const struct zonefs_super *sb)
uint32_t expected = le32_to_cpu(sb->s_crc);
uint32_t crc = ul_crc32_exclude_offset(
~0LL, (unsigned char *) sb, sizeof(*sb),
- offsetof(typeof(*sb), s_crc), sizeof(sb->s_crc));
+ offsetof(__typeof__(*sb), s_crc), sizeof(sb->s_crc));
return blkid_probe_verify_csum(pr, crc, expected);
}
diff --git a/libblkid/src/topology/sysfs.c b/libblkid/src/topology/sysfs.c
index 25debd0..d216cfc 100644
--- a/libblkid/src/topology/sysfs.c
+++ b/libblkid/src/topology/sysfs.c
@@ -26,7 +26,7 @@
static const struct topology_val {
/* /sys/dev/block/<maj>:<min>/<ATTR> */
- const char *attr;
+ const char * const attr;
/* functions to set probing result */
int (*set_ulong)(blkid_probe, unsigned long);
diff --git a/libblkid/src/topology/topology.c b/libblkid/src/topology/topology.c
index 67df3e3..f19a4f2 100644
--- a/libblkid/src/topology/topology.c
+++ b/libblkid/src/topology/topology.c
@@ -146,6 +146,7 @@ blkid_topology blkid_probe_get_topology(blkid_probe pr)
static int topology_probe(blkid_probe pr, struct blkid_chain *chn)
{
size_t i;
+ int rc;
if (chn->idx < -1)
return -1;
@@ -182,9 +183,10 @@ static int topology_probe(blkid_probe pr, struct blkid_chain *chn)
if (id->probefunc) {
DBG(LOWPROBE, ul_debug("%s: call probefunc()", id->name));
-
errno = 0;
- if (id->probefunc(pr, NULL) != 0)
+ rc = id->probefunc(pr, NULL);
+ blkid_probe_prune_buffers(pr);
+ if (rc != 0)
continue;
}