1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use linux_api::errno::Errno;
use linux_api::posix_types::kernel_mode_t;
use shadow_shim_helper_rs::syscall_types::ForeignPtr;

use crate::cshadow;
use crate::host::descriptor::CompatFile;
use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
use crate::host::syscall::type_formatting::SyscallStringArg;
use crate::host::syscall::types::{SyscallError, SyscallResult};
use crate::host::syscall::File;

impl SyscallHandler {
    log_syscall!(
        open,
        /* rv */ std::ffi::c_int,
        /* pathname */ SyscallStringArg,
        /* flags */ linux_api::fcntl::OFlag,
        /* mode */ nix::sys::stat::Mode,
    );
    pub fn open(
        ctx: &mut SyscallContext,
        _path: ForeignPtr<()>,
        _flags: std::ffi::c_int,
        _mode: kernel_mode_t,
    ) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_open, ctx)
    }

    log_syscall!(creat, /* rv */ std::ffi::c_int);
    pub fn creat(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_creat, ctx)
    }

    log_syscall!(fadvise64, /* rv */ std::ffi::c_int);
    pub fn fadvise64(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fadvise64, ctx)
    }

    log_syscall!(fallocate, /* rv */ std::ffi::c_int);
    pub fn fallocate(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fallocate, ctx)
    }

    log_syscall!(fchmod, /* rv */ std::ffi::c_int);
    pub fn fchmod(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fchmod, ctx)
    }

    log_syscall!(fchown, /* rv */ std::ffi::c_int);
    pub fn fchown(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fchown, ctx)
    }

    log_syscall!(fdatasync, /* rv */ std::ffi::c_int);
    pub fn fdatasync(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fdatasync, ctx)
    }

    log_syscall!(fgetxattr, /* rv */ std::ffi::c_int);
    pub fn fgetxattr(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fgetxattr, ctx)
    }

    log_syscall!(flistxattr, /* rv */ std::ffi::c_int);
    pub fn flistxattr(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_flistxattr, ctx)
    }

    log_syscall!(flock, /* rv */ std::ffi::c_int);
    pub fn flock(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_flock, ctx)
    }

    log_syscall!(fremovexattr, /* rv */ std::ffi::c_int);
    pub fn fremovexattr(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fremovexattr, ctx)
    }

    log_syscall!(fsetxattr, /* rv */ std::ffi::c_int);
    pub fn fsetxattr(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fsetxattr, ctx)
    }

    log_syscall!(fsync, /* rv */ std::ffi::c_int);
    pub fn fsync(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_fsync, ctx)
    }

    log_syscall!(ftruncate, /* rv */ std::ffi::c_int);
    pub fn ftruncate(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_ftruncate, ctx)
    }

    log_syscall!(getdents, /* rv */ std::ffi::c_int);
    pub fn getdents(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_getdents, ctx)
    }

    log_syscall!(getdents64, /* rv */ std::ffi::c_int);
    pub fn getdents64(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_getdents64, ctx)
    }

    log_syscall!(
        lseek,
        /* rv */ std::ffi::c_int,
        /* fd */ std::ffi::c_uint,
        /* offset */ linux_api::posix_types::kernel_off_t,
        /* whence */ std::ffi::c_uint,
    );
    pub fn lseek(
        ctx: &mut SyscallContext,
        fd: std::ffi::c_uint,
        _offset: linux_api::posix_types::kernel_off_t,
        _whence: std::ffi::c_uint,
    ) -> Result<linux_api::posix_types::kernel_off_t, SyscallError> {
        let desc_table = ctx.objs.thread.descriptor_table_borrow(ctx.objs.host);

        let file = {
            match Self::get_descriptor(&desc_table, fd)?.file() {
                CompatFile::New(file) => file,
                // if it's a legacy file, use the C syscall handler instead
                CompatFile::Legacy(_) => {
                    drop(desc_table);
                    return Self::legacy_syscall(cshadow::syscallhandler_lseek, ctx);
                }
            }
        };

        match file.inner_file() {
            File::Pipe(_) => Err(Errno::ESPIPE.into()),
            _ => {
                warn_once_then_debug!("lseek() is not implemented for this type");
                Err(Errno::ENOTSUP.into())
            }
        }
    }

    log_syscall!(readahead, /* rv */ std::ffi::c_int);
    pub fn readahead(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_readahead, ctx)
    }

    log_syscall!(sync_file_range, /* rv */ std::ffi::c_int);
    pub fn sync_file_range(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_sync_file_range, ctx)
    }

    log_syscall!(syncfs, /* rv */ std::ffi::c_int);
    pub fn syncfs(ctx: &mut SyscallContext) -> SyscallResult {
        Self::legacy_syscall(cshadow::syscallhandler_syncfs, ctx)
    }
}