Path: blob/main/tests/sys/geom/class/eli/unaligned_io.c
39635 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2023 The FreeBSD Foundation4*5* This software was developed by Mark Johnston under sponsorship from6* the FreeBSD Foundation.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions are10* met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in15* the documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*/2930/*31* Idea from a test case by Andrew "RhodiumToad" Gierth in Bugzilla PR 271766.32*/3334#include <sys/param.h>35#include <sys/disk.h>36#include <sys/mman.h>3738#include <crypto/cryptodev.h>3940#include <err.h>41#include <fcntl.h>42#include <stdlib.h>43#include <string.h>44#include <unistd.h>4546int47main(int argc, char **argv)48{49const char *disk;50char *buf1, *buf2;51off_t disksz;52size_t bufsz, iosz;53ssize_t n;54unsigned int offsets, secsz;55int fd;5657if (argc != 2)58errx(1, "Usage: %s <disk>", argv[0]);59disk = argv[1];6061fd = open(disk, O_RDWR);62if (fd < 0)63err(1, "open(%s)", disk);6465if (ioctl(fd, DIOCGSECTORSIZE, &secsz) != 0)66err(1, "ioctl(DIOCGSECTORSIZE)");67if (secsz == 0)68errx(1, "ioctl(DIOCGSECTORSIZE) returned 0");69if (ioctl(fd, DIOCGMEDIASIZE, &disksz) != 0)70err(1, "ioctl(DIOCGMEDIASIZE)");71if (disksz / secsz < 2)72errx(1, "disk needs to be at least 2 sectors in size");73iosz = 2 * secsz;7475bufsz = iosz + secsz;76buf1 = mmap(NULL, bufsz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,77-1, 0);78if (buf1 == MAP_FAILED)79err(1, "mmap");80buf2 = mmap(NULL, bufsz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,81-1, 0);82if (buf2 == MAP_FAILED)83err(1, "mmap");8485arc4random_buf(buf1, bufsz);86n = pwrite(fd, buf1, bufsz, 0);87if (n < 0 || (size_t)n != bufsz)88err(1, "pwrite");8990/*91* Limit the number of offsets we test with, to avoid spending too much92* time when the sector size is large.93*/94offsets = MAX(EALG_MAX_BLOCK_LEN, HMAC_MAX_BLOCK_LEN) + 1;9596/*97* Read test: read the first 2 sectors into buf1, then do the same with98* buf2, except at varying offsets into buf2. After each read, compare99* the buffers and make sure they're identical. This exercises corner100* cases in the crypto layer's buffer handling.101*/102n = pread(fd, buf1, iosz, 0);103if (n < 0 || (size_t)n != iosz)104err(1, "pread");105for (unsigned int i = 0; i < offsets; i++) {106n = pread(fd, buf2 + i, iosz, 0);107if (n < 0 || (size_t)n != iosz)108err(1, "pread");109if (memcmp(buf1, buf2 + i, iosz) != 0)110errx(1, "read mismatch at offset %u/%u", i, secsz);111}112113/*114* Write test. Try writing buffers at various alignments, and verify115* that we read back what we wrote.116*/117arc4random_buf(buf1, bufsz);118for (unsigned int i = 0; i < offsets; i++) {119n = pwrite(fd, buf1 + i, iosz, 0);120if (n < 0 || (size_t)n != iosz)121err(1, "pwrite");122n = pread(fd, buf2, iosz, 0);123if (n < 0 || (size_t)n != iosz)124err(1, "pread");125if (memcmp(buf1 + i, buf2, iosz) != 0)126errx(1, "write mismatch at offset %u/%u", i, secsz);127}128129return (0);130}131132133