From 8bb05ac73a5b448b339ce0bc8d396c82c459b47f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 21:33:32 +0200 Subject: Merging upstream version 2.40. Signed-off-by: Daniel Baumann --- libblkid/docs/Makefile.in | 14 +- libblkid/docs/libblkid-sections.txt | 1 + libblkid/docs/version.xml | 2 +- libblkid/libblkid.3 | 6 +- libblkid/meson.build | 2 +- libblkid/src/Makemodule.am | 3 + libblkid/src/blkid.h.in | 2 + libblkid/src/blkidP.h | 16 ++- libblkid/src/config.c | 107 ++++++++++++++- libblkid/src/dev.c | 6 +- libblkid/src/libblkid.sym | 4 + libblkid/src/partitions/bsd.c | 2 +- libblkid/src/partitions/dos.c | 14 +- libblkid/src/partitions/gpt.c | 6 +- libblkid/src/partitions/mac.c | 2 +- libblkid/src/partitions/minix.c | 4 +- libblkid/src/partitions/partitions.c | 5 +- libblkid/src/partitions/ultrix.c | 6 +- libblkid/src/probe.c | 213 ++++++++++++++++++++++++++---- libblkid/src/superblocks/adaptec_raid.c | 4 +- libblkid/src/superblocks/apfs.c | 2 +- libblkid/src/superblocks/bcache.c | 48 +++++-- libblkid/src/superblocks/befs.c | 6 +- libblkid/src/superblocks/bluestore.c | 2 +- libblkid/src/superblocks/btrfs.c | 2 +- libblkid/src/superblocks/cramfs.c | 28 ++-- libblkid/src/superblocks/cs_fvault2.c | 2 +- libblkid/src/superblocks/ddf_raid.c | 6 +- libblkid/src/superblocks/drbd.c | 147 +++++++++++---------- libblkid/src/superblocks/erofs.c | 4 +- libblkid/src/superblocks/exfat.c | 8 +- libblkid/src/superblocks/exfs.c | 6 +- libblkid/src/superblocks/f2fs.c | 6 +- libblkid/src/superblocks/gfs.c | 4 +- libblkid/src/superblocks/hfs.c | 38 ++++-- libblkid/src/superblocks/highpoint_raid.c | 3 +- libblkid/src/superblocks/hpfs.c | 6 +- libblkid/src/superblocks/iso9660.c | 195 +++++++++++++++++---------- libblkid/src/superblocks/isw_raid.c | 3 +- libblkid/src/superblocks/jfs.c | 2 +- libblkid/src/superblocks/jmicron_raid.c | 3 +- libblkid/src/superblocks/linux_raid.c | 7 +- libblkid/src/superblocks/lsi_raid.c | 3 +- libblkid/src/superblocks/luks.c | 20 ++- libblkid/src/superblocks/lvm.c | 10 +- libblkid/src/superblocks/minix.c | 2 +- libblkid/src/superblocks/mpool.c | 2 +- libblkid/src/superblocks/netware.c | 2 +- libblkid/src/superblocks/ntfs.c | 6 +- libblkid/src/superblocks/nvidia_raid.c | 3 +- libblkid/src/superblocks/ocfs.c | 6 +- libblkid/src/superblocks/promise_raid.c | 3 +- libblkid/src/superblocks/reiserfs.c | 4 +- libblkid/src/superblocks/romfs.c | 4 +- libblkid/src/superblocks/silicon_raid.c | 3 +- libblkid/src/superblocks/squashfs.c | 6 +- libblkid/src/superblocks/stratis.c | 6 +- libblkid/src/superblocks/superblocks.c | 9 +- libblkid/src/superblocks/superblocks.h | 16 ++- libblkid/src/superblocks/swap.c | 4 +- libblkid/src/superblocks/sysv.c | 2 +- libblkid/src/superblocks/ubi.c | 2 +- libblkid/src/superblocks/ubifs.c | 2 +- libblkid/src/superblocks/udf.c | 27 +++- libblkid/src/superblocks/vdo.c | 2 +- libblkid/src/superblocks/vfat.c | 17 +-- libblkid/src/superblocks/via_raid.c | 3 +- libblkid/src/superblocks/vmfs.c | 6 +- libblkid/src/superblocks/vxfs.c | 26 ++-- libblkid/src/superblocks/xfs.c | 12 +- libblkid/src/superblocks/zfs.c | 28 ++-- libblkid/src/superblocks/zonefs.c | 2 +- libblkid/src/topology/sysfs.c | 2 +- libblkid/src/topology/topology.c | 6 +- 74 files changed, 794 insertions(+), 399 deletions(-) (limited to 'libblkid') diff --git a/libblkid/docs/Makefile.in b/libblkid/docs/Makefile.in index f0007f2..ddb5709 100644 --- a/libblkid/docs/Makefile.in +++ b/libblkid/docs/Makefile.in @@ -117,7 +117,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_vscript.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/tls.m4 \ - $(top_srcdir)/m4/ul.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ul.m4 $(top_srcdir)/m4/year2038.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -159,10 +160,12 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BISON = @BISON@ BSD_WARN_CFLAGS = @BSD_WARN_CFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPTSETUP_CFLAGS = @CRYPTSETUP_CFLAGS@ @@ -192,6 +195,7 @@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ +FLEX = @FLEX@ FUZZING_ENGINE_LDFLAGS = @FUZZING_ENGINE_LDFLAGS@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GMSGFMT = @GMSGFMT@ @@ -219,6 +223,8 @@ LIBFDISK_VERSION = @LIBFDISK_VERSION@ LIBFDISK_VERSION_INFO = @LIBFDISK_VERSION_INFO@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ +LIBLASTLOG2_VERSION = @LIBLASTLOG2_VERSION@ +LIBLASTLOG2_VERSION_INFO = @LIBLASTLOG2_VERSION_INFO@ LIBMOUNT_MAJOR_VERSION = @LIBMOUNT_MAJOR_VERSION@ LIBMOUNT_MINOR_VERSION = @LIBMOUNT_MINOR_VERSION@ LIBMOUNT_PATCH_VERSION = @LIBMOUNT_PATCH_VERSION@ @@ -244,6 +250,7 @@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ +MQ_LIBS = @MQ_LIBS@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -257,7 +264,6 @@ NCURSES_CFLAGS = @NCURSES_CFLAGS@ NCURSES_LIBS = @NCURSES_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ -NO_UNUSED_WARN_CFLAGS = @NO_UNUSED_WARN_CFLAGS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ @@ -297,6 +303,8 @@ SHELL = @SHELL@ SOCKET_LIBS = @SOCKET_LIBS@ SOLIB_CFLAGS = @SOLIB_CFLAGS@ SOLIB_LDFLAGS = @SOLIB_LDFLAGS@ +SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ +SQLITE3_LIBS = @SQLITE3_LIBS@ STRIP = @STRIP@ SUID_CFLAGS = @SUID_CFLAGS@ SUID_LDFLAGS = @SUID_LDFLAGS@ @@ -382,6 +390,7 @@ sysconfdir = @sysconfdir@ sysconfstaticdir = @sysconfstaticdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ +tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @@ -391,6 +400,7 @@ usrsbin_execdir = @usrsbin_execdir@ vendordir = @vendordir@ with_bashcompletiondir = @with_bashcompletiondir@ with_systemdsystemunitdir = @with_systemdsystemunitdir@ +with_tmpfilesdir = @with_tmpfilesdir@ # We require automake 1.10 at least. AUTOMAKE_OPTIONS = 1.10 diff --git a/libblkid/docs/libblkid-sections.txt b/libblkid/docs/libblkid-sections.txt index 9297002..308f8ef 100644 --- a/libblkid/docs/libblkid-sections.txt +++ b/libblkid/docs/libblkid-sections.txt @@ -73,6 +73,7 @@ BLKID_PROBE_AMBIGUOUS lowprobe-tags blkid_do_fullprobe blkid_do_wipe +blkid_wipe_all blkid_do_probe blkid_do_safeprobe diff --git a/libblkid/docs/version.xml b/libblkid/docs/version.xml index a69af57..4bdd32f 100644 --- a/libblkid/docs/version.xml +++ b/libblkid/docs/version.xml @@ -1 +1 @@ -2.39.3 +2.40 diff --git a/libblkid/libblkid.3 b/libblkid/libblkid.3 index 42ee837..0297e27 100644 --- a/libblkid/libblkid.3 +++ b/libblkid/libblkid.3 @@ -2,12 +2,12 @@ .\" Title: libblkid .\" Author: [see the "AUTHOR(S)" section] .\" Generator: Asciidoctor 2.0.20 -.\" Date: 2023-11-21 +.\" Date: 2024-01-31 .\" Manual: Programmer's Manual -.\" Source: util-linux 2.39.3 +.\" Source: util-linux 2.40 .\" Language: English .\" -.TH "LIBBLKID" "3" "2023-11-21" "util\-linux 2.39.3" "Programmer\*(Aqs Manual" +.TH "LIBBLKID" "3" "2024-01-31" "util\-linux 2.40" "Programmer\*(Aqs Manual" .ie \n(.g .ds Aq \(aq .el .ds Aq ' .ss \n[.ss] 0 diff --git a/libblkid/meson.build b/libblkid/meson.build index 0cb134f..5a28bdf 100644 --- a/libblkid/meson.build +++ b/libblkid/meson.build @@ -140,7 +140,7 @@ lib_blkid = both_libraries( version : libblkid_version, link_args : ['-Wl,--version-script=@0@'.format(libblkid_sym_path)], link_with : lib_common, - dependencies : build_libblkid ? [] : disabler(), + dependencies : build_libblkid ? [lib_econf] : disabler(), install : build_libblkid) blkid_dep = declare_dependency(link_with: lib_blkid, include_directories: '.') 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 #include +#if defined (HAVE_LIBECONF) +#include +#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 #include #include +#include #include #ifdef HAVE_LINUX_CDROM_H #include @@ -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; } @@ -625,6 +648,39 @@ static struct blkid_bufinfo *get_cached_buffer(blkid_probe pr, uint64_t off, uin return NULL; } +/* + * 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 @@ -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) @@ -1484,6 +1601,46 @@ int blkid_do_wipe(blkid_probe pr, int dryrun) return BLKID_PROBE_OK; } +/** + * 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. + * + * + * wipe all filesystems or raids from the device + * + * fd = open(devname, O_RDWR|O_CLOEXEC); + * blkid_probe_set_device(pr, fd, 0, 0); + * + * blkid_wipe_all(pr); + * + * + * + * 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<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 - * Copyright (C) 2018 Milan Broz + * Copyright (C) 2018-2024 Milan Broz * * Inspired by libvolume_id by * Kay Sievers @@ -15,6 +15,7 @@ #include #include #include +#include #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/:/ */ - 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; } -- cgit v1.2.3