Code Monkey home page Code Monkey logo

lolios's People

Contributors

apsun avatar emre-school avatar hertin avatar mishul avatar pebailey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

gauravssnl

lolios's Issues

Add aligned_alloc to myalloc

This would let us get rid of the statically allocated kernel stacks (and hence remove the hard capped process limit).

UBSan doesn't work with clang

clang seems to insist on linking in the system libubsan even when we're compiling with -nostdlib.

Current workaround is to link the final executable with ld instead of cc when not using LTO, but that complicates our Makefile since the flags are different.

Support subdirectories in filesystem

Haven't thought of a good way to do this while maintaining backwards compatibility with the original filesystem spec. Ideally we can reuse some bits like we did for the inode refcount, but if not... haven't thought that far yet.

Fix clang infinite recursion in memcpy/memset

Building with clang and optimizations disabled causes infinite recursion. Apparently clang synthesizes a call to memset... inside of memset. -fno-builtin does not help (IIRC all it does is disable the builtin aliases for e.g. memcpy -> __builtin_memcpy, not prevent the builtins from being used).

Potential solutions, off the top of my head:

  • Write memcpy/memset purely in assembly.
  • Just use __builtin_memcpy/memset. Last I checked, GCC generates REP MOVSB which is significantly slower than our "MOVSQ" loop in QEMU. Not sure about clang. We also need to figure out what to do about types, since our string.c currently takes ints for size parameters.

Support 4KB granularity pages

Because I was lazy, pages obtained via sbrk are given out in increments of 4MB so that we didn't have to maintain page tables. However this is fairly inefficient (and I foresee issues with ELF r/w/x support since the linker script seems to assume a page size of 4KB) so we should do this properly.

TCP loopback breaks at high bandwidth

Terminal 1: nc -l 127.0.0.1 1111
Terminal 2: nc 127.0.0.1 1111 < random

Socket manages to send some data, then aborts the connection. Adding TCP_DEBUG_PRINT=1 interestingly makes it work fine, so this could be something related to TCP windows or ne2k capacity.

Change size-related usages of int -> size_t

Arguments for doing this:

  • Casting sizeof() everywhere is ugly (counterpoint: maybe this means we should make a #define isizeof(x) ((int)sizeof(x)) macro instead?
  • Improve standards conformance of libc string functions (counterpoint: we use char instead of int and some non-standard function signatures already)
  • Compiler builtins assume memcpy/memmove/memset take size_t and synthesize calls accordingly, so on the off chance we ever want to support 64-bit, we'll get mismatched argument types (although I guess since x64 uses fastcall, it probably won't explode immediately?)
  • malloc() and friends are odd-ones-out (since myalloc was originally an external project)
  • I think getting the OS to compile with -Wconversion would be pretty cool, and using int makes it a lot harder

I don't want to change the return type of syscalls (for uniformity/OCD reasons); this effectively means that all syscalls are still limited to reading 2GB at a time. Which is fine; we need to limit the range to half of size_t anyways since the return value needs to encode an error bit.

Make socketcalls respect nonblocking flag

Currently socketcalls always return -EAGAIN even if the file descriptor is not set to nonblocking mode which is kinda out of place. Potential solution paths:

a) use BLOCKING_WAIT at the socketcall level (socket.c). The socket struct can have a single sleep queue. Pros: less complexity at the protocol level, no need to propagate nonblocking flag to protocol layer. Cons: not as flexible.

b) use BLOCKING_WAIT at the protocol level (tcp.c/udp.c). Pros: fully customizable by syscall/whatever. Cons: need to figure out how to propagate the nonblocking flag.

Callee-save registers being clobbered when entering userspace

This is very dangerous. Since we don't restore ebx/esi/edi as the caller of process_run expects, we could corrupt the registers in the kernel if the way GCC arranges our variables changes. We should explicitly surround the call to process_run with clobbers.

Correctly propagate error codes

A lot of code in the kernel uses the following pattern:

if (fn() < 0) {
    return -1;
}

This discards the error code and replaces it with a generic -1. If we ever want to start returning proper error codes like EINVAL, ENOMEM, etc, we need to replace this with:

if ((ret = fn()) < 0) {
    return ret;
}

VGA cursor sometimes not displaying

When typing on the last line of the terminal or on the second/third terminal screens, the cursor disappears. It comes back if you type some characters and then delete them with backspace.

Keyboard state out of sync

Currently we only detect deltas, not full states. This causes 2 annoying bugs:

  1. If caps lock is ON when the machine boots, the states will be flipped (i.e. ON -> OFF, OFF -> ON).
  2. Some keyboards (like mine) do not distinguish left/right alt/ctrl keys. This means that if both keys are pressed down, then one is released, the modifier state will change to unpressed even though the other key is still down.

We can probably fix this by polling the complete modifier state every time one of them changes.

Register/memory corruption when compiled with gcc -Og

Repro: /build.sh -rOg run, hit any key, instant BSOD in terminal_tty_read. Backtrace:

Exception: Page-fault exception (14)

Registers:
eax: 0xfffffffd     ebx: 0xfffffffd     ecx: 0x00000001     edx: 0x00000466
esi: 0x0043e020     edi: 0x00000000     ebp: 0x0041bf54     esp: 0x00000004
cr0: 0x80000011     cr2: 0x0000000c     cr3: 0x00415000     cr4: 0x00000010
eip: 0x0040df60  eflags: 0x00000046   error: 0x00000000
cs: 0x0010   ds: 0x0018   es: 0x0018   fs: 0x0018   gs: 0x0018   ss: 0x819c

