While porting .NET (NativeAOT) to KasperskyOS CE 1.4.0.102, I collected where the SDK behaves differently from POSIX or Linux, or lacks something portable code expects. Most findings are shown by a small program run as the only application in a QEMU image, and most of those also on Linux for comparison; the others by commands run on the installed SDK. FINDINGS.md in https://github.com/caraioniurie47/kos-sdk-checks describes each one (the output, what POSIX, NetBSD and Linux do, what it breaks, and for most of them options), and the repository has the programs and scripts that reproduce them; the VfsRamFs crash has a reproducer of its own.
Bugs
B1 — mkstemps() fails with EINVAL for a valid template
B2 — pread, pwrite, ftruncate, fsync fail with ENOSYS on /dev/null, and three of them on pipes
B3 — VfsRamFs: utimensat(), rename() and posix_fallocate() fail unlike POSIX
While porting .NET (NativeAOT) to KasperskyOS CE 1.4.0.102, I collected where the SDK behaves differently from POSIX or Linux, or lacks something portable code expects. Most findings are shown by a small program run as the only application in a QEMU image, and most of those also on Linux for comparison; the others by commands run on the installed SDK. FINDINGS.md in https://github.com/caraioniurie47/kos-sdk-checks describes each one (the output, what POSIX, NetBSD and Linux do, what it breaks, and for most of them options), and the repository has the programs and scripts that reproduce them; the VfsRamFs crash has a reproducer of its own.
Bugs
B1 —
mkstemps()fails withEINVALfor a valid templateB2 —
pread,pwrite,ftruncate,fsyncfail withENOSYSon/dev/null, and three of them on pipesB3 — VfsRamFs:
utimensat(),rename()andposix_fallocate()fail unlike POSIXB4 — VfsRamFs crashes under concurrent stat/readdir/unlink (reported in https://forum.kaspersky.com/topic/vfsramfs-crashes-null-dereference-in-inode_destructor-under-concurrent-statreaddirunlink-kasperskyos-ce-140102-59792/)
B5 —
shutdown()on an unconnected TCP or UDP socket succeedsB6 — a socket from
accept4()inherits the listener'sO_NONBLOCKB7 —
poll()fails withEBADFfor a closed descriptor instead of settingPOLLNVALB8 — a connected UDP socket cannot be disconnected (
connect(AF_UNSPEC))B9 — a zero-length
recv()on an empty non-blocking TCP socket returns 0B10 —
sendto()of zero bytes on UDP returns 0 and sends nothingB11 —
IOV_MAXis 10, and more iovecs giveEINVAL, notEMSGSIZEB12 — a
read()orrecvmsg()blocked on a socket closed by another thread fails witherrno-3B13 — at the 512-descriptor limit
open("/dev/null")fails withENFILE;getrlimit/setrlimitare not implementedB14 —
sigaction()installs a handler forSIGKILLandSIGSTOPB15 —
mprotect()to read, write and execute fails withENOMEM, notENOTSUPB16 —
dlerror()is declaredconst char *Documentation errors
E1 —
link()fails withENOSYS, though the manual lists itE2 —
sendfile()to a TCP socket fails withEINVAL, though the manual lists itE3 — the manual documents IPv6 for
kos_net.h, but the network stack has no IPv6E4 — two typos in log messages
Undocumented behaviour
U1 — uid 0 without root's rights, yet
unlink()removes directories; directories lose setuid and setgidU2 — VfsRamFs's
statvfs()reports no free spaceU3 —
readdir()of a removed directory fails withENOENTU4 —
localhostresolves only from a hosts file given to VfsNetU5 —
FIONREADon UDP counts 16 bytes more than the datagramU6 —
SO_SNDBUF/SO_RCVBUFof 0 fail withEINVALU7 —
getsockopt()with a NULL buffer and length 0 fails withEINVALU8 — TCP
sendmsg()of more than 64 KiB fails withEMSGSIZE, even on a blocking socketU9 —
accept4()withaddress_lenover 128 fails withEACCESU10 —
setsockopt()fails withECONNRESETafter the peer's resetU11 —
accept()with no descriptor left drops the pending connectionU12 —
uname()returns constantsU13 —
pthread_condattr_init()fails on memory that holds an initialized attributeU14 — the VFS client waits about 10 s at startup when there is no VFS server
U15 —
PROT_NONEreservations take physical memory and seconds;MADV_DONTNEEDfrees nothingU16 — when a
MAP_NORESERVEwrite finds no memory, the kernel ends the processU17 —
mprotect()cannot make a read-only page of the program image writableU18 —
aarch64-kos-clang -static-pielinks dynamicallyU19 — unprefixed
clangandclang-17intoolchain/bintarget KasperskyOSMissing features
M1 —
SO_REUSEPORTworks but no header defines itM2 —
sysconf(_SC_PHYS_PAGES)fails althoughunistd.hdefines the nameM3 — OpenSSL 1.1.1t libraries without headers; OpenSSL 3
M4 —
libcrypto.areferences agetentropy()that nothing providesM5 — no GSSAPI or Kerberos library
M6 — functions declared in headers but defined in no library
M7 — no
SA_RESETHANDorSA_NODEFERM8 — no C
<uchar.h>M9 —
fallocate()without itsFALLOC_FL_*flagsM10 — commonly probed headers are absent
Proposals
P1 — an API to suspend another thread and read its registers
P2 — a supported way for an exception handler to resume at a new address with new registers
P3 — a way to query the CPU's features
Which of these do you plan to fix, which to document, and should any of them get a topic of its own?
Context
Found while porting .NET (NativeAOT) to KasperskyOS (latest release: https://github.com/caraioniurie47/runtime-kos/releases/latest).
Thanks!