Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::io::PathWalk container overflow with sanitizer #1859

Open
alexveden opened this issue Jan 17, 2025 · 2 comments
Open

std::io::PathWalk container overflow with sanitizer #1859

alexveden opened this issue Jan 17, 2025 · 2 comments

Comments

@alexveden
Copy link
Contributor

Consider this sample example:

fn void! AstProject.load(&self) {
    if (self.proj_path) {
        path::Path p = path::temp_new(self.proj_path)!;
        if (!path::is_dir(p)) {
            return IoError.FILE_NOT_DIR?;
        }

        path::PathWalker fnwalk = fn bool!(Path p, bool is_dir, void* ctx) {
            AstProject* self = (AstProject*)ctx;
            if (is_dir) return false;

            return false;
        };
        p.walk(fnwalk, self)!!;
    }
}

With sanitizer, it fails at:

==3625966==ERROR: AddressSanitizer: container-overflow on address 0x7ffc2d7b2f18 at pc 0x7f0b91cb6c25 bp 0x7ffc2d7b2cd0 sp 0x7ffc2d7b2480
WRITE of size 16 at 0x7ffc2d7b2f18 thread T0
    #0 0x7f0b91cb6c24 in __asan_memcpy ../../../../src/libsanitizer/asan/asan_interceptors_memintrinsics.cpp:22
    #1 0x557436aa1729 in std.io.path.PathImp.new_append /home/ubertrader/code/c3c/lib/std/io/path.c3
    #2 0x557436aa4b20 in std.io.path.PathImp.walk /home/ubertrader/code/c3c/lib/std/io/path.c3:561
    #3 0x557436aa4e8c in std.io.path.PathImp.walk /home/ubertrader/code/c3c/lib/std/io/path.c3:564
    #4 0x557436ae3f23 in c3tools.ast.AstProject.load /home/ubertrader/code/c3test/lib/c3tools/ast.c3:323
    #5 0x557436ae4406 in c3symbols.process_dir /home/ubertrader/code/c3test/src/c3symbols.c3:10
    #6 0x557436ae4d9e in c3symbols.main /home/ubertrader/code/c3test/src/c3symbols.c3:94
    #7 0x557436ae5746 in @main_to_int_main_args /home/ubertrader/code/c3c/lib/std/core/private/main_stub.c3:47
    #8 0x557436ae5746 in main /home/ubertrader/code/c3test/src/c3symbols.c3:69
    #9 0x7f0b91967249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #10 0x7f0b91967304 in __libc_start_main_impl ../csu/libc-start.c:360
    #11 0x557436a2e490 in _start (/home/ubertrader/code/c3test/build/c3symbols+0x1d490)

I think it caused by this line: https://github.com/c3lang/c3c/blob/master/lib/std/io/path.c3#L554, maybe stack overflow?

Another proposal: can we replace void* by any? I segfaulted when passed p.walk(fnwalk, &self)!!; instead of p.walk(fnwalk, self)!!;

def PathWalker = fn bool! (Path, bool is_dir, void*);
@lerno
Copy link
Collaborator

lerno commented Jan 17, 2025

Since you're passing self using &self it's already a AstProject* so when you take the address of that, you're passing an AstProject** which you then cast to AstProject* which isn't great.

Also, because it is void*, this is sufficient: AstProject* self = ctx;

@lerno
Copy link
Collaborator

lerno commented Jan 17, 2025

As for the overflow I'm somewhat at a loss where this happens here. We don't see the actual allocation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants