From: Tom Eccles <tom.eccles@codethink.co.uk>
To: dm-crypt@saout.de
Cc: richardmaw@codethink.co.uk
Subject: Re: [dm-crypt] veritysetup forward error correction failure
Date: Thu, 18 Jul 2019 12:41:21 +0100 [thread overview]
Message-ID: <e28edf2d-36d3-7f0e-91c1-ded42fe2d688@codethink.co.uk> (raw)
In-Reply-To: <0ce29b38-3f32-d2bc-651e-071075941d43@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 842 bytes --]
On 17/07/2019 8:49 pm, Milan Broz wrote:
> If you can still reproduce it, please send version of the utility and
> kernel (and --debug output as suggested in another mail) and if you have some
> data/hash/fec images that can be used to reproduce it, let me know where I can find it.
Attached is a bash script gen_image.sh which should reproduce the issue.
find_and_corrupt.c should be in the working directory when gen_image.sh is
run. find_and_corrupt.c corrupts the disk image by simply searching for a
known string and introducing an error (see the diff outputted by gen_image.sh).
See in particular the error and dmesg sample when reading the corrupted file
(gen_image.sh:77) and the success when running veritysetup verify
(gen_image.sh:86).
I have created an issue at https://gitlab.com/cryptsetup/cryptsetup/issues/462
Thanks,
Tom
[-- Attachment #2: find_and_corrupt.c --]
[-- Type: text/x-csrc, Size: 3883 bytes --]
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
// n <-> o is 0x6e <-> 0x6f so it is a single bit change
#define SEARCH_TEXT "Can you spot this error?"
#define REPLACE_TEXT "Cao you spot this error?"
#define READ_SIZE 4096
// command line args
enum {
PROG_NAME,
PATH,
MAX_ARGS
};
// so that we don't spend all our time in syscall overhead
struct read_buf {
char *buffer;
ssize_t len;
ssize_t read_ptr;
int fd;
};
static struct read_buf *read_buf_init(ssize_t size, int fd) {
if (fd < 0) {
return NULL;
}
struct read_buf *buf = malloc(sizeof(*buf));
if (buf == NULL) {
return NULL;
}
buf->buffer = malloc(size);
if (buf->buffer == NULL) {
free(buf);
return NULL;
}
buf->len = size;
buf->read_ptr = -1;
buf->fd = fd;
return buf;
}
static void read_buf_free(struct read_buf *buf) {
free(buf->buffer);
free(buf);
// doesn't close fd
}
static inline int read_buf_getc(struct read_buf *buf, char *out) {
// if we need to do another read
if (buf->read_ptr == -1 || buf->read_ptr == buf->len) {
// TODO partial read
ssize_t count = read(buf->fd, buf->buffer, buf->len);
if (count != buf->len) {
fprintf(stderr, "Read %lli, wanted %lli: %s\n",
(long long) count, (long long) buf->len,
strerror(errno));
return EXIT_FAILURE;
}
buf->read_ptr = 0;
}
*out = buf->buffer[buf->read_ptr++];
return EXIT_SUCCESS;
}
// seek through fd until we find text.
// Position the file pointer at the start of the text
static int find_text(const int fd, const char *text)
{
int ret = EXIT_FAILURE;
const size_t len = strlen(text);
size_t n_matching = 0;
off_t offset = lseek(fd, 0, SEEK_CUR);;
if (offset == -1) {
fprintf(stderr, "Failed to get current offset: %s\n",
strerror(errno));
return EXIT_FAILURE;
}
struct read_buf *buf = read_buf_init(READ_SIZE, fd);
if (buf == NULL) {
fprintf(stderr, "Couldn't allocate read_buf\n");
return EXIT_FAILURE;
}
printf("Searching for \"%s\"\n", text);
while (n_matching < len) {
char readc;
if (read_buf_getc(buf, &readc) != EXIT_SUCCESS) {
fprintf(stderr, "read_buf_getc failed\n");
goto free_buffer;
}
++offset;
if (readc == text[n_matching]) {
++n_matching;
if (n_matching == len) {
break;
}
} else {
// not a match
if (n_matching) {
n_matching = 0;
}
}
}
// go back to the beginning of the text
off_t err = lseek(fd, offset - len, SEEK_SET);
if (err == -1) {
fprintf(stderr, "Lseek error: %s\n", strerror(errno));
goto free_buffer;
}
printf("Found at %lli!\n", (long long) offset);
ret = EXIT_SUCCESS;
free_buffer:
read_buf_free(buf);
return ret;
}
static int find_and_replace(const int fd, const char *search_text,
const char *replace_text)
{
if (find_text(fd, search_text) != EXIT_SUCCESS) {
return EXIT_FAILURE;
}
const ssize_t len = strlen(replace_text);
printf("Overwriting with \"%s\"\n", replace_text);
ssize_t count = write(fd, replace_text, len);
// TODO partial write
if (count != len) {
fprintf(stderr, "write error: %s\n", strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static void print_help(const char *name)
{
fprintf(stderr, "Usage: %s FILE\n", name);
}
int main(int argc, char **argv)
{
int ret = EXIT_FAILURE;
if (argc != MAX_ARGS) {
print_help(argv[PROG_NAME]);
return EXIT_FAILURE;
}
if (strcmp("--help", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
print_help(argv[PROG_NAME]);
return EXIT_SUCCESS;
}
const char *path = argv[PATH];
int fd = open(path, O_RDWR);
if (fd == -1) {
int err = errno;
fprintf(stderr, "Can't open %s: %i: %s\n", path, err, strerror(err));
return EXIT_FAILURE;
}
ret = find_and_replace(fd, SEARCH_TEXT, REPLACE_TEXT);
close(fd);
return ret;
}
[-- Attachment #3: gen_image.sh --]
[-- Type: application/x-shellscript, Size: 2154 bytes --]
next prev parent reply other threads:[~2019-07-18 11:41 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-17 17:06 [dm-crypt] veritysetup forward error correction failure Tom Eccles
2019-07-17 18:00 ` Michael Kjörling
2019-07-17 19:49 ` Milan Broz
2019-07-18 9:10 ` Tom Eccles
2019-07-18 9:50 ` Milan Broz
2019-07-18 10:16 ` Tom Eccles
2019-07-18 11:41 ` Tom Eccles [this message]
2019-07-18 13:09 ` Milan Broz
2019-07-18 13:49 ` Tom Eccles
2019-07-18 13:59 ` Milan Broz
2019-07-18 14:01 ` Tom Eccles
2019-07-18 13:59 ` Tom Eccles
2019-07-19 7:38 ` Milan Broz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e28edf2d-36d3-7f0e-91c1-ded42fe2d688@codethink.co.uk \
--to=tom.eccles@codethink.co.uk \
--cc=dm-crypt@saout.de \
--cc=richardmaw@codethink.co.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox