instead of hardcoding the tunnel interface MTU to 1280,
we calculate the tunnel MTU from the outside MTU, which
can now be specified with the -m mtu option. The deault
outside MTU is 1500 - 8 (PPPoE).
when a process does an exec, it calls procsetup() which
unconditionally sets the sets the TS flag and fpstate=FPinit
and fpurestore() should not revert the fpstate.
cannot just reenable the fpu in FPactive case as we might have
been procsaved() an rescheduled on another cpu. what was i thinking...
thanks qu7uux for reproducing the problem.
new approach to graphics memory management:
the kernel driver never really cared about the size of stolen memory
directly. that was only to figure out the maximum allocation
to place the hardware cursor image somewhere at the end of the
allocation done by bios.
qu7uux's gm965 bios however wont steal enougth memory for his
native resolution so we have todo it manually.
the userspace igfx driver will figure out how much the bios
allocated by looking at the gtt only. then extend the memory by
creating a "fixed" physical segment.
the kernel driver allocates the memory for the cursor image
from normal kernel memory, and just maps it into the gtt at the
end of the virtual kernel framebuffer aperture.
thanks to qu7uux for the patch.
Add assembler versions for aes_encrypt/aes_decrypt and the key
setup using AES-NI instruction set. This makes aes_encrypt and
aes_decrypt into function pointers which get initialized by
the first call to setupAESstate().
Note that the expanded round key words are *NOT* stored in big
endian order as with the portable implementation. For that reason
the AESstate.ekey and AESstate.dkey fields have been changed to
void* forcing an error when someone is accessing the roundkey
words. One offender was aesXCBmac, which doesnt appear to be
used and the code looks horrible so it has been deleted.
The AES-NI implementation is for amd64 only as it requires the
kernel to save/restore the FPU state across syscalls and
pagefaults.
The aim is to take advantage of SSE instructions such as AES-NI
in the kernel by lazily saving and restoring FPU state across
system calls and pagefaults. (everything can can do I/O)
This is accomplished by the functions fpusave() and fpurestore().
fpusave() remembers the current state and disables the FPU if it
was active by setting the TS flag. In case the FPU gets used,
the current state gets saved and a new PFPU.fpslot is allocated
by mathemu().
fpurestore() restores the previous FPU state, reenabling the FPU
if fpusave() disabled it.
In the most common case, when userspace is not using the FPU,
then fpusave()/fpurestore() just toggle the FPpush bit in
up->fpstate.
When the FPU was active, but we do not use the FPU, then nothing
needs to be saved or restored. We just switched the TS flag on
and off agaian.
Note, this is done for the amd64 kernel only.
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
adjust to new aes_xts routines.
allow optional offset in the 4th argument where the encrypted
sectors start instead of hardcoding the 64K header area for
cryptsetup.
avoid allocating temporary buffer for cryptio() reads, we can
just decrypt in place there.
use sdmalloc() to allocate the temporary buffer for cryptio()
writes so that devsd wont need to allocate and copy in case
it didnt like our alignment.
do not duplicate the error reporting code, just use io()
that is what it is for.
allow 2*256 bit keys in addition to 2*128 bit keys.
the previous implementation was not portable at all, assuming
little endian in gf_mulx() and that one can cast unaligned
pointers to ulong in xor128(). also the error code is likely
to be ignored, so better abort() when the length is not a
multiple of the AES block size.
we also pass in full AESstate structures now instead of
the expanded key longs, so that we do not need to hardcode
the number of rounds. this allows each indiviaul keys to
be bigger than 128 bit.
the QLp structure used to occupy 24 bytes on amd64.
with some rearranging the fields we can get it to 16 bytes,
saving 8K in the data section for the 1024 preallocated
structs in the ql arena.
the rest of the changes are of cosmetic nature:
- getqlp() zeros the next pointer, so there is no need to set
it when queueing the entry.
- always explicitely compare pointers to nil.
- delete unused code from ape's qlock.c
the initial issue was that wunlock() would wakeup readers while
holding the spinlock causing deadlock in libthread programs where
rendezvous() would do a thread switch within the same process
which then can acquire the RWLock again.
the first fix tried to prevent holding the spinlock, waking up
one reader at a time with releasing an re-acquiering the spinlock.
this violates the invariant that readers can only wakup writers
in runlock() when multiple readers where queued at the time of
wunlock(). at the first wakeup, q->head != nil so runlock() would
find a reader queued on runlock() when it expected a writer.
this (hopefully last) fix unlinks *all* the reader QLp's atomically
and in order while holding the spinlock and then traverses the
dequeued chain of QLp structures again to call rendezvous() so
the invariant described above holds.
when the alarm hits while the process is currently in syslog(), holding
the sl lock, then calling syslog again will deadlock:
/proc/1729193/text:386 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/386
acid: lstk()
sleep()+0x7 /sys/src/libc/9syscall/sleep.s:5
lock(lk=0x394d8)+0xb7 /sys/src/libc/port/lock.c:25
i=0x3e8
syslog(logname=0x41c64,cons=0x0,fmt=0x41c6a)+0x2d /sys/src/libc/9sys/syslog.c:60
err=0x79732f27
d=0x0
ctim=0x0
buf=0x0
p=0x0
arg=0x0
n=0x0
catchalarm(msg=0xdfffc854)+0x7a /sys/src/cmd/upas/smtp/smtpd.c:71
notifier+0x30 /sys/src/libc/port/atnotify.c:15
this implements the mitigation suggested in section "6.5 Countermeasures" of
"Key Reinstallation Attacks: Forcing Nonce Resuse in WPA2" [1].
[1] https://papers.mathyvanhoef.com/ccs2017.pdf
copying files from the uefi shell works, reading plan9.ini works,
loading the kernel by calling Read to read in the DATA section of
the kernel *FAILS*. my guess is that uefi filesystem driver or
nvme driver tries to allocate a temporary buffer and hasnt got
the space. limiting the read size fixes it.