mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Extend blkid utilities for signatures wiping.
For older distributions there's fallback mode for missing blkid_do_wipe function. We erase signatures based on offsets and lengths detected by blkid.
This commit is contained in:
committed by
Milan Broz
parent
05a89e5566
commit
e8e1f844d9
12
configure.ac
12
configure.ac
@@ -438,6 +438,16 @@ if test x$enable_blkid = xyes ; then
|
||||
PKG_CHECK_MODULES([BLKID], [blkid],[AC_DEFINE([HAVE_BLKID], 1, [Define to 1 to use blkid for detection of disk signatures.])],[LIBBLKID_LIBS="-lblkid"])
|
||||
|
||||
AC_CHECK_HEADERS(blkid/blkid.h,,[AC_MSG_ERROR([You need blkid development library installed.])])
|
||||
AC_CHECK_DECL([blkid_do_wipe],
|
||||
[ AC_DEFINE([HAVE_BLKID_WIPE], 1, [Define to 1 to use blkid_do_wipe.])
|
||||
enable_blkid_wipe=yes
|
||||
],,
|
||||
[#include <blkid/blkid.h>])
|
||||
AC_CHECK_DECL([blkid_probe_step_back],
|
||||
[ AC_DEFINE([HAVE_BLKID_STEP_BACK], 1, [Define to 1 to use blkid_probe_step_back.])
|
||||
enable_blkid_step_back=yes
|
||||
],,
|
||||
[#include <blkid/blkid.h>])
|
||||
AC_CHECK_DECLS([ blkid_reset_probe,
|
||||
blkid_probe_set_device,
|
||||
blkid_probe_filter_superblocks_type,
|
||||
@@ -449,6 +459,8 @@ if test x$enable_blkid = xyes ; then
|
||||
[#include <blkid/blkid.h>])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_BLKID, test x$enable_blkid = xyes)
|
||||
AM_CONDITIONAL(HAVE_BLKID_WIPE, test x$enable_blkid_wipe = xyes)
|
||||
AM_CONDITIONAL(HAVE_BLKID_STEP_BACK, test x$enable_blkid_step_back = xyes)
|
||||
|
||||
dnl Magic for cryptsetup.static build.
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
|
||||
@@ -25,14 +25,52 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "utils_blkid.h"
|
||||
#include "utils_io.h"
|
||||
|
||||
#ifdef HAVE_BLKID
|
||||
#include <blkid/blkid.h>
|
||||
/* make bad checksums flag optional */
|
||||
#ifndef BLKID_SUBLKS_BADCSUM
|
||||
#define BLKID_SUBLKS_BADCSUM 0
|
||||
#endif
|
||||
struct blkid_handle {
|
||||
int fd;
|
||||
blkid_probe pr;
|
||||
};
|
||||
#ifndef HAVE_BLKID_WIPE
|
||||
static size_t crypt_getpagesize(void)
|
||||
{
|
||||
long r = sysconf(_SC_PAGESIZE);
|
||||
return r <= 0 ? 4096 : (size_t)r;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void blk_set_chains_for_wipes(struct blkid_handle *h)
|
||||
{
|
||||
#ifdef HAVE_BLKID
|
||||
blkid_probe_enable_partitions(h->pr, 1);
|
||||
blkid_probe_set_partitions_flags(h->pr, 0
|
||||
#ifdef HAVE_BLKID_WIPE
|
||||
| BLKID_PARTS_MAGIC
|
||||
#endif
|
||||
);
|
||||
|
||||
blkid_probe_enable_superblocks(h->pr, 1);
|
||||
blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_LABEL |
|
||||
BLKID_SUBLKS_UUID |
|
||||
BLKID_SUBLKS_TYPE |
|
||||
BLKID_SUBLKS_USAGE |
|
||||
BLKID_SUBLKS_VERSION |
|
||||
BLKID_SUBLKS_MAGIC |
|
||||
BLKID_SUBLKS_BADCSUM);
|
||||
#endif
|
||||
}
|
||||
|
||||
void blk_set_chains_for_full_print(struct blkid_handle *h)
|
||||
{
|
||||
blk_set_chains_for_wipes(h);
|
||||
}
|
||||
|
||||
void blk_set_chains_for_fast_detection(struct blkid_handle *h)
|
||||
{
|
||||
@@ -68,6 +106,35 @@ int blk_init_by_path(struct blkid_handle **h, const char *path)
|
||||
return r;
|
||||
}
|
||||
|
||||
int blk_init_by_fd(struct blkid_handle **h, int fd)
|
||||
{
|
||||
int r = -ENOTSUP;
|
||||
#ifdef HAVE_BLKID
|
||||
struct blkid_handle *tmp = malloc(sizeof(*h));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
tmp->pr = blkid_new_probe();
|
||||
if (!tmp->pr) {
|
||||
free(tmp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (blkid_probe_set_device(tmp->pr, fd, 0, 0)) {
|
||||
blkid_free_probe(tmp->pr);
|
||||
free(tmp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp->fd = fd;
|
||||
|
||||
*h = tmp;
|
||||
|
||||
r = 0;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
int blk_superblocks_filter_luks(struct blkid_handle *h)
|
||||
{
|
||||
int r = -ENOTSUP;
|
||||
@@ -81,6 +148,20 @@ int blk_superblocks_filter_luks(struct blkid_handle *h)
|
||||
return r;
|
||||
}
|
||||
|
||||
blk_probe_status blk_probe(struct blkid_handle *h)
|
||||
{
|
||||
blk_probe_status pr = PRB_FAIL;
|
||||
#ifdef HAVE_BLKID
|
||||
int r = blkid_do_probe(h->pr);
|
||||
|
||||
if (r == 0)
|
||||
pr = PRB_OK;
|
||||
else if (r == 1)
|
||||
pr = PRB_EMPTY;
|
||||
#endif
|
||||
return pr;
|
||||
}
|
||||
|
||||
blk_probe_status blk_safeprobe(struct blkid_handle *h)
|
||||
{
|
||||
int r = -1;
|
||||
@@ -148,6 +229,75 @@ void blk_free(struct blkid_handle *h)
|
||||
#endif
|
||||
}
|
||||
|
||||
int blk_step_back(struct blkid_handle *h)
|
||||
{
|
||||
#ifdef HAVE_BLKID
|
||||
#ifdef HAVE_BLKID_STEP_BACK
|
||||
return blkid_probe_step_back(h->pr);
|
||||
#else
|
||||
blkid_reset_probe(h->pr);
|
||||
blkid_probe_set_device(h->pr, h->fd, 0, 0);
|
||||
return 0;
|
||||
#endif
|
||||
#else /* HAVE_BLKID */
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
int blk_do_wipe(struct blkid_handle *h)
|
||||
{
|
||||
#ifdef HAVE_BLKID
|
||||
#ifdef HAVE_BLKID_WIPE
|
||||
return blkid_do_wipe(h->pr, 0);
|
||||
#else
|
||||
const char *offset;
|
||||
off_t offset_val;
|
||||
void *buf;
|
||||
ssize_t ret;
|
||||
size_t alignment, len, bsize = blkid_probe_get_sectorsize(h->pr);
|
||||
|
||||
if (h->fd < 0 || !bsize)
|
||||
return -EINVAL;
|
||||
|
||||
if (blk_is_partition(h)) {
|
||||
if (blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
|
||||
return -EINVAL;
|
||||
if (blkid_probe_lookup_value(h->pr, "PTMAGIC", NULL, &len))
|
||||
return -EINVAL;
|
||||
} else if (blk_is_superblock(h)) {
|
||||
if (blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
|
||||
return -EINVAL;
|
||||
if (blkid_probe_lookup_value(h->pr, "SBMAGIC", NULL, &len))
|
||||
return -EINVAL;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
alignment = crypt_getpagesize();
|
||||
|
||||
if (posix_memalign(&buf, alignment, len))
|
||||
return -EINVAL;
|
||||
memset(buf, 0, len);
|
||||
|
||||
offset_val = strtoll(offset, NULL, 10);
|
||||
|
||||
/* TODO: missing crypt_wipe_fd() */
|
||||
ret = write_lseek_blockwise(h->fd, bsize, alignment, buf, len, offset_val);
|
||||
free(buf);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
|
||||
if ((size_t)ret == len) {
|
||||
blk_step_back(h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
#endif
|
||||
#else /* HAVE_BLKID */
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
int blk_supported(void)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
@@ -29,12 +29,26 @@ int blk_init_by_path(struct blkid_handle **h, const char *path);
|
||||
|
||||
void blk_free(struct blkid_handle *h);
|
||||
|
||||
/*
|
||||
* WARNING: This will reset file description offset as if
|
||||
* lseek(devfd, 0, SEEK_SET) was called!
|
||||
*/
|
||||
int blk_init_by_fd(struct blkid_handle **h, int fd);
|
||||
|
||||
void blk_free(struct blkid_handle *h);
|
||||
|
||||
void blk_set_chains_for_wipes(struct blkid_handle *h);
|
||||
|
||||
void blk_set_chains_for_full_print(struct blkid_handle *h);
|
||||
|
||||
void blk_set_chains_for_fast_detection(struct blkid_handle *h);
|
||||
|
||||
int blk_superblocks_filter_luks(struct blkid_handle *h);
|
||||
|
||||
blk_probe_status blk_safeprobe(struct blkid_handle *h);
|
||||
|
||||
blk_probe_status blk_probe(struct blkid_handle *h);
|
||||
|
||||
int blk_is_partition(struct blkid_handle *h);
|
||||
|
||||
int blk_is_superblock(struct blkid_handle *h);
|
||||
@@ -43,6 +57,8 @@ const char *blk_get_partition_type(struct blkid_handle *h);
|
||||
|
||||
const char *blk_get_superblock_type(struct blkid_handle *h);
|
||||
|
||||
int blk_do_wipe(struct blkid_handle *h);
|
||||
|
||||
int blk_supported(void);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user