Fix stat stack corruption and link test

This commit is contained in:
jD91mZM2
2018-07-23 11:26:18 +02:00
parent 86a38b47d1
commit 5697ac0f84
16 changed files with 152 additions and 88 deletions
+2 -2
View File
@@ -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
View File
@@ -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 -14
View File
@@ -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 {
-1
View File
@@ -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;
+54 -1
View File
@@ -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],
}
+2 -3
View File
@@ -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]
+7 -7
View File
@@ -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
View File
@@ -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 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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)
View File
+4
View File
@@ -0,0 +1,4 @@
144
st_mode: 33188
st_size: 383
st_blksize: 4096
+41 -3
View File
@@ -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;
}
}
+19
View File
@@ -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);
}
-8
View File
@@ -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;
}