From 71ad6aca3d58ae8390a355d6669137e3c3796a4d Mon Sep 17 00:00:00 2001 From: subhobhai943 Date: Tue, 25 Aug 2026 17:34:50 +0530 Subject: [PATCH] feat: Growable heap, GUI-by-default run, live sysmon, SUB/SUB default login Kernel / memory: - mm/kmalloc.c: fix "Heap: Out of memory" under the GUI. The desktop allocates three full-screen 32-bit buffers (~11MB) which overflowed the fixed 16MB pool. The heap now starts at 32MB and grows on demand from the PMM (16MB regions), with region-safe coalescing (only merges physically adjacent blocks) so growth never corrupts across separate PMM allocations. Adds heap_get_grow_count(). Build / run: - Makefile: merge `run-gui` into `run` so `make run` boots into the graphical desktop; add `run-headless` (serial-only via QEMU_CMD), bump guest RAM to 256M, update .PHONY and help. Configure: - scripts/kconfig/menuconfig.py: gate the curses UI behind isatty() on stdin and stdout so non-interactive `make configure` stops emitting "nocbreak() returned ERR" and falls cleanly through to the non-interactive writer. GUI / userland: - gui/gui_apps.c: rebuild the System Monitor from hardcoded values into live telemetry -- real heap used/total/free with a colour-shifting bar, a scrolling heap-utilisation graph, the grow counter, and real PMM RAM figures. - lazybox `free`: report how many times the heap has grown. Auth: - Default login is now SUB / SUB (Kali-style username==password), seeded first as the primary uid-0 account and set as the logged-in user; root kept for compatibility. Hardcoded "root" defaults (whoami, su, passwd, ssh, sshd session) updated to SUB. Verified: clean build on x86_64/aarch64/armv8i; GUI boots with 0 OOM/0 panic; auth engine initialises cleanly; `make configure` fallback is clean. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX --- Makefile | 26 ++++-- gui/gui_apps.c | 68 ++++++++++---- include/mm/kmalloc.h | 1 + mm/kmalloc.c | 169 +++++++++++++++++++++++++--------- net/ssh.c | 2 +- scripts/kconfig/menuconfig.py | 29 ++++-- security/auth.c | 10 +- userland/lazybox/lazybox.c | 10 +- 8 files changed, 227 insertions(+), 88 deletions(-) diff --git a/Makefile b/Makefile index 263a893..51ea46c 100644 --- a/Makefile +++ b/Makefile @@ -330,7 +330,7 @@ DEPS = $(C_OBJS:.o=.d) $(CPP_OBJS:.o=.d) $(S_OBJS:.o=.d) .DEFAULT_GOAL := all -.PHONY: all clean run run-fullscreen debug info configure menuconfig config tui nconfig defconfig x86_64_defconfig aarch64_defconfig armv8_defconfig armv8i_defconfig armv81_defconfig arm32_defconfig qemu help +.PHONY: all clean run run-headless run-fullscreen run-vnc run-server debug info configure menuconfig config tui nconfig defconfig x86_64_defconfig aarch64_defconfig armv8_defconfig armv8i_defconfig armv81_defconfig arm32_defconfig qemu help all: $(TARGET) @@ -448,24 +448,29 @@ $(IMAGE): $(BUILD_DIR)/boot/boot.bin $(BUILD_DIR)/boot/stage2.bin $(BUILD_DIR)/k # ----------------------------------------------------------------------------- # Execution & Emulation Targets # ----------------------------------------------------------------------------- -run qemu: $(TARGET) - $(QEMU_CMD) - # -vga std gives the Bochs VBE adapter the kernel drives. vgamem_mb is raised # because a 1280x720 32-bit framebuffer needs more than the 8 MB default. QEMU_VGA = -device VGA,vgamem_mb=32 -run-gui: $(TARGET) +# `make run` boots straight into the SUB-OS Graphical Desktop Environment. The +# guest window scales with zoom-to-fit; pass `nogui`/`text` on the kernel +# command line for the emergency TTY. Use `make run-headless` for serial only. +run qemu: $(TARGET) ifeq ($(ARCH), x86_64) - qemu-system-x86_64 -drive format=raw,file=$(IMAGE) \ + qemu-system-x86_64 -drive format=raw,file=$(IMAGE) -m 256M \ -netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 \ -device e1000,netdev=net0 $(QEMU_VGA) -display gtk,zoom-to-fit=on -serial stdio else ifneq ($(filter $(ARCH), aarch64 arm64),) - qemu-system-aarch64 -M virt -cpu cortex-a57 -m 128M -kernel $(BUILD_DIR)/kernel.elf -device virtio-gpu-pci -serial stdio + qemu-system-aarch64 -M virt -cpu cortex-a57 -m 256M -kernel $(BUILD_DIR)/kernel.elf -device virtio-gpu-pci -serial stdio else - qemu-system-arm -M virt -cpu cortex-a15 -m 128M -kernel $(BUILD_DIR)/kernel.elf -device virtio-gpu-pci -serial stdio + qemu-system-arm -M virt -cpu cortex-a15 -m 256M -kernel $(BUILD_DIR)/kernel.elf -device virtio-gpu-pci -serial stdio endif +# Headless: no graphical window, kernel console on the serial line only. Boot +# with `nogui` on the kernel command line to reach the TTY in this mode. +run-headless: $(TARGET) + $(QEMU_CMD) + # Fullscreen without distortion: zoom-to-fit scales the guest while preserving # its aspect ratio, letterboxing rather than stretching on a wider panel. run-fullscreen: $(TARGET) @@ -521,7 +526,10 @@ help: @echo " make aarch64_defconfig- Load AArch64 default configuration" @echo " make armv8i_defconfig - Load ARMv8i (32-bit ARM) default configuration" @echo " make all [ARCH=...] - Compile kernel image for selected architecture" - @echo " make qemu [ARCH=...] - Boot the compiled kernel in QEMU emulator" + @echo " make run [ARCH=...] - Boot into the SUB-OS Graphical Desktop in QEMU" + @echo " make run-headless - Boot in QEMU with serial console only (no window)" + @echo " make run-fullscreen - Boot the desktop in a full-screen QEMU window" + @echo " make run-vnc - Boot the desktop and expose it over VNC :0" @echo " make clean - Remove all compiled objects and disk images" @echo " make info - Display build configuration and source metrics" diff --git a/gui/gui_apps.c b/gui/gui_apps.c index 31bbce4..b8876a2 100644 --- a/gui/gui_apps.c +++ b/gui/gui_apps.c @@ -26,19 +26,41 @@ static int simple_atoi(const char* s) { // ================================================================= // 1. System Performance Monitor App (High-Res 320x240) // ================================================================= -static uint8_t g_cpu_history[60] = { - 12, 15, 18, 22, 30, 25, 20, 35, 45, 50, 42, 38, 55, 60, 48, 52, 35, 30, 25, 20, - 28, 32, 45, 60, 55, 40, 30, 25, 20, 18, 22, 25, 15, 18, 22, 30, 35, 40, 38, 42, - 30, 25, 20, 18, 15, 22, 28, 35, 40, 48, 52, 45, 38, 30, 25, 20, 18, 15, 20, 24 -}; +/* Rolling trace of live heap utilisation (percent), newest sample on the right. + * Seeded flat and advanced one sample per repaint from real allocator stats. */ +static uint8_t g_heap_history[60]; +static bool g_heap_history_seeded = false; + +static void sysmon_sample_heap(uint8_t pct) { + if (!g_heap_history_seeded) { + for (int i = 0; i < 60; i++) g_heap_history[i] = pct; + g_heap_history_seeded = true; + return; + } + for (int i = 0; i < 59; i++) g_heap_history[i] = g_heap_history[i + 1]; + g_heap_history[59] = pct; +} static void sysmon_paint(gui_window_t* win) { int cx = win->x + 12; int cy = win->y + GUI_TITLEBAR_HEIGHT + 10; - gui_gfx_draw_string_16_shadow(cx, cy, "CPU Load History (Real-Time)", GUI_THEME_PRIMARY, GUI_COLOR_BLACK); - - // CPU Graph Box + /* Pull live figures straight from the kernel allocators. */ + uint64_t heap_used = (uint64_t)heap_get_used_bytes(); + uint64_t heap_total = (uint64_t)heap_get_total_bytes(); + uint64_t heap_free = (uint64_t)heap_get_free_bytes(); + uint64_t heap_grows = (uint64_t)heap_get_grow_count(); + uint32_t heap_pct = heap_total ? (uint32_t)((heap_used * 100) / heap_total) : 0; + if (heap_pct > 100) heap_pct = 100; + + uint64_t ram_free_mb = (pmm_get_free_pages() * PMM_PAGE_SIZE) / (1024 * 1024); + uint64_t ram_total_mb = pmm_get_usable_memory() / (1024 * 1024); + + sysmon_sample_heap((uint8_t)heap_pct); + + gui_gfx_draw_string_16_shadow(cx, cy, "Heap Utilization History (Live)", GUI_THEME_PRIMARY, GUI_COLOR_BLACK); + + // Heap Graph Box int graph_x = cx; int graph_y = cy + 20; int graph_w = win->width - 24; @@ -54,31 +76,37 @@ static void sysmon_paint(gui_window_t* win) { gui_gfx_draw_line(gx, graph_y + 1, gx, graph_y + graph_h - 2, 0xFF1E293B); } - // Plot Waveform + // Plot Waveform from the live heap trace for (int i = 0; i < 59 && (i * 5 + 5) < graph_w; i++) { - int y1 = graph_y + graph_h - 3 - (g_cpu_history[i] * (graph_h - 6)) / 100; - int y2 = graph_y + graph_h - 3 - (g_cpu_history[i + 1] * (graph_h - 6)) / 100; + int y1 = graph_y + graph_h - 3 - (g_heap_history[i] * (graph_h - 6)) / 100; + int y2 = graph_y + graph_h - 3 - (g_heap_history[i + 1] * (graph_h - 6)) / 100; gui_gfx_draw_line(graph_x + 4 + i * 5, y1, graph_x + 4 + (i + 1) * 5, y2, GUI_THEME_SUCCESS); } - // Memory Usage Bar + // Heap Usage Bar (real used / total) + char buf[80]; int mem_y = graph_y + graph_h + 12; - gui_gfx_draw_string_16(cx, mem_y, "RAM Usage: 24 MB / 128 MB (18% Heap)", GUI_THEME_TEXT_MAIN); - + snprintf(buf, sizeof(buf), "Heap: %llu / %llu KB (%u%%)", + (unsigned long long)(heap_used / 1024), + (unsigned long long)(heap_total / 1024), heap_pct); + gui_gfx_draw_string_16(cx, mem_y, buf, GUI_THEME_TEXT_MAIN); + int bar_y = mem_y + 20; int bar_w = win->width - 24; gui_gfx_fill_rect(cx, bar_y, bar_w, 12, GUI_THEME_BG_DARK); - gui_gfx_fill_rect(cx, bar_y, (bar_w * 24) / 128, 12, GUI_THEME_ACCENT); + gui_gfx_fill_rect(cx, bar_y, (int)((uint64_t)bar_w * heap_pct / 100), 12, + (heap_pct >= 90) ? GUI_THEME_DANGER : GUI_THEME_ACCENT); gui_gfx_draw_rect(cx, bar_y, bar_w, 12, GUI_THEME_BORDER); - // System Telemetry Metrics - char buf[64]; + // System Telemetry Metrics (live) cpufreq_stats_t stats = cpufreq_get_stats(); - snprintf(buf, sizeof(buf), "Clock: %u.%03u GHz | Governor: ondemand", - stats.current_khz / 1000000, (stats.current_khz % 1000000) / 1000); + snprintf(buf, sizeof(buf), "Clock: %u.%03u GHz | Heap free: %llu KB | Grows: %llu", + stats.current_khz / 1000000, (stats.current_khz % 1000000) / 1000, + (unsigned long long)(heap_free / 1024), (unsigned long long)heap_grows); gui_gfx_draw_string(cx, bar_y + 20, buf, GUI_THEME_TEXT_MUTED); - snprintf(buf, sizeof(buf), "Core Tasks: 6 Active | VFS Cache: 98.4%% Hit", 0); + snprintf(buf, sizeof(buf), "System RAM: %llu MB free / %llu MB usable", + (unsigned long long)ram_free_mb, (unsigned long long)ram_total_mb); gui_gfx_draw_string(cx, bar_y + 32, buf, GUI_THEME_TEXT_DIM); } diff --git a/include/mm/kmalloc.h b/include/mm/kmalloc.h index 60b828d..3b018cb 100644 --- a/include/mm/kmalloc.h +++ b/include/mm/kmalloc.h @@ -14,6 +14,7 @@ void kfree(void* ptr); size_t heap_get_used_bytes(void); size_t heap_get_free_bytes(void); size_t heap_get_total_bytes(void); +size_t heap_get_grow_count(void); // Number of on-demand PMM growth events static inline size_t kmalloc_get_used(void) { return heap_get_used_bytes(); } static inline size_t kmalloc_get_free(void) { return heap_get_free_bytes(); } diff --git a/mm/kmalloc.c b/mm/kmalloc.c index 60ad3dd..947ae0f 100644 --- a/mm/kmalloc.c +++ b/mm/kmalloc.c @@ -5,7 +5,8 @@ #include #define HEAP_MAGIC 0x53554248 // "SUBH" -#define HEAP_INITIAL_PAGES 4096 // 16 MB initial kernel heap +#define HEAP_INITIAL_PAGES 8192 // 32 MB initial kernel heap +#define HEAP_GROW_PAGES 4096 // Grow the heap 16 MB at a time on demand typedef struct heap_block { uint32_t magic; @@ -18,11 +19,21 @@ typedef struct heap_block { #define BLOCK_HEADER_SIZE sizeof(heap_block_t) static heap_block_t* heap_start = NULL; +static heap_block_t* heap_tail = NULL; // last block in address order, for O(1) growth static size_t heap_used_bytes = 0; static size_t heap_free_bytes = 0; static size_t heap_total_bytes = 0; +static size_t heap_grow_count = 0; static spinlock_t heap_lock = SPINLOCK_INIT; +/* Two blocks may only be coalesced when they are physically adjacent. The heap + * is made of one or more regions carved from the PMM; a region boundary shows + * up as a gap between a block and its list successor, so this guard keeps the + * free-list merge from ever spanning two independent PMM allocations. */ +static inline bool blocks_adjacent(heap_block_t* a, heap_block_t* b) { + return (heap_block_t*)((uint8_t*)a + BLOCK_HEADER_SIZE + a->size) == b; +} + void heap_init(void) { void* initial_mem = pmm_alloc_pages(HEAP_INITIAL_PAGES); if (!initial_mem) { @@ -31,7 +42,7 @@ void heap_init(void) { } heap_start = (heap_block_t*)initial_mem; - heap_total_bytes = HEAP_INITIAL_PAGES * PMM_PAGE_SIZE; + heap_total_bytes = (size_t)HEAP_INITIAL_PAGES * PMM_PAGE_SIZE; heap_start->magic = HEAP_MAGIC; heap_start->is_free = true; @@ -39,10 +50,87 @@ void heap_init(void) { heap_start->next = NULL; heap_start->prev = NULL; + heap_tail = heap_start; heap_used_bytes = 0; heap_free_bytes = heap_start->size; } +/* Append a fresh region from the PMM to the tail of the free list. Must be + * called with heap_lock held. Returns the new free block, or NULL if the PMM + * cannot satisfy a contiguous run large enough for the request. */ +static heap_block_t* heap_grow(size_t need) { + size_t need_pages = (need + BLOCK_HEADER_SIZE + PMM_PAGE_SIZE - 1) / PMM_PAGE_SIZE; + size_t grow_pages = need_pages > HEAP_GROW_PAGES ? need_pages : HEAP_GROW_PAGES; + + void* mem = pmm_alloc_pages(grow_pages); + if (!mem && grow_pages != need_pages) { + /* Could not get the generous chunk; fall back to exactly what is needed. */ + grow_pages = need_pages; + mem = pmm_alloc_pages(grow_pages); + } + if (!mem) { + return NULL; + } + + heap_block_t* region = (heap_block_t*)mem; + region->magic = HEAP_MAGIC; + region->is_free = true; + region->size = (size_t)grow_pages * PMM_PAGE_SIZE - BLOCK_HEADER_SIZE; + region->next = NULL; + region->prev = heap_tail; + + if (heap_tail) { + heap_tail->next = region; + } + heap_tail = region; + if (!heap_start) { + heap_start = region; + } + + heap_total_bytes += (size_t)grow_pages * PMM_PAGE_SIZE; + heap_free_bytes += region->size; + heap_grow_count++; + + /* A PMM run handed back right after the previous tail is a real neighbour; + * fuse it so the heap does not fragment purely from growing. */ + if (region->prev && region->prev->is_free && blocks_adjacent(region->prev, region)) { + heap_block_t* prev = region->prev; + prev->size += BLOCK_HEADER_SIZE + region->size; + prev->next = region->next; // NULL + heap_tail = prev; + region = prev; + } + + return region; +} + +/* Carve `size` bytes out of a free block, splitting off the remainder. Must be + * called with heap_lock held; `curr` must be free and large enough. */ +static void* heap_take(heap_block_t* curr, size_t size) { + if (curr->size >= size + BLOCK_HEADER_SIZE + 16) { + heap_block_t* new_block = (heap_block_t*)((uint8_t*)curr + BLOCK_HEADER_SIZE + size); + new_block->magic = HEAP_MAGIC; + new_block->is_free = true; + new_block->size = curr->size - size - BLOCK_HEADER_SIZE; + new_block->next = curr->next; + new_block->prev = curr; + + if (curr->next) { + curr->next->prev = new_block; + } else { + heap_tail = new_block; + } + curr->next = new_block; + curr->size = size; + } + + curr->is_free = false; + heap_used_bytes += curr->size; + heap_free_bytes -= curr->size; + + return (void*)((uint8_t*)curr + BLOCK_HEADER_SIZE); +} + void* kmalloc(size_t size) { if (size == 0) return NULL; @@ -51,44 +139,33 @@ void* kmalloc(size_t size) { spin_lock(&heap_lock); - heap_block_t* curr = heap_start; - while (curr) { - if (curr->magic != HEAP_MAGIC) { - printk(KERN_ERR "Heap Corruption detected at %p!\n", curr); - spin_unlock(&heap_lock); - return NULL; - } - - if (curr->is_free && curr->size >= size) { - // Check if block can be split - if (curr->size >= size + BLOCK_HEADER_SIZE + 16) { - heap_block_t* new_block = (heap_block_t*)((uint8_t*)curr + BLOCK_HEADER_SIZE + size); - new_block->magic = HEAP_MAGIC; - new_block->is_free = true; - new_block->size = curr->size - size - BLOCK_HEADER_SIZE; - new_block->next = curr->next; - new_block->prev = curr; - - if (curr->next) { - curr->next->prev = new_block; - } - curr->next = new_block; - curr->size = size; + for (int attempt = 0; attempt < 2; attempt++) { + heap_block_t* curr = heap_start; + while (curr) { + if (curr->magic != HEAP_MAGIC) { + printk(KERN_ERR "Heap Corruption detected at %p!\n", curr); + spin_unlock(&heap_lock); + return NULL; } - curr->is_free = false; - heap_used_bytes += curr->size; - heap_free_bytes -= curr->size; + if (curr->is_free && curr->size >= size) { + void* ptr = heap_take(curr, size); + spin_unlock(&heap_lock); + return ptr; + } - spin_unlock(&heap_lock); - return (void*)((uint8_t*)curr + BLOCK_HEADER_SIZE); + curr = curr->next; } - curr = curr->next; + /* No block fit. Pull a new region from the PMM and try once more. */ + if (attempt == 0 && heap_grow(size)) { + continue; + } + break; } spin_unlock(&heap_lock); - printk(KERN_WARNING "Heap: Out of memory for size %llu bytes!\n", size); + printk(KERN_WARNING "Heap: Out of memory for size %llu bytes!\n", (uint64_t)size); return NULL; } @@ -116,21 +193,27 @@ void kfree(void* ptr) { heap_used_bytes -= block->size; heap_free_bytes += block->size; - // Coalesce with next block if free - if (block->next && block->next->is_free) { - block->size += BLOCK_HEADER_SIZE + block->next->size; - block->next = block->next->next; + // Coalesce with next block if free AND physically adjacent (same region). + if (block->next && block->next->is_free && blocks_adjacent(block, block->next)) { + heap_block_t* nxt = block->next; + block->size += BLOCK_HEADER_SIZE + nxt->size; + block->next = nxt->next; if (block->next) { block->next->prev = block; + } else { + heap_tail = block; } } - // Coalesce with prev block if free - if (block->prev && block->prev->is_free) { - block->prev->size += BLOCK_HEADER_SIZE + block->size; - block->prev->next = block->next; + // Coalesce with prev block if free AND physically adjacent (same region). + if (block->prev && block->prev->is_free && blocks_adjacent(block->prev, block)) { + heap_block_t* prev = block->prev; + prev->size += BLOCK_HEADER_SIZE + block->size; + prev->next = block->next; if (block->next) { - block->next->prev = block->prev; + block->next->prev = prev; + } else { + heap_tail = prev; } } @@ -151,9 +234,10 @@ void* krealloc(void* ptr, size_t new_size) { return ptr; } + size_t old_size = block->size; void* new_ptr = kmalloc(new_size); if (new_ptr) { - memcpy(new_ptr, ptr, block->size); + memcpy(new_ptr, ptr, old_size); kfree(ptr); } return new_ptr; @@ -162,3 +246,4 @@ void* krealloc(void* ptr, size_t new_size) { size_t heap_get_used_bytes(void) { return heap_used_bytes; } size_t heap_get_free_bytes(void) { return heap_free_bytes; } size_t heap_get_total_bytes(void) { return heap_total_bytes; } +size_t heap_get_grow_count(void) { return heap_grow_count; } diff --git a/net/ssh.c b/net/ssh.c index 638f513..4f9dfba 100644 --- a/net/ssh.c +++ b/net/ssh.c @@ -30,7 +30,7 @@ int sshd_start(uint16_t port) { ssh_sessions[0].in_use = true; ssh_sessions[0].state = SSH_STATE_SHELL_ACTIVE; ssh_sessions[0].authenticated = true; - strcpy(ssh_sessions[0].username, "root"); + strcpy(ssh_sessions[0].username, "SUB"); ssh_sessions[0].client_ip = 0x0A000202; // 10.0.2.2 (QEMU Host Gateway) ssh_sessions[0].client_port = 52341; ssh_sessions[0].connect_time = pit_get_ticks() / 100; diff --git a/scripts/kconfig/menuconfig.py b/scripts/kconfig/menuconfig.py index 51a7b9d..b4e382b 100755 --- a/scripts/kconfig/menuconfig.py +++ b/scripts/kconfig/menuconfig.py @@ -829,17 +829,26 @@ def main(): print(f"menuconfig: lxdialog front-end failed ({exc}); " f"falling back to the curses UI.", file=sys.stderr) - # Fallback to Curses GUI replica - try: - import curses - curses.wrapper(run_curses_gui) - print(f"*** Configuration saved to {CONFIG_FILE} and {AUTOCONF_HEADER} ***") - return - except Exception as exc: - print(f"menuconfig: curses UI unavailable ({exc}); " - f"writing the current configuration non-interactively.", file=sys.stderr) + # Fallback to the curses GUI replica, but only when we genuinely have an + # interactive terminal on both ends. Probing curses without a real TTY makes + # it fail deep inside the wrapper's teardown (e.g. "nocbreak() returned + # ERR"), which looked like a crash; gate on isatty so a piped or CI + # invocation drops straight to the non-interactive writer instead. + if sys.stdin.isatty() and sys.stdout.isatty(): + try: + import curses + curses.wrapper(run_curses_gui) + print(f"*** Configuration saved to {CONFIG_FILE} and {AUTOCONF_HEADER} ***") + return + except Exception as exc: + print(f"menuconfig: curses UI unavailable ({exc}); " + f"writing the current configuration non-interactively.", file=sys.stderr) + else: + print("menuconfig: no interactive terminal detected; " + "writing the current configuration non-interactively.", file=sys.stderr) - # Last resort: no usable TTY at all. + # Last resort: no usable TTY at all. Preserve an existing .config if present, + # otherwise fall back to the architecture default so the build never stalls. cfg = load_config() save_config(cfg) print(f"*** Configuration written to {CONFIG_FILE} and {AUTOCONF_HEADER} ***") diff --git a/security/auth.c b/security/auth.c index 45a49c3..d13ace9 100644 --- a/security/auth.c +++ b/security/auth.c @@ -23,11 +23,17 @@ void auth_init(void) { user_count = 0; current_uid = 0; - // Seed default users - auth_add_user("root", "root", 0, 0, "/root", "/bin/sh"); + // Seed default users. SUB/SUB is the primary superuser account -- the way + // Kali ships with kali/kali -- so the username and password both default to + // "SUB". It is seeded first, so uid 0 resolves to it as the logged-in user. + auth_add_user("SUB", "SUB", 0, 0, "/root", "/bin/sh"); + auth_add_user("root", "root", 0, 0, "/root", "/bin/sh"); // kept for compatibility auth_add_user("admin", "admin123", 1000, 1000, "/home/admin", "/bin/sh"); auth_add_user("guest", "guest", 1001, 1001, "/home/guest", "/bin/sh"); + // Log in as SUB by default. + auth_set_current_user("SUB"); + printk(KERN_INFO "AUTH: Pluggable Authentication & SHA-256 Shadow Password engine active\n"); } diff --git a/userland/lazybox/lazybox.c b/userland/lazybox/lazybox.c index 22417d1..9c22462 100644 --- a/userland/lazybox/lazybox.c +++ b/userland/lazybox/lazybox.c @@ -709,6 +709,8 @@ static int applet_free(int argc, char** argv) { total_kb, used_kb, free_kb, free_kb); printk("Heap: %8llu %8llu %8llu\n", kmalloc_get_total() / 1024, kmalloc_get_used() / 1024, kmalloc_get_free() / 1024); + printk(" (dynamic kernel heap, grown on demand %llu time(s))\n", + (unsigned long long)heap_get_grow_count()); return 0; } @@ -1137,7 +1139,7 @@ static int applet_aead(int argc, char** argv) { static int applet_whoami(int argc, char** argv) { (void)argc; (void)argv; const user_account_t* u = auth_get_current_user(); - printk("%s\n", u ? u->username : "root"); + printk("%s\n", u ? u->username : "SUB"); return 0; } @@ -1652,7 +1654,7 @@ static int applet_ssh(int argc, char** argv) { return 1; } - char username[32] = "root"; + char username[32] = "SUB"; char host[64] = "localhost"; uint16_t port = 22; @@ -1774,7 +1776,7 @@ static int applet_logread(int argc, char** argv) { } static int applet_su(int argc, char** argv) { - const char* target = (argc >= 2) ? argv[1] : "root"; + const char* target = (argc >= 2) ? argv[1] : "SUB"; if (auth_set_current_user(target) == 0) { printk(KERN_INFO "Switched to user '%s'\n", target); return 0; @@ -1784,7 +1786,7 @@ static int applet_su(int argc, char** argv) { } static int applet_passwd(int argc, char** argv) { - const char* user = (argc >= 2) ? argv[1] : "root"; + const char* user = (argc >= 2) ? argv[1] : "SUB"; const char* new_pass = (argc >= 3) ? argv[2] : "password"; if (auth_change_password(user, new_pass) == 0) { printk(KERN_INFO "passwd: password updated successfully for '%s'\n", user);