Skip to content

Not safe to use #1

Closed
Closed
@jethrogb

Description

@jethrogb

When moving the stack to the heap, there is no guard page at the end of the new stack. This results in a potential stack-to-heap overflow.

extern crate stacker;
extern crate libc;

struct Data<'a>(usize,&'a u32);

fn recurse(arg: &mut [u8], data: &Data) {
    use std::sync::{Once, ONCE_INIT};
    static START: Once = ONCE_INIT;
    static GROWN: Once = ONCE_INIT;

    let &Data(limit,guard)=data;
    let ptr=&arg[0] as *const _;

    START.call_once(||{println!("start, arg @ {:?}",ptr)});

    if *guard != 0xDEADBEEF {
        panic!("Heap guard overwritten! arg @ {:?}",ptr as *const u8);
    }

    let f=||{recurse(&mut [0u8;1024*32],data);};
    if (arg as *const _ as *const u8 as usize) < limit {
        GROWN.call_once(||{println!("grown, arg @ {:?}",ptr)});

        f();
    } else {
        stacker::maybe_grow(64*1024,1024*1024,f);
    }
}

pub fn main() {
    use std::{mem,iter};

    let guardvec: Vec<u32>=iter::repeat(0xDEADBEEF).take(1024).collect();
    println!("guard @ {:?}",&guardvec[1023] as *const _);
    let limit=unsafe {
            let mut attr: libc::pthread_attr_t = mem::zeroed();
            assert_eq!(libc::pthread_attr_init(&mut attr), 0);
            assert_eq!(libc::pthread_getattr_np(libc::pthread_self(),
                                                &mut attr), 0);
            let mut stackaddr = 0 as *mut _;
            let mut stacksize = 0;
            assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
                                                   &mut stacksize), 0);
            assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
            stackaddr
    };
    println!("stack limit  {:?}",limit);
    recurse(&mut [0u8;1024*32],&Data(limit as usize,&guardvec[1023]));
}
guard @ 0x7fbf17c2effc
stack limit  0x7ffce055f000
start, arg @ 0x7ffce0d54070
grown, arg @ 0x7fbf17d2af80
thread '' panicked at 'Heap guard overwritten! arg @ 0x7fbf17c28580', src/main.rs:17

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions