kboot: hostfs -- check for llseek failure correctly

The host_* syscalls are all raw Linux system calls, not the POSIX
wrappers that glibc / musl create. So we have to ranage change the
return value of host_llseek correctly to use the negative value hack
that all Linux system calls use.

This fixes a false positive error detection when we do something like
lseek(fd, 0xf1234567, ...); This returns 0xf1234567, which is a negative
value which used to trigger the error path.  Instead, we check using the
is_linux_error() and store the return value in a long. Translate that
errno to a host errno and set the global errno to that and return
-1. lseek can't otherwise return a negative number, since it's the
offset after seeking into the file, which by definition is positive.

This kept the 'read the UEFI memory map out of physical memory' from
working on aarch64 (whose boot loader falls back to reading it since
there are restrictive kernel options that can also prevent it), since
the physical address the memory map was at on my platform was like
0xfa008018.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D44286
This commit is contained in:
Warner Losh 2024-03-11 14:15:24 -06:00
parent 8b1925f29c
commit d650c3efb6

View File

@ -124,7 +124,7 @@ hostfs_seek(struct open_file *f, off_t offset, int whence)
{
hostfs_file *hf = f->f_fsdata;
uint32_t offl, offh;
int err;
long err;
uint64_t res;
/*
@ -137,8 +137,15 @@ hostfs_seek(struct open_file *f, off_t offset, int whence)
offl = res & 0xfffffffful;
offh = (res >> 32) & 0xfffffffful;
err = host_llseek(hf->hf_fd, offh, offl, &res, whence);
if (err < 0)
return (err);
/*
* Since we're interfacing to the raw linux system call, we have to
* carefully check. We have to translate the errno value from the host
* to libsa's conventions.
*/
if (is_linux_error(err)) {
errno = host_to_stand_errno(err);
return (-1);
}
return (res);
}