kernel/fs: new SF's 70.11 (create symlink) and 70.12 (read symlink) with EXT driver support #570
Merged
Burer
merged 6 commits from 2026-08-21 10:30:07 +00:00
Matou1306/kolibrios:ext-symlinks into main
Dismiss Review
Are you sure you want to dismiss this review?
Labels
Clear labels
Influence/Text/TYPO
AI
Eolite
FS
GSoC
Good First PR
HLL
HardwareTested
IRCC
Influence/Settings
Lang/C
Lang/FASM
Pay for the code
Subsystem/API
Subsystem/Audio
Subsystem/Graphics
Subsystem/IPC and events
Subsystem/Memory
Subsystem/Network
Subsystem/Services(daemon)
Subsystem/Taskmanager
Subsystem/VFS
Subsystem/Window
This issue or PR in the Google Source of Code program
The issue is suitable to beginners
Paid task
infinity service, audio drivers, midi, speacker, audio programs
vesa, vga, framebuffer, cursors, blitter, and video drivers
pipes, signals, events, shared memory
virt and phys memory allocators, malloc and other
userspace and kernel(for example: serial) services
process, threads, run apps, scheduler
drivers from filesystem, fs api, blkdev, programs that work with the file system
windows, skins, buttons, mouse and keyboard code for windows (not the base code)
Category
Applications
Category
Drivers
Category
General
Category
Kernel
Category
Libraries
Kind
Breaking
Breaking change that won't be backward compatible
Kind
Bug
Something is not working
Kind
Build
Kind
Documentation
Documentation changes
Kind
Enhancement
Improve existing functionality
Kind
Feature
New functionality
Kind
Security
This is security issue
Kind
Testing
Issue or pull request related to testing
PR
Ready to merge
Pull request is ready for merge
PR
Conflicts
PR conflicts with main
PR
Dependent
This PR is dependent on another PR
PR
Request changes
Changes requested in pull request
PR
Review required
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Medium
3
The priority is medium
Priority
Low
4
The priority is low
Reviewed
Confirmed
Issue has been confirmed
Reviewed
Duplicate
This issue or pull request already exists
Reviewed
Invalid
Invalid issue
Reviewed
Won't Fix
This issue won't be fixed
Status
Abandoned
Somebody has started to work on this but abandoned work
Status
Blocked
Something is blocking this issue or pull request
Status
Need More Info
Feedback is required to reproduce issue or to continue work
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: KolibriOS/kolibrios#570
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Tested the changes on qemu and umka and everything appears to be working fine
eebe70633fto7a8183cd7c7a8183cd7cto8f6d083aee8f6d083aeetof8353df6461. Kernel heap overflow in
ext_CreateSymlink(write)ecxis checked only at line 3307 (cmp ecx, maxPathLength), then line 3369 copies that many user-controlled bytes intotempBlockBuffer. On a 1024-byte block volume a target of 1024+ characters writes past the end of the allocation. Triggerable by any caller of f70.11 with write access.2. Kernel memory disclosure in
ext_ReadSymlink(read)Lines 3429-3434 clamp
ecxto the user buffer and toINODE.fileSize, but never tobytesPerBlock, and only one block is read (3450). An inode whosefileSizeexceeds the block size - trivial on a crafted image, and exactlywhat defect 1 produces - makes line 3456 copy kernel heap past
mainBlockBufferinto the user buffer.Both paths read or write a single block, so the copy length has to be clamped
to
bytesPerBlockas well asmaxPathLength.3. Pre-existing, same class:
findInode.slow_symlinkclamps tomaxPathLength(1980) but not tobytesPerBlock, so line 1993 over-readstempBlockBufferby up to 3 KB. Not introduced here, but this PR makes it reachable by letting users create such symlinks.fs: New subfunctions 11 (create symlink) and 12 (read symlink) with added support for ext driverto kernel/fs: new SF's 70.11 (create symlink) and 70.12 (read symlink) with EXT driver support@Burer Thanks for the help, please take a look now.
The new
bytesPerBlockchecks are good, but they bound only the symlink target, not target + path tail - and the first hop skips the check that would catch it..resolve_symlinksends the first hop straight past.nested_symlink:So
.symlink_copy_remaining(2325-2335) appends'/'+ the remaining tail with an unboundedlodsb/stosb,edialready atsymlink_workspace + fileSize.symlink_workspaceisrb maxPathLength(4096).Trigger: ext image, block size 4096, a slow symlink with a 4095-byte target used as a non-terminal component, e.g.
/L/x. Target fills the buffer, then the tail writes out of bounds - length attacker-controlled, intosymlink_depth,MOUNT_POLICY,c_inode, … and adjacent kernel heap.Fix: hoist the
.nested_symlinkbound (2262-2268) out from underje .setup_extractionso target + tail is checked on the first hop too.Hi @Burer,
The check inside the nested loop is built differently (since it depends on esi pointing on the remaining path part inside
symlink_workspace). I added a check if the tail fits in the remaining space before the copy operation instead.🔴
ext_CreateSymlinkfollows the final path component. It calls the regularfindInode, so creating a symlink where one already exists resolves the old link and creates the new one at its target's path (for a dangling link - at the dead target's path). POSIXsymlink()never follows the last component and fails even on a dangling link. Fix: callreachSymlinkinstead offindInode(asext_ReadSymlinkdoes) and clearsymlink_no_followafterwards - an existing link will then correctly hit.exist.🟡
symlink_no_followis declareddwbut cleared with a byte store inext_ReadSymlink. Works today (value is only 0/1), but make the store word-sized to match the field.🟡 70.12 return convention: sysfns 30.2/30.5, which also return a path into a user buffer, always NUL-terminate (even when truncating) and count the terminator in the returned size. 70.12 currently returns raw bytes with no terminator, which introduces a second, conflicting convention. Since the API is new, better to match 30.2: always write a terminating 0 (truncate to size-1 if needed) and return the byte count including it - or, if you keep the readlink-style contract, state explicitly in the docs that the result is not NUL-terminated.
🔵
reachSymlink'smov dword [...], SYMLINK_MAX_DEPTH + 10000hsets two word fields with one instruction - clever, but add a one-line comment, otherwise it reads as a typo.@Matou1306
Sorry for long delay, was really busy on work.
Now I'm back to KOS and will try to review updates to your PR's as fast as possible.
7e5112b962to046beab0fdHello @Burer, changes on both PRs are applied now, please let me know if you find anything else. Thanks for your time and help.
6e52f8af7etod7fb1a5f73It would be good to add a flag to the information about the file/directory (system function 70.5) that indicates that the object is a symbolic link.
d7fb1a5f73to3719dba28f