Skip to content

Conversation

@hpaluch
Copy link

@hpaluch hpaluch commented Jun 8, 2025

Here is draft patch to fix fatal error Invalid argument when accessing any block device (USB stick, disk drive, ...) on FreeBSD. It is caused by FreeBSD requirement that block device I/O must be aligned to sector size. So I simply copied Windows code part using 512 bytes to FreeBSD part.

Warning

Proper patch should somehow detect used sector size, but I don't have 4K sectors USB stick to verify that.

Existing references:

Details: here is what happens when unpatched libcfile is used:

$ ./bdetools/bdeinfo -v /dev/da0

bdeinfo 20240625  
                                 
Unable to open: /dev/da0.
libcfile_file_read_buffer_with_error_code: unable to read from file with error: Invalid argument
libcfile_file_read_buffer: unable to read from file.
libbfio_file_io_handle_read_buffer: unable to read from file: /dev/da0.
libbfio_file_range_io_handle_read_buffer: unable to read from file IO handle.
libbfio_internal_handle_read_buffer: unable to read from handle.
libbfio_handle_read_buffer_at_offset: unable to read buffer.
libbde_metadata_block_header_read_file_io_handle: unable to read FVE metadata block header data at offset: 2472767488 (0x93637000).
libbde_metadata_read_block: unable to read metadata block header.
libbde_internal_volume_open_read: unable to read primary metadata block.
libbde_volume_open_file_io_handle: unable to read from file IO handle.
info_handle_open: unable to open volume. 

Truss command reveals what's the problem:

openat(AT_FDCWD,"/dev/da0",O_RDONLY|O_CLOEXEC,00) = 3 (0x3)
fstat(3,{ mode=crw-r----- ,inode=130,size=0,blksize=4096 }) = 0 (0x0)
ioctl(3,DIOCGMEDIASIZE,0x8211e01d8)              = 0 (0x0)
lseek(3,0x0,SEEK_SET)                            = 0 (0x0)
lseek(3,0x0,SEEK_SET)                            = 0 (0x0)
lseek(3,0x0,SEEK_CUR)                            = 0 (0x0)
read(3,"\M-kX\M^P-FVE-FS-\0\^B\b^\^D\0\0"...,512) = 512 (0x200)
lseek(3,0x93637000,SEEK_SET)                     = 2472767488 (0x93637000)
lseek(3,0x0,SEEK_CUR)                            = 2472767488 (0x93637000)
read(3,0x8211e01c0,64)                           ERR#22 'Invalid argument'

Notice that first read (512 bytes) finishes without error, while seconds read (64 bytes) fails with Invalid argument. Also seek is OK (I use 4GB USB stick so it is in allowed range).

Tested FreeBSD version:

$ uname -a

FreeBSD fbsd-bde 14.2-RELEASE FreeBSD 14.2-RELEASE releng/14.2-n269506-c8918d6c7412 GENERIC amd64

$ uname -U

1402000

$ uname -K

Note: I tested my patch in quirky way:

  1. I modified synclibs.sh in libbde project to exclude libcfile from list:
diff --git a/synclibs.sh b/synclibs.sh
index 7f8be52..d29a623 100755
--- a/synclibs.sh
+++ b/synclibs.sh
@@ -7,7 +7,7 @@ EXIT_SUCCESS=0;
 EXIT_FAILURE=1;
 
 GIT_URL_PREFIX="https://github.com/libyal";
-LOCAL_LIBS="libbfio libcaes libcdata libcerror libcfile libclocale libcnotify libcpath libcsplit libcthreads libfcache libfdatetime libfguid libfvalue libhmac libuna";
+LOCAL_LIBS="libbfio libcaes libcdata libcerror libclocale libcnotify libcpath libcsplit libcthreads libfcache libfdatetime libfguid libfvalue libhmac libuna";
 
 OLDIFS=$IFS;
 IFS=" ";
  1. next cloned it to synclib-hp.sh and hacked URLs and branch for it:
--- synclibs.sh	2025-06-08 10:02:15.988473000 +0200
+++ synclibs-hp.sh	2025-06-08 10:04:04.516640000 +0200
@@ -6,8 +6,8 @@
 EXIT_SUCCESS=0;
 EXIT_FAILURE=1;
 
-GIT_URL_PREFIX="https://github.com/libyal";
-LOCAL_LIBS="libbfio libcaes libcdata libcerror libclocale libcnotify libcpath libcsplit libcthreads libfcache libfdatetime libfguid libfvalue libhmac libuna";
+GIT_URL_PREFIX="https://github.com/hpaluch";
+LOCAL_LIBS="libcfile";
 
 OLDIFS=$IFS;
 IFS=" ";
@@ -30,14 +30,14 @@
 
 	LATEST_TAG=`cd ${LOCAL_LIB}-$$ && git describe --tags --abbrev=0`;
 
-	if test -n ${LATEST_TAG} && test "$1" != "--use-head";
-	then
-		echo "Synchronizing: ${LOCAL_LIB} from ${GIT_URL} tag ${LATEST_TAG}";
+	#if test -n ${LATEST_TAG} && test "$1" != "--use-head";
+	#then
+	#	echo "Synchronizing: ${LOCAL_LIB} from ${GIT_URL} tag ${LATEST_TAG}";
 
-		(cd ${LOCAL_LIB}-$$ && git checkout --quiet tags/${LATEST_TAG});
-	else
-		echo "Synchronizing: ${LOCAL_LIB} from ${GIT_URL} HEAD";
-	fi
+		(cd ${LOCAL_LIB}-$$ && git checkout br-fix-fbsd-invalid-arg);
+	#else
+	#	echo "Synchronizing: ${LOCAL_LIB} from ${GIT_URL} HEAD";
+	#fi
 
 	rm -rf ${LOCAL_LIB};
 	mkdir ${LOCAL_LIB};
  1. finally run (in libbde project):
./synclibs-hp.sh 
./synclibs.sh 
./autogen.sh 
./configure
make
doas ./bdetools/bdeinfo -v /dev/da0

That did trick for me to use my own libcfile project and branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant