Fix stat stack corruption and link test
This commit is contained in:
@@ -14,9 +14,9 @@ extern crate sys_socket;
|
||||
use core::str::FromStr;
|
||||
use core::{mem, ptr, slice, str};
|
||||
use errno::*;
|
||||
pub use netinet::in_h::*;
|
||||
use netinet::in_h::in_addr;
|
||||
use platform::types::*;
|
||||
use platform::{c_str, socklen_t, AF_INET};
|
||||
use platform::c_str;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn htonl(hostlong: u32) -> u32 {
|
||||
|
||||
+1
-34
@@ -36,46 +36,13 @@ mod sys;
|
||||
pub mod types;
|
||||
|
||||
use alloc::Vec;
|
||||
use core::{fmt, mem, ptr};
|
||||
use core::{fmt, ptr};
|
||||
|
||||
use types::*;
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: Allocator = Allocator;
|
||||
|
||||
pub const AF_INET: c_int = 2;
|
||||
pub const SOCK_STREAM: c_int = 1;
|
||||
pub const SOCK_DGRAM: c_int = 2;
|
||||
pub const SOCK_NONBLOCK: c_int = 0o4000;
|
||||
pub const SOCK_CLOEXEC: c_int = 0o2000000;
|
||||
|
||||
pub const SIG_BLOCK: c_int = 0;
|
||||
pub const SIG_UNBLOCK: c_int = 1;
|
||||
pub const SIG_SETMASK: c_int = 2;
|
||||
|
||||
pub type in_addr_t = [u8; 4];
|
||||
pub type in_port_t = u16;
|
||||
pub type sa_family_t = u16;
|
||||
pub type socklen_t = u32;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr {
|
||||
pub sa_family: sa_family_t,
|
||||
pub data: [c_char; 14],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_handler: extern "C" fn(c_int),
|
||||
pub sa_flags: c_ulong,
|
||||
pub sa_restorer: unsafe extern "C" fn(),
|
||||
pub sa_mask: sigset_t
|
||||
}
|
||||
|
||||
const NSIG: usize = 64;
|
||||
|
||||
pub type sigset_t = [c_ulong; NSIG / (8 * mem::size_of::<c_ulong>())];
|
||||
|
||||
//TODO #[thread_local]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[no_mangle]
|
||||
|
||||
@@ -1,26 +1,13 @@
|
||||
use core::{mem, ptr};
|
||||
|
||||
use errno;
|
||||
use types::*;
|
||||
use *;
|
||||
|
||||
const AT_FDCWD: c_int = -100;
|
||||
const AT_EMPTY_PATH: c_int = 0x1000;
|
||||
const AT_REMOVEDIR: c_int = 0x200;
|
||||
const AT_SYMLINK_NOFOLLOW: c_int = 0x100;
|
||||
|
||||
// Also in sys_utsname. Has to be both because cbindgen
|
||||
const UTSLENGTH: usize = 65;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct utsname {
|
||||
pub sysname: [c_char; UTSLENGTH],
|
||||
pub nodename: [c_char; UTSLENGTH],
|
||||
pub release: [c_char; UTSLENGTH],
|
||||
pub version: [c_char; UTSLENGTH],
|
||||
pub machine: [c_char; UTSLENGTH],
|
||||
pub domainname: [c_char; UTSLENGTH],
|
||||
}
|
||||
|
||||
fn e(sys: usize) -> usize {
|
||||
if (sys as isize) < 0 && (sys as isize) >= -256 {
|
||||
unsafe {
|
||||
|
||||
@@ -10,7 +10,6 @@ use syscall::flag::*;
|
||||
use syscall::{self, Result};
|
||||
|
||||
use types::*;
|
||||
use *;
|
||||
|
||||
#[thread_local]
|
||||
static mut SIG_HANDLER: Option<extern "C" fn(c_int)> = None;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use core::mem;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
use syscall::data::TimeSpec as redox_timespec;
|
||||
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
|
||||
@@ -96,8 +98,59 @@ pub struct stat {
|
||||
pub st_rdev: dev_t,
|
||||
pub st_size: off_t,
|
||||
pub st_blksize: blksize_t,
|
||||
pub st_blocks: blkcnt_t,
|
||||
|
||||
pub st_atim: time_t,
|
||||
pub st_mtim: time_t,
|
||||
pub st_ctim: time_t,
|
||||
pub st_blocks: blkcnt_t,
|
||||
|
||||
// Compared to glibc, our struct is for some reason 48 bytes too small.
|
||||
// Accessing atime works, so clearly the struct isn't incorrect...
|
||||
// This works.
|
||||
pub _pad: [u8; 48]
|
||||
}
|
||||
|
||||
pub const AF_INET: c_int = 2;
|
||||
pub const SOCK_STREAM: c_int = 1;
|
||||
pub const SOCK_DGRAM: c_int = 2;
|
||||
pub const SOCK_NONBLOCK: c_int = 0o4000;
|
||||
pub const SOCK_CLOEXEC: c_int = 0o2000000;
|
||||
|
||||
pub const SIG_BLOCK: c_int = 0;
|
||||
pub const SIG_UNBLOCK: c_int = 1;
|
||||
pub const SIG_SETMASK: c_int = 2;
|
||||
|
||||
pub type in_addr_t = [u8; 4];
|
||||
pub type in_port_t = u16;
|
||||
pub type sa_family_t = u16;
|
||||
pub type socklen_t = u32;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr {
|
||||
pub sa_family: sa_family_t,
|
||||
pub data: [c_char; 14],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_handler: extern "C" fn(c_int),
|
||||
pub sa_flags: c_ulong,
|
||||
pub sa_restorer: unsafe extern "C" fn(),
|
||||
pub sa_mask: sigset_t
|
||||
}
|
||||
|
||||
const NSIG: usize = 64;
|
||||
|
||||
pub type sigset_t = [c_ulong; NSIG / (8 * mem::size_of::<c_ulong>())];
|
||||
|
||||
const UTSLENGTH: usize = 65;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct utsname {
|
||||
pub sysname: [c_char; UTSLENGTH],
|
||||
pub nodename: [c_char; UTSLENGTH],
|
||||
pub release: [c_char; UTSLENGTH],
|
||||
pub version: [c_char; UTSLENGTH],
|
||||
pub machine: [c_char; UTSLENGTH],
|
||||
pub domainname: [c_char; UTSLENGTH],
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ pub use sys::*;
|
||||
|
||||
use core::{mem, ptr};
|
||||
use platform::types::*;
|
||||
use platform::sigset_t;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn kill(pid: pid_t, sig: c_int) -> c_int {
|
||||
@@ -59,11 +58,11 @@ pub unsafe extern "C" fn sigaction(sig: c_int, act: *const sigaction, oact: *mut
|
||||
let ptr = if !act.is_null() {
|
||||
_sigaction = Some((*act).clone());
|
||||
_sigaction.as_mut().unwrap().sa_flags |= SA_RESTORER as c_ulong;
|
||||
_sigaction.as_mut().unwrap() as *mut _ as *mut platform::sigaction
|
||||
_sigaction.as_mut().unwrap() as *mut _ as *mut platform::types::sigaction
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
};
|
||||
platform::sigaction(sig, ptr, oact as *mut platform::sigaction)
|
||||
platform::sigaction(sig, ptr, oact as *mut platform::types::sigaction)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
|
||||
@@ -28,7 +28,7 @@ pub unsafe extern "C" fn accept(
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
platform::accept(socket, address as *mut platform::sockaddr, address_len)
|
||||
platform::accept(socket, address as *mut platform::types::sockaddr, address_len)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -37,7 +37,7 @@ pub unsafe extern "C" fn bind(
|
||||
address: *const sockaddr,
|
||||
address_len: socklen_t,
|
||||
) -> c_int {
|
||||
platform::bind(socket, address as *const platform::sockaddr, address_len)
|
||||
platform::bind(socket, address as *const platform::types::sockaddr, address_len)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -46,7 +46,7 @@ pub unsafe extern "C" fn connect(
|
||||
address: *const sockaddr,
|
||||
address_len: socklen_t,
|
||||
) -> c_int {
|
||||
platform::connect(socket, address as *const platform::sockaddr, address_len)
|
||||
platform::connect(socket, address as *const platform::types::sockaddr, address_len)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -55,7 +55,7 @@ pub unsafe extern "C" fn getpeername(
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
platform::getpeername(socket, address as *mut platform::sockaddr, address_len)
|
||||
platform::getpeername(socket, address as *mut platform::types::sockaddr, address_len)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -64,7 +64,7 @@ pub unsafe extern "C" fn getsockname(
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
platform::getsockname(socket, address as *mut platform::sockaddr, address_len)
|
||||
platform::getsockname(socket, address as *mut platform::types::sockaddr, address_len)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -114,7 +114,7 @@ pub unsafe extern "C" fn recvfrom(
|
||||
buffer,
|
||||
length,
|
||||
flags,
|
||||
address as *mut platform::sockaddr,
|
||||
address as *mut platform::types::sockaddr,
|
||||
address_len,
|
||||
)
|
||||
}
|
||||
@@ -143,7 +143,7 @@ pub unsafe extern "C" fn sendto(
|
||||
message,
|
||||
length,
|
||||
flags,
|
||||
dest_addr as *const platform::sockaddr,
|
||||
dest_addr as *const platform::types::sockaddr,
|
||||
dest_len,
|
||||
)
|
||||
}
|
||||
|
||||
+10
-4
@@ -6,7 +6,7 @@ extern crate platform;
|
||||
|
||||
use platform::types::*;
|
||||
|
||||
pub const S_IFMT: c_int = 0o0170000;
|
||||
pub const S_IFMT: c_int = 0o0170000;
|
||||
pub const S_IFBLK: c_int = 0o060000;
|
||||
pub const S_IFCHR: c_int = 0o020000;
|
||||
pub const S_IFIFO: c_int = 0o010000;
|
||||
@@ -43,10 +43,16 @@ pub struct stat {
|
||||
pub st_rdev: dev_t,
|
||||
pub st_size: off_t,
|
||||
pub st_blksize: blksize_t,
|
||||
pub st_atime: time_t,
|
||||
pub st_mtime: time_t,
|
||||
pub st_ctime: time_t,
|
||||
pub st_blocks: blkcnt_t,
|
||||
|
||||
pub st_atim: time_t,
|
||||
pub st_mtim: time_t,
|
||||
pub st_ctim: time_t,
|
||||
|
||||
// Compared to glibc, our struct is for some reason 48 bytes too small.
|
||||
// Accessing atime works, so clearly the struct isn't incorrect...
|
||||
// This works.
|
||||
pub _pad: [u8; 48]
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -8,22 +8,22 @@ mod inner {
|
||||
|
||||
use self::platform::types::*;
|
||||
|
||||
const LENGTH: usize = 65;
|
||||
const UTSLENGTH: usize = 65;
|
||||
|
||||
#[no_mangle]
|
||||
#[repr(C)]
|
||||
pub struct utsname {
|
||||
pub sysname: [c_char; LENGTH],
|
||||
pub nodename: [c_char; LENGTH],
|
||||
pub release: [c_char; LENGTH],
|
||||
pub version: [c_char; LENGTH],
|
||||
pub machine: [c_char; LENGTH],
|
||||
pub domainname: [c_char; LENGTH],
|
||||
pub sysname: [c_char; UTSLENGTH],
|
||||
pub nodename: [c_char; UTSLENGTH],
|
||||
pub release: [c_char; UTSLENGTH],
|
||||
pub version: [c_char; UTSLENGTH],
|
||||
pub machine: [c_char; UTSLENGTH],
|
||||
pub domainname: [c_char; UTSLENGTH],
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn uname(uts: *mut utsname) -> c_int {
|
||||
platform::uname(uts as *mut platform::utsname)
|
||||
platform::uname(uts as *mut platform::types::utsname)
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
|
||||
+1
-1
@@ -56,6 +56,7 @@ unistd/getopt
|
||||
unistd/pipe
|
||||
unistd/rmdir
|
||||
unistd/sleep
|
||||
unistd/stat
|
||||
unistd/write
|
||||
waitpid
|
||||
wchar/mbrtowc
|
||||
@@ -70,4 +71,3 @@ unistd/gethostname
|
||||
unistd/getid
|
||||
unistd/link
|
||||
unistd/setid
|
||||
unistd/unlink
|
||||
|
||||
+2
-2
@@ -55,6 +55,7 @@ EXPECT_BINS=\
|
||||
unistd/pipe \
|
||||
unistd/rmdir \
|
||||
unistd/sleep \
|
||||
unistd/stat \
|
||||
unistd/write \
|
||||
waitpid \
|
||||
wchar/mbrtowc \
|
||||
@@ -72,8 +73,7 @@ BINS=\
|
||||
unistd/gethostname \
|
||||
unistd/getid \
|
||||
unistd/link \
|
||||
unistd/setid \
|
||||
unistd/unlink
|
||||
unistd/setid
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
144
|
||||
st_mode: 33188
|
||||
st_size: 383
|
||||
st_blksize: 4096
|
||||
+41
-3
@@ -1,8 +1,46 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
link("./link.c", "./link.out");
|
||||
perror("link");
|
||||
return 0;
|
||||
printf("%ld\n", sizeof(struct stat));
|
||||
|
||||
struct stat buf;
|
||||
|
||||
// Stat for the inode
|
||||
if (stat("unistd/link.c", &buf)) {
|
||||
perror("stat");
|
||||
return 1;
|
||||
}
|
||||
unsigned long inode = buf.st_ino;
|
||||
printf("%ld\n", inode);
|
||||
|
||||
// Create the link
|
||||
if (link("unistd/link.c", "link.out")) {
|
||||
perror("link");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Make sure inodes match
|
||||
if (stat("link.out", &buf)) {
|
||||
perror("stat");
|
||||
}
|
||||
printf("%ld\n", inode);
|
||||
printf("%ld\n", buf.st_ino);
|
||||
if (inode != buf.st_ino) {
|
||||
puts("Created file is not a link.");
|
||||
printf("unistd/link.c inode: %ld\n", inode);
|
||||
printf("link.out inode: %ld\n", buf.st_ino);
|
||||
}
|
||||
|
||||
// Remove link
|
||||
if (unlink("link.out")) {
|
||||
perror("unlink");
|
||||
return 1;
|
||||
}
|
||||
if (!stat("link.out", &buf) || errno != ENOENT) {
|
||||
perror("stat");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
printf("%ld\n", sizeof(struct stat));
|
||||
|
||||
struct stat buf;
|
||||
|
||||
if (stat("unistd/stat.c", &buf)) {
|
||||
perror("stat");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("st_mode: %u\n", buf.st_mode);
|
||||
printf("st_size: %lu\n", buf.st_size);
|
||||
printf("st_blksize: %lu\n", buf.st_blksize);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
link("./unlink.c", "./unlink.out");
|
||||
perror("unlink");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user