mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 23:13:34 +00:00
7cf66bc161
This change introduces the nointernet() function which may be called to prevent a process and its descendants from communicating with publicly routable Internet addresses. GNU Make has been modified to always call this function. In the future Landlock Make will have a way to whitelist subnets to override this behavior, or disable it entirely. Support is available for Linux only. Our firewall does not require root access. Calling nointernet() will return control to the caller inside a new process that has a SECCOMP BPF filter installed, which traps network related system calls. Your original process then becomes a permanent ptrace() supervisor that monitors all processes and threads descending from the returned child. Whenever a networking system call happens the kernel will stop the process and wakes up the monitor, which then peeks into the child memory to read the sockaddr_in to determine if it's ok. The downside to doing this is that there can be only one supervisor at a time using ptrace() on a process. So this firewall won't be enabled if you run make under strace or inside gdb. It also makes testing tricky.
165 lines
6.2 KiB
C
165 lines
6.2 KiB
C
#ifndef COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_
|
|
#define COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_
|
|
#include "libc/nt/struct/overlapped.h"
|
|
#include "libc/nt/thunk/msabi.h"
|
|
#include "libc/nt/winsock.h"
|
|
#include "libc/sock/select.h"
|
|
#include "libc/sock/sock.h"
|
|
#include "libc/sock/struct/msghdr.h"
|
|
#include "libc/sock/struct/pollfd.h"
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
#define FD_READ (1 << FD_READ_BIT)
|
|
#define FD_READ_BIT 0
|
|
#define FD_WRITE (1 << FD_WRITE_BIT)
|
|
#define FD_WRITE_BIT 1
|
|
#define FD_OOB (1 << FD_OOB_BIT)
|
|
#define FD_OOB_BIT 2
|
|
#define FD_ACCEPT (1 << FD_ACCEPT_BIT)
|
|
#define FD_ACCEPT_BIT 3
|
|
#define FD_CONNECT (1 << FD_CONNECT_BIT)
|
|
#define FD_CONNECT_BIT 4
|
|
#define FD_CLOSE (1 << FD_CLOSE_BIT)
|
|
#define FD_CLOSE_BIT 5
|
|
|
|
struct sockaddr_bsd {
|
|
uint8_t sa_len; /* « different type */
|
|
uint8_t sa_family; /* « different type */
|
|
char sa_data[14];
|
|
};
|
|
|
|
struct sockaddr_in_bsd {
|
|
uint8_t sin_len; /* « different type */
|
|
uint8_t sin_family; /* « different type */
|
|
uint16_t sin_port;
|
|
struct in_addr sin_addr;
|
|
uint8_t sin_zero[8];
|
|
};
|
|
|
|
struct msghdr_bsd {
|
|
void *msg_name;
|
|
uint32_t msg_namelen;
|
|
struct iovec *msg_iov;
|
|
uint32_t msg_iovlen; /* « different type */
|
|
void *msg_control;
|
|
uint64_t msg_controllen;
|
|
uint32_t msg_flags; /* « different type */
|
|
};
|
|
|
|
struct sockaddr_un_bsd {
|
|
uint8_t sun_len; /* sockaddr len including NUL on freebsd but excluding it on
|
|
openbsd/xnu */
|
|
uint8_t sun_family;
|
|
char sun_path[108];
|
|
};
|
|
|
|
union sockaddr_storage_bsd {
|
|
struct sockaddr_bsd sa;
|
|
struct sockaddr_in_bsd sin;
|
|
struct sockaddr_un_bsd sun;
|
|
};
|
|
|
|
union sockaddr_storage_linux {
|
|
struct sockaddr sa;
|
|
struct sockaddr_in sin;
|
|
struct sockaddr_un sun;
|
|
};
|
|
|
|
/* ------------------------------------------------------------------------------------*/
|
|
|
|
#define SOCKFD_OVERLAP_BUFSIZ 128
|
|
|
|
struct SockFd {
|
|
int family;
|
|
int type;
|
|
int protocol;
|
|
uint32_t rcvtimeo;
|
|
uint32_t sndtimeo;
|
|
bool32 (*__msabi ConnectEx)(int64_t s, const struct sockaddr *name,
|
|
int namelen, const void *opt_lpSendBuffer,
|
|
uint32_t dwSendDataLength,
|
|
uint32_t *out_lpdwBytesSent,
|
|
struct NtOverlapped *inout_lpOverlapped);
|
|
bool32 (*__msabi AcceptEx)(
|
|
int64_t sListenSocket, int64_t sAcceptSocket,
|
|
void *out_lpOutputBuffer /*[recvlen+local+remoteaddrlen]*/,
|
|
uint32_t dwReceiveDataLength, uint32_t dwLocalAddressLength,
|
|
uint32_t dwRemoteAddressLength, uint32_t *out_lpdwBytesReceived,
|
|
struct NtOverlapped *inout_lpOverlapped);
|
|
};
|
|
|
|
errno_t __dos2errno(uint32_t) hidden;
|
|
|
|
int32_t __sys_accept(int32_t, void *, uint32_t *, int) dontdiscard hidden;
|
|
int32_t __sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden;
|
|
int32_t __sys_bind(int32_t, const void *, uint32_t) hidden;
|
|
int32_t __sys_connect(int32_t, const void *, uint32_t) hidden;
|
|
int32_t __sys_getpeername(int32_t, void *, uint32_t *) hidden;
|
|
int32_t __sys_getsockname(int32_t, void *, uint32_t *) hidden;
|
|
int32_t __sys_socket(int32_t, int32_t, int32_t) hidden;
|
|
int32_t __sys_socketpair(int32_t, int32_t, int32_t, int32_t[2]) hidden;
|
|
|
|
int32_t sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden;
|
|
int32_t sys_accept(int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_bind(int32_t, const void *, uint32_t) hidden;
|
|
int32_t sys_connect(int32_t, const void *, uint32_t) hidden;
|
|
int32_t sys_getsockopt(int32_t, int32_t, int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_listen(int32_t, int32_t) hidden;
|
|
int32_t sys_getsockname(int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_getpeername(int32_t, void *, uint32_t *) hidden;
|
|
int32_t sys_poll(struct pollfd *, uint64_t, signed) hidden;
|
|
int32_t sys_shutdown(int32_t, int32_t) hidden;
|
|
int32_t sys_socket(int32_t, int32_t, int32_t) hidden;
|
|
int32_t sys_socketpair(int32_t, int32_t, int32_t, int32_t[2]) hidden;
|
|
int64_t sys_readv(int32_t, const struct iovec *, int32_t) hidden;
|
|
int64_t sys_writev(int32_t, const struct iovec *, int32_t) hidden;
|
|
ssize_t sys_recvfrom(int, void *, size_t, int, void *, uint32_t *) hidden;
|
|
ssize_t sys_sendto(int, const void *, size_t, int, const void *,
|
|
uint32_t) hidden;
|
|
ssize_t sys_sendmsg(int, const struct msghdr *, int) hidden;
|
|
ssize_t sys_recvmsg(int, struct msghdr *, int) hidden;
|
|
int32_t sys_select(int32_t, fd_set *, fd_set *, fd_set *,
|
|
struct timeval *) hidden;
|
|
int sys_pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *,
|
|
const sigset_t *);
|
|
int sys_setsockopt(int, int, int, const void *, uint32_t) hidden;
|
|
int32_t sys_epoll_create(int32_t) hidden;
|
|
int32_t sys_epoll_ctl(int32_t, int32_t, int32_t, void *) hidden;
|
|
int32_t sys_epoll_wait(int32_t, void *, int32_t, int32_t) hidden;
|
|
int sys_poll_metal(struct pollfd *, size_t, unsigned);
|
|
|
|
int sys_poll_nt(struct pollfd *, uint64_t, uint64_t *) hidden;
|
|
int sys_socket_nt(int, int, int) hidden;
|
|
/*
|
|
int sys_socketpair_nt_stream(int, int, int, int[2]) hidden;
|
|
int sys_socketpair_nt_dgram(int, int, int, int[2]) hidden;
|
|
*/
|
|
int sys_socketpair_nt(int, int, int, int[2]) hidden;
|
|
int sys_select_nt(int, fd_set *, fd_set *, fd_set *, struct timeval *) hidden;
|
|
|
|
bool __asan_is_valid_msghdr(const struct msghdr *);
|
|
ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) hidden;
|
|
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
|
size_t) hidden;
|
|
ssize_t sys_sendto_nt(int, const struct iovec *, size_t, uint32_t, void *,
|
|
uint32_t) hidden;
|
|
|
|
void WinSockInit(void) hidden;
|
|
int64_t __winsockerr(void) nocallback hidden;
|
|
int __fixupnewsockfd(int, int) hidden;
|
|
int __wsablock(int64_t, struct NtOverlapped *, uint32_t *, bool,
|
|
uint32_t) hidden;
|
|
int64_t __winsockblock(int64_t, unsigned, int64_t, uint32_t) hidden;
|
|
struct SockFd *_dupsockfd(struct SockFd *) hidden;
|
|
int64_t GetNtBaseSocket(int64_t) hidden;
|
|
int sys_close_epoll(int) hidden;
|
|
|
|
int sockaddr2bsd(const void *, uint32_t, union sockaddr_storage_bsd *,
|
|
uint32_t *);
|
|
void sockaddr2linux(const union sockaddr_storage_bsd *, uint32_t,
|
|
union sockaddr_storage_linux *, uint32_t *);
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_SOCK_INTERNAL_H_ */
|