Backtrace:
 at 0x0040df60 (0x00800050, 0x08400008, 0x00000400, 0x00407b33, 0x00000008)
 at 0x0040144f (0x00000000, 0x08400008, 0x00000400, 0x08049c0a, 0x0804e56c)
 at 0x00402f5e (0x00000000, 0x00000000, 0x083ffeb8, 0x00400164, 0x0041bfc0)
 at 0x00402fb9 (0x0041bfc0, 0x083ffeb8, 0x0804e56c, 0x08049c0a, 0x00000400)
 at 0x00400164 (0x00000000, 0x00000000, 0x083ffef8, 0x0804ad97, 0x00000000)
 at 0x0804a19d (0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000)
 at 0x0804ad97 (0x083fff3f, 0x00000081, 0x0804e56c, 0x00000000, 0x00000000)
 at 0x0804ae43 (0x083fff3f, 0x00000081, 0x00000000, 0x00000000, 0x00000000)

I suspect an optimization in a new version of GCC is breaking something in the scheduler code. Strangely this only happens in -Og; levels 0, 1, 2, 3 don't exhibit this behavior. clang doesn't do this either.

$ gcc --version
gcc (GCC) 12.2.1 20230201

Split IRQ and IDT code

The two are logically independent, IDT should be strictly for the interrupt handler ASM <-> C function linkage. This also causes bugs like passing INT_IRQ8 to the register_irq_handler when we should have used IRQ_RTC instead.

However, the IRQ code should probably not go into i8259.c, since that would introduce a circular dependency between i8259.c and idt.c.

RTC + concurrent reads = ?

This may or may not be a problem, but what happens if we have 2 processes who call rtc_read at the same time (one process is pre-empted while waiting for the next tick, and the other also calls read)? If the flag is set to 0 between stopping process 1 and starting process 2, the first process will miss a tick.

This probably isn't a huge issue, but it would be nice to virtualize the RTC for multple processes which should fix this problem. Each process has its own interrupt_occurred flag, and on tick all of them will be reset to 0. Also each file descriptor should have its own virtual RTC frequency.

Compiling with gcc -O3 + LTO fails with linker error

/usr/bin/ld: /tmp/ccjI03lp.ltrans1.ltrans.o: in function `terminal_mouse_read.lto_priv.0':
<artificial>:(.text+0x2a53): undefined reference to `scheduler_yield_impl'

I already marked scheduler_yield_impl as __attribute__((used)), not sure how to fix this one.

Fix netcat DNS lookup buffer overflows

Our DNS response parser is trash. We should fix it to limit reads into the response body range only. Currently this is vulnerable to RCE (though I suppose since we only support QEMU, this probably isn't that big of an issue).

Support real ELF loading

It would be great to get rid of the elfconvert black box binary, one way would be to load real x86 ELF binaries. The post-elfconvert binaries seem to be valid ELF, as they can be executed natively on Linux (cat for instance), so we can transparently replace the old implementation.

elf.h: https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h

Unfortunately the x86 ABI specifies that addresses 4MB~3GB are available for usage. There are two solutions:
a. move the kernel to virtual address 3GB
b. write a custom linker script to avoid the 4-8MB page

Currently there are no plans to support a dynamic linker. All binaries should be statically linked.

Vidmap + multiple terminals = fail

We should update the vidmap page to point to the "backing" page if the executing process is not currently displayed.

This depends on issue #9, so finish that first.

Fix userspace makefile dependency detection

Currently, modifying a header in userspace/ doesn't rebuild programs that depend on it. In kernel/ we have Makefile.dep, but the mechanism used to generate it assumes a flat directory tree which is not the case in userspace/.

vgabios.bin not present in Arch Linux seabios package

isa-vga looks for vgabios.bin which doesn't come with the seabios package on Arch (it's called vgabios-isavga.bin instead). VGA (pci-vga) on the other hand looks for vgabios-stdvga.bin which works.

Current workaround is:

sudo ln -sf /usr/share/qemu/vgabios-isavga.bin /usr/share/qemu/vgabios.bin

But obviously I'd prefer not to maintain that hack.

Switching to pci-vga is currently blocked on (obviously) PCI support, since using isa-vga is what makes hard-coding the framebuffer address work. The PCI variant requires reading the address from the BAR.

TCP deadlock if window update is lost

Consider:

local -> remote "SEQ=0, LEN=1500" (received)
remote -> local "ACK=1500, WND=0" (received - inbox is now empty, new writes are rejected)
remote -> local "ACK=1500, WND=1500" (lost)

Since we don't attempt to send anything when the window is full, we will deadlock. According to the TCP RFC, we should try to send probing packets even when the window is full to periodically check if the window has reopened.

Scheduling algorithm

To prevent visible lag, we can take a "foreground terminal has higher priority" approach to scheduling. Basically, give the foreground process extra time when choosing which process to schedule.

TCP memory corruption

Repro steps:

  1. Enable TCP_DEBUG_DROP
  2. Set TCP_FIN_TIMEOUT_MS to a smaller value (e.g. 6000) to make it go faster
  3. Repeatedly run testsocket

This seems to always corrupt 8 bytes within an object in a pattern similar to list_t (self-referential pointer). I'm strongly suspecting a use-after-free, since the other fields within the object are not smashed. Timer seems like the prime culprit at the moment since it gets used during packet loss, and it touches list_t.

Handle getargs() buffer too small

If the length of the input buffer is too small, we should either return -1 or at least make sure the string is NUL-terminated, since the test programs assume that if the call succeeded, the buffer is valid.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.