Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Endevir/29f4bce0ab6b17a801d7df4ad1180039 to your computer and use it in GitHub Desktop.
Save Endevir/29f4bce0ab6b17a801d7df4ad1180039 to your computer and use it in GitHub Desktop.
diff -ruNp linux-5.4.42/arch/x86/ia32/sys_ia32.c linux-5.4.42-cher1/arch/x86/ia32/sys_ia32.c
--- linux-5.4.42/arch/x86/ia32/sys_ia32.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/arch/x86/ia32/sys_ia32.c 2020-08-22 10:28:40.182204939 +0300
@@ -97,12 +97,26 @@ static int cp_stat64(struct stat64 __use
return 0;
}
+int cher_patch_is_secure_path(const char *);
+
COMPAT_SYSCALL_DEFINE2(x86_stat64, const char __user *, filename,
struct stat64 __user *, statbuf)
{
struct kstat stat;
- int ret = vfs_stat(filename, &stat);
+ int ret = 0;
+
+ if (SBOX_IS_RESTRICTED()) {
+ struct filename *tmp = getname(filename);
+ if (IS_ERR(tmp)) return -EINVAL;
+ if (cher_patch_is_secure_path(tmp->name) < 0) {
+ putname(tmp);
+ return -EPERM;
+ }
+ if (!strncmp(tmp->name, "/SANDBOX/", 9)) filename += 9;
+ putname(tmp);
+ }
+ ret = vfs_stat(filename, &stat);
if (!ret)
ret = cp_stat64(statbuf, &stat);
return ret;
@@ -112,7 +126,20 @@ COMPAT_SYSCALL_DEFINE2(x86_lstat64, cons
struct stat64 __user *, statbuf)
{
struct kstat stat;
- int ret = vfs_lstat(filename, &stat);
+ int ret = 0;
+
+ if (SBOX_IS_RESTRICTED()) {
+ struct filename *tmp = getname(filename);
+ if (IS_ERR(tmp)) return -EINVAL;
+ if (cher_patch_is_secure_path(tmp->name) < 0) {
+ putname(tmp);
+ return -EPERM;
+ }
+ if (!strncmp(tmp->name, "/SANDBOX/", 9)) filename += 9;
+ putname(tmp);
+ }
+
+ ret = vfs_lstat(filename, &stat);
if (!ret)
ret = cp_stat64(statbuf, &stat);
return ret;
@@ -135,6 +162,10 @@ COMPAT_SYSCALL_DEFINE4(x86_fstatat, unsi
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
diff -ruNp linux-5.4.42/arch/x86/kernel/ioport.c linux-5.4.42-cher1/arch/x86/kernel/ioport.c
--- linux-5.4.42/arch/x86/kernel/ioport.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/arch/x86/kernel/ioport.c 2020-08-20 13:14:04.680823826 +0300
@@ -30,6 +30,11 @@ long ksys_ioperm(unsigned long from, uns
struct tss_struct *tss;
unsigned int i, max_long, bytes, bytes_updated;
+ if (SBOX_IS_RESTRICTED()) {
+ //SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
return -EINVAL;
if (turn_on && (!capable(CAP_SYS_RAWIO) ||
@@ -124,6 +129,11 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve
*/
unsigned int old = t->iopl >> X86_EFLAGS_IOPL_BIT;
+ if (SBOX_IS_RESTRICTED()) {
+ //SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (level > 3)
return -EINVAL;
/* Trying to gain more privileges? */
diff -ruNp linux-5.4.42/arch/x86/kernel/ldt.c linux-5.4.42-cher1/arch/x86/kernel/ldt.c
--- linux-5.4.42/arch/x86/kernel/ldt.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/arch/x86/kernel/ldt.c 2020-08-20 12:25:27.450310200 +0300
@@ -555,6 +555,11 @@ SYSCALL_DEFINE3(modify_ldt, int , func ,
{
int ret = -ENOSYS;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
switch (func) {
case 0:
ret = read_ldt(ptr, bytecount);
diff -ruNp linux-5.4.42/arch/x86/kernel/vm86_32.c linux-5.4.42-cher1/arch/x86/kernel/vm86_32.c
--- linux-5.4.42/arch/x86/kernel/vm86_32.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/arch/x86/kernel/vm86_32.c 2020-08-20 12:31:33.238748164 +0300
@@ -209,12 +209,22 @@ static long do_sys_vm86(struct vm86plus_
SYSCALL_DEFINE1(vm86old, struct vm86_struct __user *, user_vm86)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_sys_vm86((struct vm86plus_struct __user *) user_vm86, false);
}
SYSCALL_DEFINE2(vm86, unsigned long, cmd, unsigned long, arg)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
switch (cmd) {
case VM86_REQUEST_IRQ:
case VM86_FREE_IRQ:
diff -ruNp linux-5.4.42/block/ioprio.c linux-5.4.42-cher1/block/ioprio.c
--- linux-5.4.42/block/ioprio.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/block/ioprio.c 2020-08-20 13:02:46.366943492 +0300
@@ -33,6 +33,8 @@
#include <linux/security.h>
#include <linux/pid_namespace.h>
+#include <linux/sched.h>
+
int set_task_ioprio(struct task_struct *task, int ioprio)
{
int err;
@@ -99,6 +101,11 @@ SYSCALL_DEFINE3(ioprio_set, int, which,
kuid_t uid;
int ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
ret = ioprio_check_cap(ioprio);
if (ret)
return ret;
diff -ruNp linux-5.4.42/fs/aio.c linux-5.4.42-cher1/fs/aio.c
--- linux-5.4.42/fs/aio.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/aio.c 2020-08-22 11:16:05.876590992 +0300
@@ -22,6 +22,8 @@
#include <linux/refcount.h>
#include <linux/uio.h>
+#include <linux/sched.h>
+
#include <linux/sched/signal.h>
#include <linux/fs.h>
#include <linux/file.h>
@@ -1315,6 +1317,9 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_e
unsigned long ctx;
long ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
ret = get_user(ctx, ctxp);
if (unlikely(ret))
goto out;
@@ -1346,6 +1351,9 @@ COMPAT_SYSCALL_DEFINE2(io_setup, unsigne
unsigned long ctx;
long ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
ret = get_user(ctx, ctx32p);
if (unlikely(ret))
goto out;
@@ -1380,7 +1388,13 @@ out:
*/
SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
{
- struct kioctx *ioctx = lookup_ioctx(ctx);
+ struct kioctx *ioctx = NULL;
+
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
+ ioctx = lookup_ioctx(ctx);
if (likely(NULL != ioctx)) {
struct ctx_rq_wait wait;
int ret;
@@ -1912,6 +1926,9 @@ SYSCALL_DEFINE3(io_submit, aio_context_t
int i = 0;
struct blk_plug plug;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (unlikely(nr < 0))
return -EINVAL;
@@ -1954,6 +1971,9 @@ COMPAT_SYSCALL_DEFINE3(io_submit, compat
int i = 0;
struct blk_plug plug;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (unlikely(nr < 0))
return -EINVAL;
@@ -2007,6 +2027,9 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t
u32 key;
u64 obj = (u64)(unsigned long)iocb;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (unlikely(get_user(key, &iocb->aio_key)))
return -EFAULT;
if (unlikely(key != KIOCB_KEY))
@@ -2083,6 +2106,9 @@ SYSCALL_DEFINE5(io_getevents, aio_contex
struct timespec64 ts;
int ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (timeout && unlikely(get_timespec64(&ts, timeout)))
return -EFAULT;
@@ -2181,6 +2207,9 @@ SYSCALL_DEFINE5(io_getevents_time32, __u
struct timespec64 t;
int ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (timeout && get_old_timespec32(&t, timeout))
return -EFAULT;
diff -ruNp linux-5.4.42/fs/buffer.c linux-5.4.42-cher1/fs/buffer.c
--- linux-5.4.42/fs/buffer.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/buffer.c 2020-08-20 13:28:51.104704950 +0300
@@ -48,6 +48,8 @@
#include <linux/sched/mm.h>
#include <trace/events/block.h>
+#include <linux/sched.h>
+
static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
enum rw_hint hint, struct writeback_control *wbc);
@@ -3302,6 +3304,9 @@ SYSCALL_DEFINE2(bdflush, int, func, long
{
static int msg_count;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
diff -ruNp linux-5.4.42/fs/compat.c linux-5.4.42-cher1/fs/compat.c
--- linux-5.4.42/fs/compat.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/compat.c 2020-08-22 11:17:20.572600496 +0300
@@ -19,6 +19,8 @@
#include <linux/uaccess.h>
#include "internal.h"
+#include <linux/sched.h>
+
struct compat_nfs_string {
compat_uint_t len;
compat_uptr_t data;
@@ -96,6 +98,11 @@ COMPAT_SYSCALL_DEFINE5(mount, const char
char *kernel_dev;
int retval;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
kernel_type = copy_mount_string(type);
retval = PTR_ERR(kernel_type);
if (IS_ERR(kernel_type))
diff -ruNp linux-5.4.42/fs/compat_ioctl.c linux-5.4.42-cher1/fs/compat_ioctl.c
--- linux-5.4.42/fs/compat_ioctl.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/compat_ioctl.c 2020-08-20 14:20:03.954779524 +0300
@@ -1001,6 +1001,11 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned i
if (!f.file)
goto out;
+ if (SBOX_IS_RESTRICTED() && cmd != FIOCLEX && cmd != FIONCLEX) {
+ error = -EPERM;
+ goto out_fput;
+ }
+
/* RED-PEN how should LSM module know it's handling 32bit? */
error = security_file_ioctl(f.file, cmd, arg);
if (error)
diff -ruNp linux-5.4.42/fs/dcookies.c linux-5.4.42-cher1/fs/dcookies.c
--- linux-5.4.42/fs/dcookies.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/dcookies.c 2020-08-20 14:33:20.755169365 +0300
@@ -29,6 +29,8 @@
#include <linux/compat.h>
#include <linux/uaccess.h>
+#include <linux/sched.h>
+
/* The dcookies are allocated from a kmem_cache and
* hashed onto a small number of lists. None of the
* code here is particularly performance critical
@@ -206,6 +208,11 @@ out:
SYSCALL_DEFINE3(lookup_dcookie, u64, cookie64, char __user *, buf, size_t, len)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_lookup_dcookie(cookie64, buf, len);
}
diff -ruNp linux-5.4.42/fs/d_path.c linux-5.4.42-cher1/fs/d_path.c
--- linux-5.4.42/fs/d_path.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/d_path.c 2020-08-20 14:29:57.615073089 +0300
@@ -8,6 +8,8 @@
#include <linux/prefetch.h>
#include "mount.h"
+#include <linux/sched.h>
+
static int prepend(char **buffer, int *buflen, const char *str, int namelen)
{
*buflen -= namelen;
@@ -426,8 +428,14 @@ SYSCALL_DEFINE2(getcwd, char __user *, b
{
int error;
struct path pwd, root;
- char *page = __getname();
+ char *page = 0;
+
+ if (SBOX_IS_RESTRICTED()) {
+ copy_to_user(buf, "/SANDBOX", 9);
+ return 9;
+ }
+ page = __getname();
if (!page)
return -ENOMEM;
diff -ruNp linux-5.4.42/fs/eventfd.c linux-5.4.42-cher1/fs/eventfd.c
--- linux-5.4.42/fs/eventfd.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/eventfd.c 2020-08-20 14:37:21.183281967 +0300
@@ -24,6 +24,8 @@
#include <linux/seq_file.h>
#include <linux/idr.h>
+#include <linux/sched.h>
+
DEFINE_PER_CPU(int, eventfd_wake_count);
static DEFINE_IDA(eventfd_ida);
@@ -435,6 +437,9 @@ static int do_eventfd(unsigned int count
SYSCALL_DEFINE2(eventfd2, unsigned int, count, int, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_eventfd(count, flags);
}
diff -ruNp linux-5.4.42/fs/eventpoll.c linux-5.4.42-cher1/fs/eventpoll.c
--- linux-5.4.42/fs/eventpoll.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/eventpoll.c 2020-08-20 14:44:39.655485165 +0300
@@ -39,6 +39,8 @@
#include <linux/rculist.h>
#include <net/busy_poll.h>
+#include <linux/sched.h>
+
/*
* LOCKING:
* There are three level of locking required by epoll :
@@ -2089,6 +2091,9 @@ out_free_ep:
SYSCALL_DEFINE1(epoll_create1, int, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_epoll_create(flags);
}
@@ -2116,6 +2121,9 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, in
struct epoll_event epds;
struct eventpoll *tep = NULL;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
error = -EFAULT;
if (ep_op_has_event(op) &&
copy_from_user(&epds, event, sizeof(struct epoll_event)))
@@ -2306,6 +2314,9 @@ error_fput:
SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,
int, maxevents, int, timeout)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_epoll_wait(epfd, events, maxevents, timeout);
}
@@ -2319,6 +2330,9 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd,
{
int error;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
/*
* If the caller wants a certain signal mask to be set during the wait,
* we apply it here.
diff -ruNp linux-5.4.42/fs/exec.c linux-5.4.42-cher1/fs/exec.c
--- linux-5.4.42/fs/exec.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/exec.c 2020-08-20 14:57:53.388888628 +0300
@@ -73,6 +73,8 @@
#include <trace/events/sched.h>
+#include <linux/sched.h>
+
int suid_dumpable = 0;
static LIST_HEAD(formats);
@@ -134,6 +136,11 @@ SYSCALL_DEFINE1(uselib, const char __use
if (IS_ERR(tmp))
goto out;
+ if (SBOX_IS_RESTRICTED()) {
+ putname(tmp);
+ return -EPERM;
+ }
+
file = do_filp_open(AT_FDCWD, tmp, &uselib_flags);
putname(tmp);
error = PTR_ERR(file);
@@ -1725,6 +1732,15 @@ static int __do_execve_file(int fd, stru
struct files_struct *displaced;
int retval;
+ if (SBOX_IS_RESTRICTED() && fd != AT_FDCWD) {
+ retval = -EPERM;
+ goto out_ret;
+ }
+ if ((current->sbox_flags & SBOX_NO_EXEC)) {
+ SBOX_SET_SECURITY_ERR();
+ goto out_ret;
+ }
+
if (IS_ERR(filename))
return PTR_ERR(filename);
@@ -1835,6 +1851,9 @@ static int __do_execve_file(int fd, stru
putname(filename);
if (displaced)
put_files_struct(displaced);
+ if ((current->sbox_flags & SBOX_NO_SYSCALLS)) {
+ current->sbox_flags |= SBOX_NO_EXEC;
+ }
return retval;
out:
@@ -1855,6 +1874,11 @@ out_files:
if (displaced)
reset_files_struct(displaced);
out_ret:
+ if (retval == -ENOMEM) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
+ }
if (filename)
putname(filename);
return retval;
diff -ruNp linux-5.4.42/fs/fcntl.c linux-5.4.42-cher1/fs/fcntl.c
--- linux-5.4.42/fs/fcntl.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/fcntl.c 2020-08-22 11:06:45.936716094 +0300
@@ -30,6 +30,8 @@
#include <asm/siginfo.h>
#include <linux/uaccess.h>
+#include <linux/sched.h>
+
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
static int setfl(int fd, struct file * filp, unsigned long arg)
@@ -452,6 +454,11 @@ SYSCALL_DEFINE3(fcntl, unsigned int, fd,
if (!f.file)
goto out;
+
+ if (SBOX_IS_RESTRICTED() && !check_fcntl_cmd(cmd)) {
+ err = -EPERM;
+ goto out1;
+ }
if (unlikely(f.file->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd))
@@ -480,6 +487,11 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
if (!f.file)
goto out;
+ if (SBOX_IS_RESTRICTED() && !check_fcntl_cmd(cmd)) {
+ err = -EPERM;
+ goto out1;
+ }
+
if (unlikely(f.file->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd))
goto out1;
@@ -675,6 +687,9 @@ out_put:
COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
compat_ulong_t, arg)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_compat_fcntl64(fd, cmd, arg);
}
diff -ruNp linux-5.4.42/fs/fhandle.c linux-5.4.42-cher1/fs/fhandle.c
--- linux-5.4.42/fs/fhandle.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/fhandle.c 2020-08-22 11:25:58.704983795 +0300
@@ -14,6 +14,8 @@
#include "internal.h"
#include "mount.h"
+#include <linux/sched.h>
+
static long do_sys_name_to_handle(struct path *path,
struct file_handle __user *ufh,
int __user *mnt_id)
@@ -98,6 +100,11 @@ SYSCALL_DEFINE5(name_to_handle_at, int,
int lookup_flags;
int err;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if ((flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
return -EINVAL;
@@ -259,6 +266,11 @@ SYSCALL_DEFINE3(open_by_handle_at, int,
{
long ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (force_o_largefile())
flags |= O_LARGEFILE;
@@ -274,6 +286,11 @@ SYSCALL_DEFINE3(open_by_handle_at, int,
COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd,
struct file_handle __user *, handle, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_handle_open(mountdirfd, handle, flags);
}
#endif
diff -ruNp linux-5.4.42/fs/filesystems.c linux-5.4.42-cher1/fs/filesystems.c
--- linux-5.4.42/fs/filesystems.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/filesystems.c 2020-08-20 15:10:23.905866453 +0300
@@ -18,6 +18,8 @@
#include <linux/uaccess.h>
#include <linux/fs_parser.h>
+#include <linux/sched.h>
+
/*
* Handling of filesystem drivers list.
* Rules:
@@ -191,6 +193,11 @@ SYSCALL_DEFINE3(sysfs, int, option, unsi
{
int retval = -EINVAL;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
switch (option) {
case 1:
retval = fs_index((const char __user *) arg1);
diff -ruNp linux-5.4.42/fs/ioctl.c linux-5.4.42-cher1/fs/ioctl.c
--- linux-5.4.42/fs/ioctl.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/ioctl.c 2020-08-20 15:13:54.805405855 +0300
@@ -23,6 +23,8 @@
#include <asm/ioctls.h>
+#include <linux/sched.h>
+
/* So that the fiemap access checks can't overflow on 32 bit machines. */
#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
@@ -709,6 +711,12 @@ int ksys_ioctl(unsigned int fd, unsigned
if (!f.file)
return -EBADF;
+
+ if (SBOX_IS_RESTRICTED() && cmd != FIOCLEX && cmd != FIONCLEX) {
+ fdput(f);
+ return -EPERM;
+ }
+
error = security_file_ioctl(f.file, cmd, arg);
if (!error)
error = do_vfs_ioctl(f.file, fd, cmd, arg);
diff -ruNp linux-5.4.42/fs/locks.c linux-5.4.42-cher1/fs/locks.c
--- linux-5.4.42/fs/locks.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/locks.c 2020-08-20 15:16:59.065064925 +0300
@@ -169,6 +169,8 @@
#include <linux/hashtable.h>
#include <linux/percpu.h>
+#include <linux/sched.h>
+
#define CREATE_TRACE_POINTS
#include <trace/events/filelock.h>
@@ -2222,6 +2224,11 @@ SYSCALL_DEFINE2(flock, unsigned int, fd,
error = -EBADF;
if (!f.file)
goto out;
+
+ if (SBOX_IS_RESTRICTED()) {
+ fdput(f);
+ return -EPERM;
+ }
can_sleep = !(cmd & LOCK_NB);
cmd &= ~LOCK_NB;
diff -ruNp linux-5.4.42/fs/namei.c linux-5.4.42-cher1/fs/namei.c
--- linux-5.4.42/fs/namei.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/namei.c 2020-08-20 16:14:24.724956628 +0300
@@ -43,6 +43,8 @@
#include "internal.h"
#include "mount.h"
+#include <linux/sched.h>
+
/* [Feb-1997 T. Schoebel-Theuer]
* Fundamental changes in the pathname lookup mechanisms (namei)
* were necessary because of omirr. The reason is that omirr needs
@@ -3780,6 +3782,11 @@ out:
SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
unsigned int, dev)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_mknodat(dfd, filename, mode, dev);
}
@@ -3841,6 +3848,11 @@ retry:
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_mkdirat(dfd, pathname, mode);
}
@@ -3950,6 +3962,9 @@ exit1:
SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
return do_rmdir(AT_FDCWD, pathname);
}
@@ -4091,6 +4106,10 @@ slashes:
SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
if ((flag & ~AT_REMOVEDIR) != 0)
return -EINVAL;
@@ -4102,6 +4121,10 @@ SYSCALL_DEFINE3(unlinkat, int, dfd, cons
SYSCALL_DEFINE1(unlink, const char __user *, pathname)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
return do_unlinkat(AT_FDCWD, getname(pathname));
}
@@ -4160,6 +4183,10 @@ out_putname:
SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
int, newdfd, const char __user *, newname)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
return do_symlinkat(oldname, newdfd, newname);
}
@@ -4325,6 +4352,10 @@ out:
SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
return do_linkat(olddfd, oldname, newdfd, newname, flags);
}
@@ -4654,6 +4685,10 @@ exit:
SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname, unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
return do_renameat2(olddfd, oldname, newdfd, newname, flags);
}
diff -ruNp linux-5.4.42/fs/namespace.c linux-5.4.42-cher1/fs/namespace.c
--- linux-5.4.42/fs/namespace.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/namespace.c 2020-08-20 15:31:38.306678520 +0300
@@ -34,6 +34,8 @@
#include "pnode.h"
#include "internal.h"
+#include <linux/sched.h>
+
/* Maximum number of mounts in a mount namespace */
unsigned int sysctl_mount_max __read_mostly = 100000;
@@ -1706,6 +1708,11 @@ out:
SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_umount(name, flags);
}
@@ -3362,6 +3369,11 @@ out_type:
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
char __user *, type, unsigned long, flags, void __user *, data)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_mount(dev_name, dir_name, type, flags, data);
}
@@ -3621,6 +3633,11 @@ SYSCALL_DEFINE2(pivot_root, const char _
struct mountpoint *old_mp, *root_mp;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!may_mount())
return -EPERM;
diff -ruNp linux-5.4.42/fs/notify/fanotify/fanotify_user.c linux-5.4.42-cher1/fs/notify/fanotify/fanotify_user.c
--- linux-5.4.42/fs/notify/fanotify/fanotify_user.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/notify/fanotify/fanotify_user.c 2020-08-20 15:36:43.126655871 +0300
@@ -26,6 +26,8 @@
#include "../fdinfo.h"
#include "fanotify.h"
+#include <linux/sched.h>
+
#define FANOTIFY_DEFAULT_MAX_EVENTS 16384
#define FANOTIFY_DEFAULT_MAX_MARKS 8192
#define FANOTIFY_DEFAULT_MAX_LISTENERS 128
@@ -770,6 +772,9 @@ SYSCALL_DEFINE2(fanotify_init, unsigned
struct user_struct *user;
struct fanotify_event *oevent;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
pr_debug("%s: flags=%x event_f_flags=%x\n",
__func__, flags, event_f_flags);
@@ -1108,6 +1113,9 @@ SYSCALL_DEFINE5(fanotify_mark, int, fano
__u64, mask, int, dfd,
const char __user *, pathname)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname);
}
diff -ruNp linux-5.4.42/fs/notify/inotify/inotify_user.c linux-5.4.42-cher1/fs/notify/inotify/inotify_user.c
--- linux-5.4.42/fs/notify/inotify/inotify_user.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/notify/inotify/inotify_user.c 2020-08-20 15:40:47.156722406 +0300
@@ -37,6 +37,8 @@
#include <asm/ioctls.h>
+#include <linux/sched.h>
+
/* configurable via /proc/sys/fs/inotify/ */
static int inotify_max_queued_events __read_mostly;
@@ -687,6 +689,9 @@ static int do_inotify_init(int flags)
SYSCALL_DEFINE1(inotify_init1, int, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_inotify_init(flags);
}
@@ -705,6 +710,9 @@ SYSCALL_DEFINE3(inotify_add_watch, int,
int ret;
unsigned flags = 0;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
/*
* We share a lot of code with fs/dnotify. We also share
* the bit layout between inotify's IN_* and the fsnotify
@@ -766,6 +774,9 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, f
struct fd f;
int ret = 0;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
f = fdget(fd);
if (unlikely(!f.file))
return -EBADF;
diff -ruNp linux-5.4.42/fs/open.c linux-5.4.42-cher1/fs/open.c
--- linux-5.4.42/fs/open.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/open.c 2020-08-23 18:19:09.663920955 +0300
@@ -33,8 +33,61 @@
#include <linux/dnotify.h>
#include <linux/compat.h>
+#include <linux/sched.h>
+
#include "internal.h"
+static const char * const secure_paths[] =
+{
+ "/lib/", "/lib32/", "/lib64/", "/lib/x86_64-linux-gnu/",
+ "/usr/lib/", "/usr/lib32/", "/usr/lib64/", "/usr/lib/x86_64-linux-gnu/",
+ "/usr/include/", "/usr/libexec/",
+ "/usr/local/lib/", "/usr/local/lib32/", "/usr/local/lib64/", "/usr/local/lib/x86_64-linux-gnu/",
+ "/usr/local/include/", "/usr/local/libexec/",
+ "/bin/", "/usr/bin/", "/usr/local/bin/",
+ "/usr/share/", "/usr/local/share/", "/dev/urandom", "/dev/zero", "/dev/null",
+ "/etc/localtime",
+ "/proc/self/exe",
+ "/proc/self/personality",
+// "/proc/self/", -- insecure!!!
+ NULL
+};
+
+int cher_patch_is_secure_path(const char *path)
+{
+ const char *s;
+ int i;
+
+ if (strstr(path, ".."))
+ return -1;
+ for (i = 0; secure_paths[i] && strncmp(path, secure_paths[i], strlen(secure_paths[i])); ++i);
+ if (secure_paths[i]) {
+ return 0;
+ }
+
+ if (!strncmp(path, "/SANDBOX/", 9)) path += 9;
+ s = path;
+ while (s[0] == '.' && s[1] == '/') s += 2;
+ for (; *s && *s != '/'; s++);
+ if (*s == '/') return -1;
+ return 0;
+}
+
+int cher_check_user_path(int dfd, const char __user **p_path)
+{
+ struct filename *tmp = NULL;
+ if (dfd != AT_FDCWD) return -EPERM;
+ tmp = getname(*p_path);
+ if (IS_ERR(tmp)) return -EINVAL;
+ if (cher_patch_is_secure_path(tmp->name) < 0) {
+ putname(tmp);
+ return -EPERM;
+ }
+ if (!strncmp("/SANDBOX/", tmp->name, 9)) *p_path += 9;
+ putname(tmp);
+ return 0;
+}
+
int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
struct file *filp)
{
@@ -142,12 +195,18 @@ retry:
SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_sys_truncate(path, length);
}
#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_sys_truncate(path, length);
}
#endif
@@ -216,11 +275,17 @@ COMPAT_SYSCALL_DEFINE2(ftruncate, unsign
#if BITS_PER_LONG == 32
SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_sys_truncate(path, length);
}
SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_sys_ftruncate(fd, length, 0);
}
#endif /* BITS_PER_LONG == 32 */
@@ -325,9 +390,13 @@ EXPORT_SYMBOL_GPL(vfs_fallocate);
int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len)
{
- struct fd f = fdget(fd);
+ struct fd f;
int error = -EBADF;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ f = fdget(fd);
if (f.file) {
error = vfs_fallocate(f.file, mode, offset, len);
fdput(f);
@@ -354,6 +423,11 @@ long do_faccessat(int dfd, const char __
int res;
unsigned int lookup_flags = LOOKUP_FOLLOW;
+ if (SBOX_IS_RESTRICTED()) {
+ res = cher_check_user_path(dfd, &filename);
+ if (res < 0) return res;
+ }
+
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
return -EINVAL;
@@ -478,6 +552,9 @@ out:
SYSCALL_DEFINE1(chdir, const char __user *, filename)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return ksys_chdir(filename);
}
@@ -490,6 +567,11 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
if (!f.file)
goto out;
+ if (SBOX_IS_RESTRICTED()) {
+ error = -EPERM;
+ goto out_putf;
+ }
+
error = -ENOTDIR;
if (!d_can_lookup(f.file->f_path.dentry))
goto out_putf;
@@ -538,6 +620,11 @@ out:
SYSCALL_DEFINE1(chroot, const char __user *, filename)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_chroot(filename);
}
@@ -572,9 +659,15 @@ out_unlock:
int ksys_fchmod(unsigned int fd, umode_t mode)
{
- struct fd f = fdget(fd);
+ struct fd f;
int err = -EBADF;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ f = fdget(fd);
if (f.file) {
audit_file(f.file);
err = chmod_common(&f.file->f_path, mode);
@@ -609,6 +702,11 @@ retry:
SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename,
umode_t, mode)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_fchmodat(dfd, filename, mode);
}
@@ -694,6 +792,11 @@ out:
SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
gid_t, group, int, flag)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_fchownat(dfd, filename, user, group, flag);
}
@@ -716,6 +819,12 @@ int ksys_fchown(unsigned int fd, uid_t u
if (!f.file)
goto out;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ error = -EPERM;
+ goto out_fput;
+ }
+
error = mnt_want_write_file(f.file);
if (error)
goto out_fput;
@@ -1079,9 +1188,16 @@ EXPORT_SYMBOL(file_open_root);
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;
- int fd = build_open_flags(flags, mode, &op);
+ int fd = 0;
struct filename *tmp;
+ if (SBOX_IS_RESTRICTED()) {
+ int res = cher_check_user_path(dfd, &filename);
+ if (res < 0) return res;
+ flags &= ~(O_CREAT | O_EXCL);
+ }
+
+ fd = build_open_flags(flags, mode, &op);
if (fd)
return fd;
@@ -1137,6 +1253,10 @@ COMPAT_SYSCALL_DEFINE3(open, const char
*/
COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
return do_sys_open(dfd, filename, flags, mode);
}
#endif
@@ -1205,6 +1325,9 @@ SYSCALL_DEFINE1(close, unsigned int, fd)
*/
SYSCALL_DEFINE0(vhangup)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (capable(CAP_SYS_TTY_CONFIG)) {
tty_vhangup_self();
return 0;
diff -ruNp linux-5.4.42/fs/pipe.c linux-5.4.42-cher1/fs/pipe.c
--- linux-5.4.42/fs/pipe.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/pipe.c 2020-08-20 17:33:51.652901453 +0300
@@ -28,6 +28,8 @@
#include <linux/uaccess.h>
#include <asm/ioctls.h>
+#include <linux/sched.h>
+
#include "internal.h"
/*
@@ -870,6 +872,11 @@ static int do_pipe2(int __user *fildes,
SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_pipe2(fildes, flags);
}
diff -ruNp linux-5.4.42/fs/quota/compat.c linux-5.4.42-cher1/fs/quota/compat.c
--- linux-5.4.42/fs/quota/compat.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/quota/compat.c 2020-08-20 17:38:19.933165236 +0300
@@ -4,6 +4,8 @@
#include <linux/compat.h>
#include <linux/quotaops.h>
+#include <linux/sched.h>
+
/*
* This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
* and is necessary due to alignment problems.
@@ -54,6 +56,11 @@ COMPAT_SYSCALL_DEFINE4(quotactl32, unsig
u16 xdata;
long ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
cmds = cmd >> SUBCMDSHIFT;
switch (cmds) {
diff -ruNp linux-5.4.42/fs/quota/quota.c linux-5.4.42-cher1/fs/quota/quota.c
--- linux-5.4.42/fs/quota/quota.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/quota/quota.c 2020-08-20 17:40:15.493256333 +0300
@@ -20,6 +20,8 @@
#include <linux/writeback.h>
#include <linux/nospec.h>
+#include <linux/sched.h>
+
static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
qid_t id)
{
@@ -876,5 +878,10 @@ out:
SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
qid_t, id, void __user *, addr)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return kernel_quotactl(cmd, special, id, addr);
}
diff -ruNp linux-5.4.42/fs/read_write.c linux-5.4.42-cher1/fs/read_write.c
--- linux-5.4.42/fs/read_write.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/read_write.c 2020-08-20 18:11:04.511848282 +0300
@@ -25,6 +25,8 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#include <linux/sched.h>
+
const struct file_operations generic_ro_fops = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -646,6 +648,9 @@ ssize_t ksys_pread64(unsigned int fd, ch
SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
size_t, count, loff_t, pos)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return ksys_pread64(fd, buf, count, pos);
}
@@ -672,6 +677,9 @@ ssize_t ksys_pwrite64(unsigned int fd, c
SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
size_t, count, loff_t, pos)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return ksys_pwrite64(fd, buf, count, pos);
}
@@ -1079,6 +1087,9 @@ static ssize_t do_preadv(unsigned long f
struct fd f;
ssize_t ret = -EBADF;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (pos < 0)
return -EINVAL;
@@ -1102,6 +1113,9 @@ static ssize_t do_pwritev(unsigned long
struct fd f;
ssize_t ret = -EBADF;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (pos < 0)
return -EINVAL;
@@ -1134,6 +1148,10 @@ SYSCALL_DEFINE3(writev, unsigned long, f
SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
loff_t pos = pos_from_hilo(pos_h, pos_l);
return do_preadv(fd, vec, vlen, pos, 0);
@@ -1143,6 +1161,10 @@ SYSCALL_DEFINE6(preadv2, unsigned long,
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
rwf_t, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
loff_t pos = pos_from_hilo(pos_h, pos_l);
if (pos == -1)
@@ -1154,6 +1176,9 @@ SYSCALL_DEFINE6(preadv2, unsigned long,
SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
loff_t pos = pos_from_hilo(pos_h, pos_l);
return do_pwritev(fd, vec, vlen, pos, 0);
@@ -1163,6 +1188,9 @@ SYSCALL_DEFINE6(pwritev2, unsigned long,
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
rwf_t, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
loff_t pos = pos_from_hilo(pos_h, pos_l);
if (pos == -1)
@@ -1225,6 +1253,9 @@ static long do_compat_preadv64(unsigned
struct fd f;
ssize_t ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (pos < 0)
return -EINVAL;
f = fdget(fd);
@@ -1334,6 +1365,9 @@ static long do_compat_pwritev64(unsigned
struct fd f;
ssize_t ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (pos < 0)
return -EINVAL;
f = fdget(fd);
diff -ruNp linux-5.4.42/fs/select.c linux-5.4.42-cher1/fs/select.c
--- linux-5.4.42/fs/select.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/select.c 2020-08-22 11:24:30.344890366 +0300
@@ -34,7 +34,6 @@
#include <linux/uaccess.h>
-
/*
* Estimate expected accuracy in ns from a timeval.
*
diff -ruNp linux-5.4.42/fs/signalfd.c linux-5.4.42-cher1/fs/signalfd.c
--- linux-5.4.42/fs/signalfd.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/signalfd.c 2020-08-20 18:15:40.143577264 +0300
@@ -33,6 +33,8 @@
#include <linux/proc_fs.h>
#include <linux/compat.h>
+#include <linux/sched.h>
+
void signalfd_cleanup(struct sighand_struct *sighand)
{
wait_queue_head_t *wqh = &sighand->signalfd_wqh;
@@ -314,6 +316,9 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sig
{
sigset_t mask;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (sizemask != sizeof(sigset_t) ||
copy_from_user(&mask, user_mask, sizeof(mask)))
return -EINVAL;
@@ -350,6 +355,9 @@ COMPAT_SYSCALL_DEFINE4(signalfd4, int, u
compat_size_t, sigsetsize,
int, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_compat_signalfd4(ufd, user_mask, sigsetsize, flags);
}
diff -ruNp linux-5.4.42/fs/splice.c linux-5.4.42-cher1/fs/splice.c
--- linux-5.4.42/fs/splice.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/splice.c 2020-08-20 18:26:24.890045238 +0300
@@ -36,6 +36,8 @@
#include <linux/compat.h>
#include <linux/sched/signal.h>
+#include <linux/sched.h>
+
#include "internal.h"
/*
@@ -1368,6 +1370,9 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const
struct fd f;
int type;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
f = fdget(fd);
error = vmsplice_type(f, &type);
if (error)
@@ -1394,6 +1399,9 @@ COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd
struct fd f;
int type;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
f = fdget(fd);
error = vmsplice_type(f, &type);
if (error)
@@ -1417,6 +1425,9 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff
struct fd in, out;
long error;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (unlikely(!len))
return 0;
@@ -1766,6 +1777,9 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdo
struct fd in;
int error;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL;
diff -ruNp linux-5.4.42/fs/stat.c linux-5.4.42-cher1/fs/stat.c
--- linux-5.4.42/fs/stat.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/stat.c 2020-08-22 10:54:13.092445033 +0300
@@ -21,6 +21,10 @@
#include <linux/uaccess.h>
#include <asm/unistd.h>
+#include <linux/sched.h>
+
+int cher_check_user_path(int dfd, const char __user **p_path);
+
/**
* generic_fillattr - Fill in the basic attributes from the inode struct
* @inode: Inode to use as the source
@@ -249,6 +253,11 @@ SYSCALL_DEFINE2(stat, const char __user
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(AT_FDCWD, &filename);
+ if (error < 0) return error;
+ }
+
error = vfs_stat(filename, &stat);
if (error)
return error;
@@ -262,6 +271,11 @@ SYSCALL_DEFINE2(lstat, const char __user
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(AT_FDCWD, &filename);
+ if (error < 0) return error;
+ }
+
error = vfs_lstat(filename, &stat);
if (error)
return error;
@@ -338,8 +352,14 @@ SYSCALL_DEFINE2(newstat, const char __us
struct stat __user *, statbuf)
{
struct kstat stat;
- int error = vfs_stat(filename, &stat);
+ int error;
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(AT_FDCWD, &filename);
+ if (error < 0) return error;
+ }
+
+ error = vfs_stat(filename, &stat);
if (error)
return error;
return cp_new_stat(&stat, statbuf);
@@ -351,6 +371,11 @@ SYSCALL_DEFINE2(newlstat, const char __u
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(AT_FDCWD, &filename);
+ if (error < 0) return error;
+ }
+
error = vfs_lstat(filename, &stat);
if (error)
return error;
@@ -365,6 +390,11 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, co
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(dfd, &filename);
+ if (error < 0) return error;
+ }
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
@@ -392,6 +422,11 @@ static int do_readlinkat(int dfd, const
int empty = 0;
unsigned int lookup_flags = LOOKUP_EMPTY;
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(dfd, &pathname);
+ if (error < 0) return error;
+ }
+
if (bufsiz <= 0)
return -EINVAL;
@@ -479,8 +514,14 @@ SYSCALL_DEFINE2(stat64, const char __use
struct stat64 __user *, statbuf)
{
struct kstat stat;
- int error = vfs_stat(filename, &stat);
+ int error;
+
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(AT_FDCWD, &filename);
+ if (error < 0) return error;
+ }
+ error = vfs_stat(filename, &stat);
if (!error)
error = cp_new_stat64(&stat, statbuf);
@@ -491,8 +532,14 @@ SYSCALL_DEFINE2(lstat64, const char __us
struct stat64 __user *, statbuf)
{
struct kstat stat;
- int error = vfs_lstat(filename, &stat);
+ int error;
+
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(AT_FDCWD, &filename);
+ if (error < 0) return error;
+ }
+ error = vfs_lstat(filename, &stat);
if (!error)
error = cp_new_stat64(&stat, statbuf);
@@ -516,6 +563,11 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, con
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ error = cher_check_user_path(dfd, &filename);
+ if (error < 0) return error;
+ }
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
@@ -622,12 +674,25 @@ static int cp_compat_stat(struct kstat *
return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
+int cher_patch_is_secure_path(const char*);
+
COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,
struct compat_stat __user *, statbuf)
{
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ struct filename *tmp = getname(filename);
+ if (IS_ERR(tmp)) return -EINVAL;
+ if (cher_patch_is_secure_path(tmp->name) < 0) {
+ putname(tmp);
+ return -EPERM;
+ }
+ if (!strncmp(tmp->name, "/SANDBOX/", 9)) filename += 9;
+ putname(tmp);
+ }
+
error = vfs_stat(filename, &stat);
if (error)
return error;
@@ -640,6 +705,17 @@ COMPAT_SYSCALL_DEFINE2(newlstat, const c
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ struct filename *tmp = getname(filename);
+ if (IS_ERR(tmp)) return -EINVAL;
+ if (cher_patch_is_secure_path(tmp->name) < 0) {
+ putname(tmp);
+ return -EPERM;
+ }
+ if (!strncmp(tmp->name, "/SANDBOX/", 9)) filename += 9;
+ putname(tmp);
+ }
+
error = vfs_lstat(filename, &stat);
if (error)
return error;
@@ -654,6 +730,9 @@ COMPAT_SYSCALL_DEFINE4(newfstatat, unsig
struct kstat stat;
int error;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
diff -ruNp linux-5.4.42/fs/statfs.c linux-5.4.42-cher1/fs/statfs.c
--- linux-5.4.42/fs/statfs.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/statfs.c 2020-08-22 11:03:49.300511224 +0300
@@ -9,6 +9,7 @@
#include <linux/security.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
+#include <linux/sched.h>
#include "internal.h"
static int flags_by_mnt(int mnt_flags)
@@ -190,7 +191,12 @@ static int do_statfs64(struct kstatfs *s
SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf)
{
struct kstatfs st;
- int error = user_statfs(pathname, &st);
+ int error;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ error = user_statfs(pathname, &st);
if (!error)
error = do_statfs_native(&st, buf);
return error;
@@ -200,6 +206,10 @@ SYSCALL_DEFINE3(statfs64, const char __u
{
struct kstatfs st;
int error;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (sz != sizeof(*buf))
return -EINVAL;
error = user_statfs(pathname, &st);
@@ -211,7 +221,12 @@ SYSCALL_DEFINE3(statfs64, const char __u
SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf)
{
struct kstatfs st;
- int error = fd_statfs(fd, &st);
+ int error;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ error = fd_statfs(fd, &st);
if (!error)
error = do_statfs_native(&st, buf);
return error;
@@ -222,6 +237,9 @@ SYSCALL_DEFINE3(fstatfs64, unsigned int,
struct kstatfs st;
int error;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (sz != sizeof(*buf))
return -EINVAL;
@@ -247,7 +265,12 @@ SYSCALL_DEFINE2(ustat, unsigned, dev, st
{
struct ustat tmp;
struct kstatfs sbuf;
- int err = vfs_ustat(new_decode_dev(dev), &sbuf);
+ int err;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ err = vfs_ustat(new_decode_dev(dev), &sbuf);
if (err)
return err;
@@ -300,7 +323,12 @@ static int put_compat_statfs(struct comp
COMPAT_SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct compat_statfs __user *, buf)
{
struct kstatfs tmp;
- int error = user_statfs(pathname, &tmp);
+ int error;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ error = user_statfs(pathname, &tmp);
if (!error)
error = put_compat_statfs(buf, &tmp);
return error;
@@ -309,7 +337,12 @@ COMPAT_SYSCALL_DEFINE2(statfs, const cha
COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *, buf)
{
struct kstatfs tmp;
- int error = fd_statfs(fd, &tmp);
+ int error;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ error = fd_statfs(fd, &tmp);
if (!error)
error = put_compat_statfs(buf, &tmp);
return error;
@@ -356,6 +389,9 @@ int kcompat_sys_statfs64(const char __us
COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, sz, struct compat_statfs64 __user *, buf)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return kcompat_sys_statfs64(pathname, sz, buf);
}
@@ -375,6 +411,9 @@ int kcompat_sys_fstatfs64(unsigned int f
COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct compat_statfs64 __user *, buf)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return kcompat_sys_fstatfs64(fd, sz, buf);
}
@@ -387,7 +426,12 @@ COMPAT_SYSCALL_DEFINE2(ustat, unsigned,
{
struct compat_ustat tmp;
struct kstatfs sbuf;
- int err = vfs_ustat(new_decode_dev(dev), &sbuf);
+ int err;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ err = vfs_ustat(new_decode_dev(dev), &sbuf);
if (err)
return err;
diff -ruNp linux-5.4.42/fs/sync.c linux-5.4.42-cher1/fs/sync.c
--- linux-5.4.42/fs/sync.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/sync.c 2020-08-20 21:52:39.543197872 +0300
@@ -121,6 +121,9 @@ void ksys_sync(void)
SYSCALL_DEFINE0(sync)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
ksys_sync();
return 0;
}
@@ -159,10 +162,14 @@ void emergency_sync(void)
*/
SYSCALL_DEFINE1(syncfs, int, fd)
{
- struct fd f = fdget(fd);
+ struct fd f;
struct super_block *sb;
int ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ f = fdget(fd);
if (!f.file)
return -EBADF;
sb = f.file->f_path.dentry->d_sb;
@@ -226,11 +233,17 @@ static int do_fsync(unsigned int fd, int
SYSCALL_DEFINE1(fsync, unsigned int, fd)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_fsync(fd, 0);
}
SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_fsync(fd, 1);
}
@@ -379,6 +392,9 @@ int ksys_sync_file_range(int fd, loff_t
SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes,
unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return ksys_sync_file_range(fd, offset, nbytes, flags);
}
diff -ruNp linux-5.4.42/fs/timerfd.c linux-5.4.42-cher1/fs/timerfd.c
--- linux-5.4.42/fs/timerfd.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/timerfd.c 2020-08-20 22:08:53.982521717 +0300
@@ -389,6 +389,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clo
int ufd;
struct timerfd_ctx *ctx;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
/* Check the TFD_* constants for consistency. */
BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK);
@@ -542,6 +545,9 @@ SYSCALL_DEFINE4(timerfd_settime, int, uf
{
struct itimerspec64 new, old;
int ret;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
if (get_itimerspec64(&new, utmr))
return -EFAULT;
@@ -557,7 +563,12 @@ SYSCALL_DEFINE4(timerfd_settime, int, uf
SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct __kernel_itimerspec __user *, otmr)
{
struct itimerspec64 kotmr;
- int ret = do_timerfd_gettime(ufd, &kotmr);
+ int ret;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ ret = do_timerfd_gettime(ufd, &kotmr);
if (ret)
return ret;
return put_itimerspec64(&kotmr, otmr) ? -EFAULT : 0;
@@ -571,6 +582,9 @@ SYSCALL_DEFINE4(timerfd_settime32, int,
struct itimerspec64 new, old;
int ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (get_old_itimerspec32(&new, utmr))
return -EFAULT;
ret = do_timerfd_settime(ufd, flags, &new, &old);
@@ -585,7 +599,12 @@ SYSCALL_DEFINE2(timerfd_gettime32, int,
struct old_itimerspec32 __user *, otmr)
{
struct itimerspec64 kotmr;
- int ret = do_timerfd_gettime(ufd, &kotmr);
+ int ret;
+
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
+ ret = do_timerfd_gettime(ufd, &kotmr);
if (ret)
return ret;
return put_old_itimerspec32(&kotmr, otmr) ? -EFAULT : 0;
diff -ruNp linux-5.4.42/fs/userfaultfd.c linux-5.4.42-cher1/fs/userfaultfd.c
--- linux-5.4.42/fs/userfaultfd.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/userfaultfd.c 2020-08-20 22:13:22.382264040 +0300
@@ -28,6 +28,8 @@
#include <linux/security.h>
#include <linux/hugetlb.h>
+#include <linux/sched.h>
+
int sysctl_unprivileged_userfaultfd __read_mostly = 1;
static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly;
@@ -1947,6 +1949,11 @@ SYSCALL_DEFINE1(userfaultfd, int, flags)
struct userfaultfd_ctx *ctx;
int fd;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!sysctl_unprivileged_userfaultfd && !capable(CAP_SYS_PTRACE))
return -EPERM;
diff -ruNp linux-5.4.42/fs/utimes.c linux-5.4.42-cher1/fs/utimes.c
--- linux-5.4.42/fs/utimes.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/utimes.c 2020-08-22 10:48:10.773396951 +0300
@@ -8,6 +8,8 @@
#include <linux/compat.h>
#include <asm/unistd.h>
+#include <linux/sched.h>
+
static bool nsec_valid(long nsec)
{
if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
@@ -139,6 +141,9 @@ SYSCALL_DEFINE4(utimensat, int, dfd, con
{
struct timespec64 tstimes[2];
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (utimes) {
if ((get_timespec64(&tstimes[0], &utimes[0]) ||
get_timespec64(&tstimes[1], &utimes[1])))
@@ -192,6 +197,9 @@ static long do_futimesat(int dfd, const
SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename,
struct timeval __user *, utimes)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_futimesat(dfd, filename, utimes);
}
@@ -205,6 +213,9 @@ SYSCALL_DEFINE2(utime, char __user *, fi
{
struct timespec64 tv[2];
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (times) {
if (get_user(tv[0].tv_sec, &times->actime) ||
get_user(tv[1].tv_sec, &times->modtime))
@@ -227,6 +238,11 @@ SYSCALL_DEFINE2(utime32, const char __us
{
struct timespec64 tv[2];
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (t) {
if (get_user(tv[0].tv_sec, &t->actime) ||
get_user(tv[1].tv_sec, &t->modtime))
@@ -242,6 +258,11 @@ SYSCALL_DEFINE4(utimensat_time32, unsign
{
struct timespec64 tv[2];
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (t) {
if (get_old_timespec32(&tv[0], &t[0]) ||
get_old_timespec32(&tv[1], &t[1]))
@@ -278,6 +299,11 @@ SYSCALL_DEFINE3(futimesat_time32, unsign
const char __user *, filename,
struct old_timeval32 __user *, t)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_compat_futimesat(dfd, filename, t);
}
diff -ruNp linux-5.4.42/fs/xattr.c linux-5.4.42-cher1/fs/xattr.c
--- linux-5.4.42/fs/xattr.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/fs/xattr.c 2020-08-20 22:38:45.812900157 +0300
@@ -22,6 +22,7 @@
#include <linux/audit.h>
#include <linux/vmalloc.h>
#include <linux/posix_acl_xattr.h>
+#include <linux/sched.h>
#include <linux/uaccess.h>
@@ -482,6 +483,11 @@ SYSCALL_DEFINE5(setxattr, const char __u
const char __user *, name, const void __user *, value,
size_t, size, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW);
}
@@ -489,15 +495,26 @@ SYSCALL_DEFINE5(lsetxattr, const char __
const char __user *, name, const void __user *, value,
size_t, size, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_setxattr(pathname, name, value, size, flags, 0);
}
SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
const void __user *,value, size_t, size, int, flags)
{
- struct fd f = fdget(fd);
+ struct fd f;
int error = -EBADF;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ f = fdget(fd);
if (!f.file)
return error;
audit_file(f.file);
@@ -575,21 +592,37 @@ retry:
SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
const char __user *, name, void __user *, value, size_t, size)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW);
}
SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
const char __user *, name, void __user *, value, size_t, size)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_getxattr(pathname, name, value, size, 0);
}
SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
void __user *, value, size_t, size)
{
- struct fd f = fdget(fd);
+ struct fd f;
ssize_t error = -EBADF;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ f = fdget(fd);
if (!f.file)
return error;
audit_file(f.file);
@@ -651,20 +684,36 @@ retry:
SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
size_t, size)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_listxattr(pathname, list, size, LOOKUP_FOLLOW);
}
SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
size_t, size)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_listxattr(pathname, list, size, 0);
}
SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
{
- struct fd f = fdget(fd);
+ struct fd f;
ssize_t error = -EBADF;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ f = fdget(fd);
if (!f.file)
return error;
audit_file(f.file);
@@ -716,20 +765,36 @@ retry:
SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
const char __user *, name)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_removexattr(pathname, name, LOOKUP_FOLLOW);
}
SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
const char __user *, name)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return path_removexattr(pathname, name, 0);
}
SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
{
- struct fd f = fdget(fd);
+ struct fd f;
int error = -EBADF;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ f = fdget(fd);
if (!f.file)
return error;
audit_file(f.file);
diff -ruNp linux-5.4.42/include/linux/sched.h linux-5.4.42-cher1/include/linux/sched.h
--- linux-5.4.42/include/linux/sched.h 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/include/linux/sched.h 2020-08-20 11:51:33.567658531 +0300
@@ -621,6 +621,17 @@ struct wake_q_node {
struct wake_q_node *next;
};
+/* sandbox flags */
+enum {
+ SBOX_NO_SYSCALLS = 1, /* disable most "dangerous" syscalls */
+ SBOX_NO_EXEC = 2, /* disable exec syscall */
+ SBOX_MEMLIMITON = 4, /* enable memory limit check */
+ SBOX_WAS_MEMLIMIT = 8, /* memory limit happened? */
+ SBOX_WAS_SECURITY = 16, /* was security violation? */
+ SBOX_TLON = 32, /* enable kernel time limit check */
+ SBOX_WAS_TL = 64 /* was time limit? */
+};
+
struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
@@ -1268,6 +1279,9 @@ struct task_struct {
unsigned long prev_lowest_stack;
#endif
+ /* sandbox flags */
+ int sbox_flags;
+
/*
* New fields for task_struct should be added above here, so that
* they are included in the randomized portion of task_struct.
@@ -1285,6 +1299,14 @@ struct task_struct {
*/
};
+#define SBOX_IS_RESTRICTED() unlikely(current->sbox_flags & SBOX_NO_SYSCALLS)
+#define SBOX_SET_SECURITY_ERR() do { current->sbox_flags |= SBOX_WAS_SECURITY; printk(KERN_ERR "%s: %s: %s: %d: security violation\n", current->comm, __FUNCTION__, __FILE__, __LINE__); } while (0)
+#define SBOX_SET_TL_ERR() (current->sbox_flags |= SBOX_WAS_TL)
+
+#define SBOX_IS_MEMLIMIT_ERR(p) (p->sbox_flags & SBOX_WAS_MEMLIMIT)
+#define SBOX_IS_SECURITY_ERR(p) (p->sbox_flags & SBOX_WAS_SECURITY)
+#define SBOX_IS_TL_ERR(p) (p->sbox_flags & SBOX_WAS_TL)
+
static inline struct pid *task_pid(struct task_struct *task)
{
return task->thread_pid;
diff -ruNp linux-5.4.42/include/uapi/linux/ptrace.h linux-5.4.42-cher1/include/uapi/linux/ptrace.h
--- linux-5.4.42/include/uapi/linux/ptrace.h 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/include/uapi/linux/ptrace.h 2020-08-20 11:54:54.655710275 +0300
@@ -50,6 +50,10 @@
#define PTRACE_GETREGSET 0x4204
#define PTRACE_SETREGSET 0x4205
+#define PTRACE_MEMLIMIT 0x4280
+#define PTRACE_NO_SYSCALLS 0x4281
+#define PTRACE_TIMELIMIT 0x4282
+
#define PTRACE_SEIZE 0x4206
#define PTRACE_INTERRUPT 0x4207
#define PTRACE_LISTEN 0x4208
diff -ruNp linux-5.4.42/ipc/mqueue.c linux-5.4.42-cher1/ipc/mqueue.c
--- linux-5.4.42/ipc/mqueue.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/ipc/mqueue.c 2020-08-20 22:56:48.413227192 +0300
@@ -40,6 +40,8 @@
#include <linux/sched/signal.h>
#include <linux/sched/user.h>
+#include <linux/sched.h>
+
#include <net/sock.h>
#include "util.h"
@@ -865,6 +867,12 @@ SYSCALL_DEFINE4(mq_open, const char __us
struct mq_attr __user *, u_attr)
{
struct mq_attr attr;
+
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
return -EFAULT;
@@ -880,6 +888,11 @@ SYSCALL_DEFINE1(mq_unlink, const char __
struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
struct vfsmount *mnt = ipc_ns->mq_mnt;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
name = getname(u_name);
if (IS_ERR(name))
return PTR_ERR(name);
@@ -1202,6 +1215,12 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqd
const struct __kernel_timespec __user *, u_abs_timeout)
{
struct timespec64 ts, *p = NULL;
+
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (u_abs_timeout) {
int res = prepare_timeout(u_abs_timeout, &ts);
if (res)
@@ -1216,6 +1235,12 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t,
const struct __kernel_timespec __user *, u_abs_timeout)
{
struct timespec64 ts, *p = NULL;
+
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (u_abs_timeout) {
int res = prepare_timeout(u_abs_timeout, &ts);
if (res)
@@ -1357,6 +1382,12 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
const struct sigevent __user *, u_notification)
{
struct sigevent n, *p = NULL;
+
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (u_notification) {
if (copy_from_user(&n, u_notification, sizeof(struct sigevent)))
return -EFAULT;
@@ -1417,6 +1448,11 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mq
struct mq_attr mqstat, omqstat;
struct mq_attr *new = NULL, *old = NULL;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (u_mqstat) {
new = &mqstat;
if (copy_from_user(new, u_mqstat, sizeof(struct mq_attr)))
diff -ruNp linux-5.4.42/ipc/msg.c linux-5.4.42-cher1/ipc/msg.c
--- linux-5.4.42/ipc/msg.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/ipc/msg.c 2020-08-20 23:05:15.816862820 +0300
@@ -40,6 +40,8 @@
#include <linux/ipc_namespace.h>
#include <linux/rhashtable.h>
+#include <linux/sched.h>
+
#include <asm/current.h>
#include <linux/uaccess.h>
#include "util.h"
@@ -292,6 +294,11 @@ long ksys_msgget(key_t key, int msgflg)
SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_msgget(key, msgflg);
}
@@ -612,6 +619,11 @@ static long ksys_msgctl(int msqid, int c
SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_msgctl(msqid, cmd, buf, IPC_64);
}
@@ -940,6 +952,11 @@ long ksys_msgsnd(int msqid, struct msgbu
SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
int, msgflg)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_msgsnd(msqid, msgp, msgsz, msgflg);
}
@@ -1231,6 +1248,11 @@ long ksys_msgrcv(int msqid, struct msgbu
SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
long, msgtyp, int, msgflg)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
}
diff -ruNp linux-5.4.42/ipc/sem.c linux-5.4.42-cher1/ipc/sem.c
--- linux-5.4.42/ipc/sem.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/ipc/sem.c 2020-08-20 23:10:49.992871575 +0300
@@ -88,6 +88,8 @@
#include <linux/nospec.h>
#include <linux/rhashtable.h>
+#include <linux/sched.h>
+
#include <linux/uaccess.h>
#include "util.h"
@@ -602,6 +604,11 @@ long ksys_semget(key_t key, int nsems, i
SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_semget(key, nsems, semflg);
}
@@ -1686,6 +1693,11 @@ static long ksys_semctl(int semid, int s
SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_semctl(semid, semnum, cmd, arg, IPC_64);
}
@@ -2231,6 +2243,11 @@ long ksys_semtimedop(int semid, struct s
SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
unsigned int, nsops, const struct __kernel_timespec __user *, timeout)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_semtimedop(semid, tsops, nsops, timeout);
}
diff -ruNp linux-5.4.42/ipc/shm.c linux-5.4.42-cher1/ipc/shm.c
--- linux-5.4.42/ipc/shm.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/ipc/shm.c 2020-08-20 23:21:42.569107744 +0300
@@ -45,6 +45,8 @@
#include <linux/ipc_namespace.h>
#include <linux/rhashtable.h>
+#include <linux/sched.h>
+
#include <linux/uaccess.h>
#include "util.h"
@@ -744,6 +746,11 @@ long ksys_shmget(key_t key, size_t size,
SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_shmget(key, size, shmflg);
}
@@ -1146,6 +1153,11 @@ static long ksys_shmctl(int shmid, int c
if (cmd < 0 || shmid < 0)
return -EINVAL;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
ns = current->nsproxy->ipc_ns;
switch (cmd) {
@@ -1592,6 +1604,11 @@ SYSCALL_DEFINE3(shmat, int, shmid, char
{
unsigned long ret;
long err;
+
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA);
if (err)
@@ -1732,6 +1749,11 @@ long ksys_shmdt(char __user *shmaddr)
SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_shmdt(shmaddr);
}
diff -ruNp linux-5.4.42/ipc/syscall.c linux-5.4.42-cher1/ipc/syscall.c
--- linux-5.4.42/ipc/syscall.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/ipc/syscall.c 2020-08-20 23:24:39.409194825 +0300
@@ -11,6 +11,8 @@
#include <linux/ipc_namespace.h>
#include "util.h"
+#include <linux/sched.h>
+
#ifdef __ARCH_WANT_SYS_IPC
#include <linux/errno.h>
#include <linux/ipc.h>
@@ -110,6 +112,11 @@ int ksys_ipc(unsigned int call, int firs
SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
unsigned long, third, void __user *, ptr, long, fifth)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_ipc(call, first, second, third, ptr, fifth);
}
#endif
@@ -205,6 +212,11 @@ int compat_ksys_ipc(u32 call, int first,
COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
u32, third, compat_uptr_t, ptr, u32, fifth)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return compat_ksys_ipc(call, first, second, third, ptr, fifth);
}
#endif
diff -ruNp linux-5.4.42/kernel/acct.c linux-5.4.42-cher1/kernel/acct.c
--- linux-5.4.42/kernel/acct.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/acct.c 2020-08-21 11:19:04.031229257 +0300
@@ -59,6 +59,8 @@
#include <linux/uaccess.h>
#include <linux/sched/cputime.h>
+#include <linux/sched.h>
+
#include <asm/div64.h>
#include <linux/blkdev.h> /* sector_div */
#include <linux/pid_namespace.h>
@@ -274,6 +276,11 @@ SYSCALL_DEFINE1(acct, const char __user
{
int error = 0;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!capable(CAP_SYS_PACCT))
return -EPERM;
diff -ruNp linux-5.4.42/kernel/bpf/syscall.c linux-5.4.42-cher1/kernel/bpf/syscall.c
--- linux-5.4.42/kernel/bpf/syscall.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/bpf/syscall.c 2020-08-21 11:21:53.454545443 +0300
@@ -24,6 +24,8 @@
#include <linux/ctype.h>
#include <linux/nospec.h>
+#include <linux/sched.h>
+
#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
(map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
(map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
@@ -2843,6 +2845,11 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf
union bpf_attr attr;
int err;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN))
return -EPERM;
diff -ruNp linux-5.4.42/kernel/capability.c linux-5.4.42-cher1/kernel/capability.c
--- linux-5.4.42/kernel/capability.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/capability.c 2020-08-21 11:24:01.174032151 +0300
@@ -20,6 +20,8 @@
#include <linux/user_namespace.h>
#include <linux/uaccess.h>
+#include <linux/sched.h>
+
/*
* Leveraged for setting/resetting capabilities
*/
@@ -228,6 +230,11 @@ SYSCALL_DEFINE2(capset, cap_user_header_
int ret;
pid_t pid;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
ret = cap_validate_magic(header, &tocopy);
if (ret != 0)
return ret;
diff -ruNp linux-5.4.42/kernel/compat.c linux-5.4.42-cher1/kernel/compat.c
--- linux-5.4.42/kernel/compat.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/compat.c 2020-08-21 11:40:43.062015052 +0300
@@ -132,6 +132,10 @@ COMPAT_SYSCALL_DEFINE3(sigprocmask, int,
old_sigset_t old_set, new_set;
sigset_t new_blocked;
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
old_set = current->blocked.sig[0];
if (nset) {
@@ -216,6 +220,11 @@ COMPAT_SYSCALL_DEFINE3(sched_setaffinity
cpumask_var_t new_mask;
int retval;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
return -ENOMEM;
diff -ruNp linux-5.4.42/kernel/events/core.c linux-5.4.42-cher1/kernel/events/core.c
--- linux-5.4.42/kernel/events/core.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/events/core.c 2020-08-21 12:04:07.868558458 +0300
@@ -50,6 +50,8 @@
#include <linux/proc_ns.h>
#include <linux/mount.h>
+#include <linux/sched.h>
+
#include "internal.h"
#include <asm/irq_regs.h>
@@ -10909,6 +10911,11 @@ SYSCALL_DEFINE5(perf_event_open,
int f_flags = O_RDWR;
int cgroup_fd = -1;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
/* for future expandability... */
if (flags & ~PERF_FLAG_ALL)
return -EINVAL;
diff -ruNp linux-5.4.42/kernel/exec_domain.c linux-5.4.42-cher1/kernel/exec_domain.c
--- linux-5.4.42/kernel/exec_domain.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/exec_domain.c 2020-08-21 12:06:32.008729739 +0300
@@ -39,6 +39,9 @@ SYSCALL_DEFINE1(personality, unsigned in
{
unsigned int old = current->personality;
+ if (SBOX_IS_RESTRICTED())
+ return old;
+
if (personality != 0xffffffff)
set_personality(personality);
diff -ruNp linux-5.4.42/kernel/exit.c linux-5.4.42-cher1/kernel/exit.c
--- linux-5.4.42/kernel/exit.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/exit.c 2020-08-21 12:33:00.712006766 +0300
@@ -64,6 +64,8 @@
#include <linux/rcuwait.h>
#include <linux/compat.h>
+#include <linux/sched.h>
+
#include <linux/uaccess.h>
#include <asm/unistd.h>
#include <asm/pgtable.h>
@@ -1066,6 +1068,11 @@ static int wait_task_zombie(struct wait_
getrusage(p, RUSAGE_BOTH, wo->wo_rusage);
status = (p->signal->flags & SIGNAL_GROUP_EXIT)
? p->signal->group_exit_code : p->exit_code;
+
+ if (SBOX_IS_MEMLIMIT_ERR(p)) status |= 0x10000;
+ if (SBOX_IS_SECURITY_ERR(p)) status |= 0x20000;
+ if (SBOX_IS_TL_ERR(p)) status |= 0x40000;
+
wo->wo_stat = status;
if (state == EXIT_TRACE) {
@@ -1186,6 +1193,10 @@ unlock_sig:
if (likely(!(wo->wo_flags & WNOWAIT)))
wo->wo_stat = (exit_code << 8) | 0x7f;
+ if (SBOX_IS_MEMLIMIT_ERR(p)) wo->wo_stat |= 0x10000;
+ if (SBOX_IS_SECURITY_ERR(p)) wo->wo_stat |= 0x20000;
+ if (SBOX_IS_TL_ERR(p)) wo->wo_stat |= 0x40000;
+
infop = wo->wo_info;
if (infop) {
infop->cause = why;
diff -ruNp linux-5.4.42/kernel/fork.c linux-5.4.42-cher1/kernel/fork.c
--- linux-5.4.42/kernel/fork.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/fork.c 2020-08-21 12:40:01.875198090 +0300
@@ -102,6 +102,8 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include <linux/sched.h>
+
#include <trace/events/sched.h>
#define CREATE_TRACE_POINTS
@@ -2335,6 +2337,11 @@ long _do_fork(struct kernel_clone_args *
int trace = 0;
long nr;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
/*
* Determine whether and which event to report to ptracer. When
* called from kernel_thread or CLONE_UNTRACED is explicitly
@@ -2924,6 +2931,11 @@ bad_unshare_out:
SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_unshare(unshare_flags);
}
diff -ruNp linux-5.4.42/kernel/groups.c linux-5.4.42-cher1/kernel/groups.c
--- linux-5.4.42/kernel/groups.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/groups.c 2020-08-21 12:42:40.033434629 +0300
@@ -12,6 +12,8 @@
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
+#include <linux/sched.h>
+
struct group_info *groups_alloc(int gidsetsize)
{
struct group_info *gi;
@@ -192,6 +194,11 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsi
struct group_info *group_info;
int retval;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!may_setgroups())
return -EPERM;
if ((unsigned)gidsetsize > NGROUPS_MAX)
diff -ruNp linux-5.4.42/kernel/kcmp.c linux-5.4.42-cher1/kernel/kcmp.c
--- linux-5.4.42/kernel/kcmp.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/kcmp.c 2020-08-21 12:44:41.888391290 +0300
@@ -17,6 +17,8 @@
#include <linux/eventpoll.h>
#include <linux/file.h>
+#include <linux/sched.h>
+
#include <asm/unistd.h>
/*
@@ -155,6 +157,11 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t
struct task_struct *task1, *task2;
int ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
rcu_read_lock();
/*
diff -ruNp linux-5.4.42/kernel/kexec.c linux-5.4.42-cher1/kernel/kexec.c
--- linux-5.4.42/kernel/kexec.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/kexec.c 2020-08-21 15:56:31.453585101 +0300
@@ -17,6 +17,8 @@
#include <linux/vmalloc.h>
#include <linux/slab.h>
+#include <linux/sched.h>
+
#include "kexec_internal.h"
static int copy_user_segment_list(struct kimage *image,
@@ -234,6 +236,11 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
{
int result;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
result = kexec_load_check(nr_segments, flags);
if (result)
return result;
@@ -271,6 +278,11 @@ COMPAT_SYSCALL_DEFINE4(kexec_load, compa
struct kexec_segment out, __user *ksegments;
unsigned long i, result;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
result = kexec_load_check(nr_segments, flags);
if (result)
return result;
diff -ruNp linux-5.4.42/kernel/module.c linux-5.4.42-cher1/kernel/module.c
--- linux-5.4.42/kernel/module.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/module.c 2020-08-21 16:05:46.316781304 +0300
@@ -974,6 +974,11 @@ SYSCALL_DEFINE2(delete_module, const cha
char name[MODULE_NAME_LEN];
int ret, forced = 0;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!capable(CAP_SYS_MODULE) || modules_disabled)
return -EPERM;
@@ -3982,6 +3987,11 @@ SYSCALL_DEFINE3(init_module, void __user
int err;
struct load_info info = { };
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
err = may_init_module();
if (err)
return err;
@@ -4003,6 +4013,11 @@ SYSCALL_DEFINE3(finit_module, int, fd, c
void *hdr;
int err;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
err = may_init_module();
if (err)
return err;
diff -ruNp linux-5.4.42/kernel/nsproxy.c linux-5.4.42-cher1/kernel/nsproxy.c
--- linux-5.4.42/kernel/nsproxy.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/nsproxy.c 2020-08-21 16:07:44.396599724 +0300
@@ -24,6 +24,8 @@
#include <linux/cgroup.h>
#include <linux/perf_event.h>
+#include <linux/sched.h>
+
static struct kmem_cache *nsproxy_cachep;
struct nsproxy init_nsproxy = {
@@ -238,6 +240,11 @@ SYSCALL_DEFINE2(setns, int, fd, int, nst
struct ns_common *ns;
int err;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
file = proc_ns_fget(fd);
if (IS_ERR(file))
return PTR_ERR(file);
diff -ruNp linux-5.4.42/kernel/printk/printk.c linux-5.4.42-cher1/kernel/printk/printk.c
--- linux-5.4.42/kernel/printk/printk.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/printk/printk.c 2020-08-21 16:09:56.940417708 +0300
@@ -49,6 +49,8 @@
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
+#include <linux/sched.h>
+
#include <linux/uaccess.h>
#include <asm/sections.h>
@@ -1645,6 +1647,9 @@ int do_syslog(int type, char __user *buf
SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
return do_syslog(type, buf, len, SYSLOG_FROM_READER);
}
diff -ruNp linux-5.4.42/kernel/ptrace.c linux-5.4.42-cher1/kernel/ptrace.c
--- linux-5.4.42/kernel/ptrace.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/ptrace.c 2020-08-21 16:14:54.580068374 +0300
@@ -1245,6 +1245,24 @@ SYSCALL_DEFINE4(ptrace, long, request, l
struct task_struct *child;
long ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ if (request == PTRACE_MEMLIMIT) {
+ current->sbox_flags |= SBOX_MEMLIMITON;
+ return 0;
+ }
+ if (request == PTRACE_NO_SYSCALLS) {
+ current->sbox_flags |= SBOX_NO_SYSCALLS;
+ return 0;
+ }
+ if (request == PTRACE_TIMELIMIT) {
+ current->sbox_flags |= SBOX_TLON;
+ return 0;
+ }
+
if (request == PTRACE_TRACEME) {
ret = ptrace_traceme();
if (!ret)
@@ -1392,6 +1410,24 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_lo
struct task_struct *child;
long ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ if (request == PTRACE_MEMLIMIT) {
+ current->sbox_flags |= SBOX_MEMLIMITON;
+ return 0;
+ }
+ if (request == PTRACE_NO_SYSCALLS) {
+ current->sbox_flags |= SBOX_NO_SYSCALLS;
+ return 0;
+ }
+ if (request == PTRACE_TIMELIMIT) {
+ current->sbox_flags |= SBOX_TLON;
+ return 0;
+ }
+
if (request == PTRACE_TRACEME) {
ret = ptrace_traceme();
goto out;
diff -ruNp linux-5.4.42/kernel/reboot.c linux-5.4.42-cher1/kernel/reboot.c
--- linux-5.4.42/kernel/reboot.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/reboot.c 2020-08-21 16:17:48.171890320 +0300
@@ -18,6 +18,8 @@
#include <linux/syscore_ops.h>
#include <linux/uaccess.h>
+#include <linux/sched.h>
+
/*
* this indicates whether you can reboot with ctrl-alt-del: the default is yes
*/
@@ -310,10 +312,16 @@ DEFINE_MUTEX(system_transition_mutex);
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
{
- struct pid_namespace *pid_ns = task_active_pid_ns(current);
+ struct pid_namespace *pid_ns = NULL;
char buffer[256];
int ret = 0;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ pid_ns = task_active_pid_ns(current);
/* We only trust the superuser with rebooting the system. */
if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))
return -EPERM;
diff -ruNp linux-5.4.42/kernel/sched/core.c linux-5.4.42-cher1/kernel/sched/core.c
--- linux-5.4.42/kernel/sched/core.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/sched/core.c 2020-08-21 16:24:14.211533434 +0300
@@ -4572,6 +4572,9 @@ SYSCALL_DEFINE1(nice, int, increment)
{
long nice, retval;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
/*
* Setpriority might change our priority at the same moment.
* We don't have to worry. Conceptually one call occurs first
@@ -5161,6 +5164,11 @@ err_size:
*/
SYSCALL_DEFINE3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (policy < 0)
return -EINVAL;
@@ -5176,6 +5184,11 @@ SYSCALL_DEFINE3(sched_setscheduler, pid_
*/
SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_sched_setscheduler(pid, SETPARAM_POLICY, param);
}
@@ -5192,6 +5205,11 @@ SYSCALL_DEFINE3(sched_setattr, pid_t, pi
struct task_struct *p;
int retval;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!uattr || pid < 0 || flags)
return -EINVAL;
@@ -5495,6 +5513,11 @@ SYSCALL_DEFINE3(sched_setaffinity, pid_t
cpumask_var_t new_mask;
int retval;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
return -ENOMEM;
diff -ruNp linux-5.4.42/kernel/sched/membarrier.c linux-5.4.42-cher1/kernel/sched/membarrier.c
--- linux-5.4.42/kernel/sched/membarrier.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/sched/membarrier.c 2020-08-21 16:00:31.625395919 +0300
@@ -339,6 +339,11 @@ static int membarrier_register_private_e
*/
SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (unlikely(flags))
return -EINVAL;
switch (cmd) {
diff -ruNp linux-5.4.42/kernel/seccomp.c linux-5.4.42-cher1/kernel/seccomp.c
--- linux-5.4.42/kernel/seccomp.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/seccomp.c 2020-08-21 16:25:57.699443689 +0300
@@ -1413,6 +1413,9 @@ static long do_seccomp(unsigned int op,
SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
void __user *, uargs)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_seccomp(op, flags, uargs);
}
diff -ruNp linux-5.4.42/kernel/signal.c linux-5.4.42-cher1/kernel/signal.c
--- linux-5.4.42/kernel/signal.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/signal.c 2020-08-21 16:37:17.955487154 +0300
@@ -47,6 +47,8 @@
#include <linux/cgroup.h>
#include <linux/audit.h>
+#include <linux/sched.h>
+
#define CREATE_TRACE_POINTS
#include <trace/events/signal.h>
@@ -3022,6 +3024,10 @@ SYSCALL_DEFINE4(rt_sigprocmask, int, how
sigset_t old_set, new_set;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ nset = NULL;
+ }
+
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
@@ -3052,6 +3058,10 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, i
{
sigset_t old_set = current->blocked;
+ if (SBOX_IS_RESTRICTED()) {
+ nset = NULL;
+ }
+
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
@@ -3644,6 +3654,14 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, s
{
struct kernel_siginfo info;
+ if (SBOX_IS_RESTRICTED()) {
+ if (!pid) pid = current->pid;
+ if (pid != current->pid) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+ }
+
prepare_kill_siginfo(sig, &info);
return kill_something_info(sig, &info, pid);
@@ -3826,6 +3844,11 @@ SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid
if (pid <= 0 || tgid <= 0)
return -EINVAL;
+ if (SBOX_IS_RESTRICTED() && current->pid != tgid) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_tkill(tgid, pid, sig);
}
@@ -3842,6 +3865,11 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int,
if (pid <= 0)
return -EINVAL;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return do_tkill(0, pid, sig);
}
@@ -4047,6 +4075,11 @@ SYSCALL_DEFINE2(sigaltstack,const stack_
{
stack_t new, old;
int err;
+
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
if (uss && copy_from_user(&new, uss, sizeof(stack_t)))
return -EFAULT;
err = do_sigaltstack(uss ? &new : NULL, uoss ? &old : NULL,
@@ -4115,6 +4148,10 @@ COMPAT_SYSCALL_DEFINE2(sigaltstack,
const compat_stack_t __user *, uss_ptr,
compat_stack_t __user *, uoss_ptr)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
return do_compat_sigaltstack(uss_ptr, uoss_ptr);
}
@@ -4192,6 +4229,10 @@ SYSCALL_DEFINE3(sigprocmask, int, how, o
old_sigset_t old_set, new_set;
sigset_t new_blocked;
+ if (SBOX_IS_RESTRICTED()) {
+ nset = NULL;
+ }
+
old_set = current->blocked.sig[0];
if (nset) {
@@ -4399,6 +4440,10 @@ SYSCALL_DEFINE1(ssetmask, int, newmask)
int old = current->blocked.sig[0];
sigset_t newset;
+ if (SBOX_IS_RESTRICTED()) {
+ return old;
+ }
+
siginitset(&newset, newmask);
set_current_blocked(&newset);
diff -ruNp linux-5.4.42/kernel/sys.c linux-5.4.42-cher1/kernel/sys.c
--- linux-5.4.42/kernel/sys.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/sys.c 2020-08-21 17:46:52.528149083 +0300
@@ -202,6 +202,11 @@ SYSCALL_DEFINE3(setpriority, int, which,
struct pid *pgrp;
kuid_t uid;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (which > PRIO_USER || which < PRIO_PROCESS)
goto out;
@@ -401,6 +406,11 @@ error:
SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setregid(rgid, egid);
}
@@ -443,6 +453,11 @@ error:
SYSCALL_DEFINE1(setgid, gid_t, gid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setgid(gid);
}
@@ -552,6 +567,11 @@ error:
SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setreuid(ruid, euid);
}
@@ -610,6 +630,11 @@ error:
SYSCALL_DEFINE1(setuid, uid_t, uid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setuid(uid);
}
@@ -685,6 +710,11 @@ error:
SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setresuid(ruid, euid, suid);
}
@@ -764,6 +794,11 @@ error:
SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setresgid(rgid, egid, sgid);
}
@@ -832,6 +867,11 @@ change_okay:
SYSCALL_DEFINE1(setfsuid, uid_t, uid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setfsuid(uid);
}
@@ -875,6 +915,11 @@ change_okay:
SYSCALL_DEFINE1(setfsgid, gid_t, gid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setfsgid(gid);
}
#endif /* CONFIG_MULTIUSER */
@@ -974,6 +1019,11 @@ static compat_clock_t clock_t_to_compat_
COMPAT_SYSCALL_DEFINE1(times, struct compat_tms __user *, tbuf)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (tbuf) {
struct tms tms;
struct compat_tms tmp;
@@ -1010,6 +1060,11 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid
struct pid *pgrp;
int err;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!pid)
pid = task_pid_vnr(group_leader);
if (!pgid)
@@ -1190,6 +1245,11 @@ out:
SYSCALL_DEFINE0(setsid)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return ksys_setsid();
}
@@ -1307,6 +1367,11 @@ SYSCALL_DEFINE2(sethostname, char __user
int errno;
char tmp[__NEW_UTS_LEN];
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
return -EPERM;
@@ -1360,6 +1425,11 @@ SYSCALL_DEFINE2(setdomainname, char __us
int errno;
char tmp[__NEW_UTS_LEN];
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
@@ -1400,6 +1470,11 @@ COMPAT_SYSCALL_DEFINE2(setrlimit, unsign
struct rlimit r;
struct compat_rlimit r32;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (copy_from_user(&r32, rlim, sizeof(struct compat_rlimit)))
return -EFAULT;
@@ -1613,6 +1688,15 @@ SYSCALL_DEFINE4(prlimit64, pid_t, pid, u
unsigned int checkflags = 0;
int ret;
+ if (SBOX_IS_RESTRICTED()) {
+ if (!pid) pid = current->pid;
+ if (pid != current->pid) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+ new_rlim = NULL;
+ }
+
if (old_rlim)
checkflags |= LSM_PRLIMIT_READ;
@@ -1654,6 +1738,10 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
{
struct rlimit new_rlim;
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
return -EFAULT;
return do_prlimit(current, resource, &new_rlim, NULL);
@@ -1805,6 +1893,10 @@ COMPAT_SYSCALL_DEFINE2(getrusage, int, w
SYSCALL_DEFINE1(umask, int, mask)
{
+ if (SBOX_IS_RESTRICTED()) {
+ return current->fs->umask;
+ }
+
mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
return mask;
}
@@ -2266,6 +2358,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
unsigned char comm[sizeof(me->comm)];
long error;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
error = security_task_prctl(option, arg2, arg3, arg4, arg5);
if (error != -ENOSYS)
return error;
@@ -2576,6 +2673,10 @@ SYSCALL_DEFINE1(sysinfo, struct sysinfo
{
struct sysinfo val;
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
do_sysinfo(&val);
if (copy_to_user(info, &val, sizeof(struct sysinfo)))
@@ -2606,6 +2707,10 @@ COMPAT_SYSCALL_DEFINE1(sysinfo, struct c
{
struct sysinfo s;
+ if (SBOX_IS_RESTRICTED()) {
+ return -EPERM;
+ }
+
do_sysinfo(&s);
/* Check to see if any memory value is too large for 32-bit and scale
diff -ruNp linux-5.4.42/kernel/sysctl_binary.c linux-5.4.42-cher1/kernel/sysctl_binary.c
--- linux-5.4.42/kernel/sysctl_binary.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/sysctl_binary.c 2020-08-21 17:49:24.088043723 +0300
@@ -1405,6 +1405,11 @@ SYSCALL_DEFINE1(sysctl, struct __sysctl_
size_t oldlen = 0;
ssize_t result;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
@@ -1448,6 +1453,11 @@ COMPAT_SYSCALL_DEFINE1(sysctl, struct co
size_t oldlen = 0;
ssize_t result;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
diff -ruNp linux-5.4.42/kernel/time/itimer.c linux-5.4.42-cher1/kernel/time/itimer.c
--- linux-5.4.42/kernel/time/itimer.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/time/itimer.c 2020-08-21 11:34:29.277220892 +0300
@@ -18,6 +18,8 @@
#include <linux/uaccess.h>
+#include <linux/sched.h>
+
/**
* itimer_get_remtime - get remaining time for the timer
*
@@ -116,8 +118,14 @@ COMPAT_SYSCALL_DEFINE2(getitimer, int, w
struct compat_itimerval __user *, it)
{
struct itimerval kit;
- int error = do_getitimer(which, &kit);
+ int error;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
+ error = do_getitimer(which, &kit);
if (!error && put_compat_itimerval(it, &kit))
error = -EFAULT;
return error;
@@ -317,6 +325,11 @@ COMPAT_SYSCALL_DEFINE3(setitimer, int, w
struct itimerval kin, kout;
int error;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (in) {
if (get_compat_itimerval(&kin, in))
return -EFAULT;
diff -ruNp linux-5.4.42/kernel/time/posix-cpu-timers.c linux-5.4.42-cher1/kernel/time/posix-cpu-timers.c
--- linux-5.4.42/kernel/time/posix-cpu-timers.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/time/posix-cpu-timers.c 2020-08-21 17:57:23.311915014 +0300
@@ -16,6 +16,8 @@
#include <linux/compat.h>
#include <linux/sched/deadline.h>
+#include <linux/sched.h>
+
#include "posix-timers.h"
static void posix_cpu_timer_rearm(struct k_itimer *timer);
@@ -850,8 +852,11 @@ static void check_thread_timers(struct t
/* At the hard limit, send SIGKILL. No further action. */
if (hard != RLIM_INFINITY &&
- check_rlimit(rttime, hard, SIGKILL, true, true))
+ check_rlimit(rttime, hard, SIGKILL, true, true)) {
+ if ((tsk->sbox_flags & SBOX_TLON))
+ tsk->sbox_flags |= SBOX_WAS_TL;
return;
+ }
/* At the soft limit, send a SIGXCPU every second */
if (check_rlimit(rttime, soft, SIGXCPU, true, false)) {
@@ -949,8 +954,11 @@ static void check_process_timers(struct
/* At the hard limit, send SIGKILL. No further action. */
if (hard != RLIM_INFINITY &&
- check_rlimit(ptime, hardns, SIGKILL, false, true))
+ check_rlimit(ptime, hardns, SIGKILL, false, true)) {
+ if ((tsk->sbox_flags & SBOX_TLON))
+ tsk->sbox_flags |= SBOX_WAS_TL;
return;
+ }
/* At the soft limit, send a SIGXCPU every second */
if (check_rlimit(ptime, softns, SIGXCPU, false, false)) {
diff -ruNp linux-5.4.42/kernel/time/posix-stubs.c linux-5.4.42-cher1/kernel/time/posix-stubs.c
--- linux-5.4.42/kernel/time/posix-stubs.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/time/posix-stubs.c 2020-08-21 11:52:49.530608662 +0300
@@ -61,6 +61,11 @@ SYSCALL_DEFINE2(clock_settime, const clo
{
struct timespec64 new_tp;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (which_clock != CLOCK_REALTIME)
return -EINVAL;
if (get_timespec64(&new_tp, tp))
diff -ruNp linux-5.4.42/kernel/time/posix-timers.c linux-5.4.42-cher1/kernel/time/posix-timers.c
--- linux-5.4.42/kernel/time/posix-timers.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/time/posix-timers.c 2020-08-21 11:56:02.219383433 +0300
@@ -31,6 +31,8 @@
#include <linux/compat.h>
#include <linux/nospec.h>
+#include <linux/sched.h>
+
#include "timekeeping.h"
#include "posix-timers.h"
@@ -567,6 +569,11 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clo
struct compat_sigevent __user *, timer_event_spec,
timer_t __user *, created_timer_id)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (timer_event_spec) {
sigevent_t event;
@@ -921,6 +928,11 @@ SYSCALL_DEFINE4(timer_settime, timer_t,
struct itimerspec64 *rtn = old_setting ? &old_spec : NULL;
int error = 0;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!new_setting)
return -EINVAL;
@@ -1048,6 +1060,11 @@ SYSCALL_DEFINE2(clock_settime, const clo
const struct k_clock *kc = clockid_to_kclock(which_clock);
struct timespec64 new_tp;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!kc || !kc->clock_set)
return -EINVAL;
@@ -1093,6 +1110,11 @@ SYSCALL_DEFINE2(clock_adjtime, const clo
struct __kernel_timex ktx;
int err;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (copy_from_user(&ktx, utx, sizeof(ktx)))
return -EFAULT;
diff -ruNp linux-5.4.42/kernel/time/time.c linux-5.4.42-cher1/kernel/time/time.c
--- linux-5.4.42/kernel/time/time.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/time/time.c 2020-08-21 18:40:03.055525017 +0300
@@ -43,6 +43,8 @@
#include <generated/timeconst.h>
#include "timekeeping.h"
+#include <linux/sched.h>
+
/*
* The timezone where the local system is located. Used as a default by some
* programs who obtain this value by using gettimeofday.
@@ -83,6 +85,11 @@ SYSCALL_DEFINE1(stime, time_t __user *,
struct timespec64 tv;
int err;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (get_user(tv.tv_sec, tptr))
return -EFAULT;
@@ -203,6 +210,11 @@ SYSCALL_DEFINE2(settimeofday, struct tim
struct timeval user_tv;
struct timezone new_tz;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (tv) {
if (copy_from_user(&user_tv, tv, sizeof(*tv)))
return -EFAULT;
@@ -248,6 +260,11 @@ COMPAT_SYSCALL_DEFINE2(settimeofday, str
struct timeval user_tv;
struct timezone new_tz;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (tv) {
if (compat_get_timeval(&user_tv, tv))
return -EFAULT;
@@ -273,6 +290,11 @@ SYSCALL_DEFINE1(adjtimex, struct __kerne
struct __kernel_timex txc; /* Local copy of parameter */
int ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
/* Copy the user data space into the kernel copy
* structure. But bear in mind that the structures
* may change
diff -ruNp linux-5.4.42/kernel/uid16.c linux-5.4.42-cher1/kernel/uid16.c
--- linux-5.4.42/kernel/uid16.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/kernel/uid16.c 2020-08-21 18:48:31.058896554 +0300
@@ -18,6 +18,8 @@
#include <linux/uaccess.h>
+#include <linux/sched.h>
+
#include "uid16.h"
SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
@@ -179,6 +181,11 @@ SYSCALL_DEFINE2(setgroups16, int, gidset
struct group_info *group_info;
int retval;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!may_setgroups())
return -EPERM;
if ((unsigned)gidsetsize > NGROUPS_MAX)
diff -ruNp linux-5.4.42/Makefile linux-5.4.42-cher1/Makefile
--- linux-5.4.42/Makefile 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/Makefile 2020-08-21 18:51:16.966920930 +0300
@@ -2,7 +2,7 @@
VERSION = 5
PATCHLEVEL = 4
SUBLEVEL = 42
-EXTRAVERSION =
+EXTRAVERSION = -cher1
NAME = Kleptomaniac Octopus
# *DOCUMENTATION*
diff -ruNp linux-5.4.42/mm/madvise.c linux-5.4.42-cher1/mm/madvise.c
--- linux-5.4.42/mm/madvise.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/madvise.c 2020-08-21 21:37:34.359877205 +0300
@@ -1060,6 +1060,9 @@ SYSCALL_DEFINE3(madvise, unsigned long,
size_t len;
struct blk_plug plug;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
start = untagged_addr(start);
if (!madvise_behavior_valid(behavior))
diff -ruNp linux-5.4.42/mm/memfd.c linux-5.4.42-cher1/mm/memfd.c
--- linux-5.4.42/mm/memfd.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/memfd.c 2020-08-21 22:42:54.063484910 +0300
@@ -20,6 +20,8 @@
#include <linux/memfd.h>
#include <uapi/linux/memfd.h>
+#include <linux/sched.h>
+
/*
* We need a tag: a new tag would expand every xa_node by 8 bytes,
* so reuse a tag which we firmly believe is never set or cleared on tmpfs
@@ -257,6 +259,9 @@ SYSCALL_DEFINE2(memfd_create,
char *name;
long len;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (!(flags & MFD_HUGETLB)) {
if (flags & ~(unsigned int)MFD_ALL_FLAGS)
return -EINVAL;
diff -ruNp linux-5.4.42/mm/mempolicy.c linux-5.4.42-cher1/mm/mempolicy.c
--- linux-5.4.42/mm/mempolicy.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/mempolicy.c 2020-08-21 21:45:07.924834918 +0300
@@ -1427,6 +1427,9 @@ SYSCALL_DEFINE6(mbind, unsigned long, st
unsigned long, mode, const unsigned long __user *, nmask,
unsigned long, maxnode, unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return kernel_mbind(start, len, mode, nmask, maxnode, flags);
}
@@ -1453,6 +1456,9 @@ static long kernel_set_mempolicy(int mod
SYSCALL_DEFINE3(set_mempolicy, int, mode, const unsigned long __user *, nmask,
unsigned long, maxnode)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return kernel_set_mempolicy(mode, nmask, maxnode);
}
@@ -1548,6 +1554,9 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi
const unsigned long __user *, old_nodes,
const unsigned long __user *, new_nodes)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return kernel_migrate_pages(pid, maxnode, old_nodes, new_nodes);
}
@@ -1586,6 +1595,9 @@ SYSCALL_DEFINE5(get_mempolicy, int __use
unsigned long __user *, nmask, unsigned long, maxnode,
unsigned long, addr, unsigned long, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return kernel_get_mempolicy(policy, nmask, maxnode, addr, flags);
}
@@ -1601,6 +1613,9 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, in
unsigned long nr_bits, alloc_size;
DECLARE_BITMAP(bm, MAX_NUMNODES);
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
nr_bits = min_t(unsigned long, maxnode-1, nr_node_ids);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
@@ -1628,6 +1643,9 @@ COMPAT_SYSCALL_DEFINE3(set_mempolicy, in
unsigned long nr_bits, alloc_size;
DECLARE_BITMAP(bm, MAX_NUMNODES);
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
@@ -1650,6 +1668,9 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulo
unsigned long nr_bits, alloc_size;
nodemask_t bm;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
diff -ruNp linux-5.4.42/mm/migrate.c linux-5.4.42-cher1/mm/migrate.c
--- linux-5.4.42/mm/migrate.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/migrate.c 2020-08-21 21:47:58.193329941 +0300
@@ -49,6 +49,8 @@
#include <linux/sched/mm.h>
#include <linux/ptrace.h>
+#include <linux/sched.h>
+
#include <asm/tlbflush.h>
#define CREATE_TRACE_POINTS
@@ -1850,6 +1852,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
const int __user *, nodes,
int __user *, status, int, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return kernel_move_pages(pid, nr_pages, pages, nodes, status, flags);
}
diff -ruNp linux-5.4.42/mm/mincore.c linux-5.4.42-cher1/mm/mincore.c
--- linux-5.4.42/mm/mincore.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/mincore.c 2020-08-21 21:49:51.649598821 +0300
@@ -18,6 +18,8 @@
#include <linux/shmem_fs.h>
#include <linux/hugetlb.h>
+#include <linux/sched.h>
+
#include <linux/uaccess.h>
#include <asm/pgtable.h>
@@ -256,6 +258,9 @@ SYSCALL_DEFINE3(mincore, unsigned long,
unsigned long pages;
unsigned char *tmp;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
start = untagged_addr(start);
/* Check the start address: needs to be page-aligned.. */
diff -ruNp linux-5.4.42/mm/mlock.c linux-5.4.42-cher1/mm/mlock.c
--- linux-5.4.42/mm/mlock.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/mlock.c 2020-08-21 21:55:40.930221573 +0300
@@ -717,6 +717,9 @@ static __must_check int do_mlock(unsigne
SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return do_mlock(start, len, VM_LOCKED);
}
@@ -724,6 +727,9 @@ SYSCALL_DEFINE3(mlock2, unsigned long, s
{
vm_flags_t vm_flags = VM_LOCKED;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (flags & ~MLOCK_ONFAULT)
return -EINVAL;
@@ -737,6 +743,9 @@ SYSCALL_DEFINE2(munlock, unsigned long,
{
int ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
start = untagged_addr(start);
len = PAGE_ALIGN(len + (offset_in_page(start)));
@@ -801,6 +810,9 @@ SYSCALL_DEFINE1(mlockall, int, flags)
unsigned long lock_limit;
int ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT)) ||
flags == MCL_ONFAULT)
return -EINVAL;
@@ -829,6 +841,9 @@ SYSCALL_DEFINE0(munlockall)
{
int ret;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
if (down_write_killable(&current->mm->mmap_sem))
return -EINTR;
ret = apply_mlockall_flags(0);
diff -ruNp linux-5.4.42/mm/mmap.c linux-5.4.42-cher1/mm/mmap.c
--- linux-5.4.42/mm/mmap.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/mmap.c 2020-08-21 22:20:34.221657147 +0300
@@ -48,6 +48,8 @@
#include <linux/oom.h>
#include <linux/sched/mm.h>
+#include <linux/sched.h>
+
#include <linux/uaccess.h>
#include <asm/cacheflush.h>
#include <asm/tlb.h>
@@ -275,11 +277,21 @@ success:
userfaultfd_unmap_complete(mm, &uf);
if (populate)
mm_populate(oldbrk, newbrk - oldbrk);
+ if (brk == -ENOMEM) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
+ }
return brk;
out:
retval = origbrk;
up_write(&mm->mmap_sem);
+ if (retval == -ENOMEM) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
+ }
return retval;
}
@@ -1620,6 +1632,11 @@ unsigned long ksys_mmap_pgoff(unsigned l
out_fput:
if (file)
fput(file);
+ if (retval == -ENOMEM) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
+ }
return retval;
}
@@ -2297,12 +2314,20 @@ static int acct_stack_growth(struct vm_a
unsigned long new_start;
/* address space limit tests */
- if (!may_expand_vm(mm, vma->vm_flags, grow))
+ if (!may_expand_vm(mm, vma->vm_flags, grow)) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
return -ENOMEM;
+ }
/* Stack limit test */
- if (size > rlimit(RLIMIT_STACK))
+ if (size > rlimit(RLIMIT_STACK)) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
return -ENOMEM;
+ }
/* mlock limit tests */
if (vma->vm_flags & VM_LOCKED) {
@@ -2311,8 +2336,12 @@ static int acct_stack_growth(struct vm_a
locked = mm->locked_vm + grow;
limit = rlimit(RLIMIT_MEMLOCK);
limit >>= PAGE_SHIFT;
- if (locked > limit && !capable(CAP_IPC_LOCK))
+ if (locked > limit && !capable(CAP_IPC_LOCK)) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
return -ENOMEM;
+ }
}
/* Check to ensure the stack will not grow into a hugetlb-only region */
@@ -2325,8 +2354,12 @@ static int acct_stack_growth(struct vm_a
* Overcommit.. This must be the final test, as it will
* update security statistics.
*/
- if (security_vm_enough_memory_mm(mm, grow))
+ if (security_vm_enough_memory_mm(mm, grow)) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
return -ENOMEM;
+ }
return 0;
}
@@ -2898,6 +2931,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
unsigned long ret = -EINVAL;
struct file *file;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n",
current->comm, current->pid);
@@ -2981,6 +3019,11 @@ out:
mm_populate(ret, populate);
if (!IS_ERR_VALUE(ret))
ret = 0;
+ if (ret == -ENOMEM) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
+ }
return ret;
}
diff -ruNp linux-5.4.42/mm/mprotect.c linux-5.4.42-cher1/mm/mprotect.c
--- linux-5.4.42/mm/mprotect.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/mprotect.c 2020-08-21 22:23:55.380950423 +0300
@@ -33,6 +33,8 @@
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
+#include <linux/sched.h>
+
#include "internal.h"
static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
@@ -625,6 +627,11 @@ SYSCALL_DEFINE2(pkey_alloc, unsigned lon
int pkey;
int ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
/* No flags supported yet. */
if (flags)
return -EINVAL;
@@ -654,6 +661,11 @@ SYSCALL_DEFINE1(pkey_free, int, pkey)
{
int ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
down_write(&current->mm->mmap_sem);
ret = mm_pkey_free(current->mm, pkey);
up_write(&current->mm->mmap_sem);
diff -ruNp linux-5.4.42/mm/mremap.c linux-5.4.42-cher1/mm/mremap.c
--- linux-5.4.42/mm/mremap.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/mremap.c 2020-08-21 22:29:39.432203618 +0300
@@ -25,6 +25,8 @@
#include <linux/mm-arch-hooks.h>
#include <linux/userfaultfd_k.h>
+#include <linux/sched.h>
+
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
@@ -737,5 +739,10 @@ out:
userfaultfd_unmap_complete(mm, &uf_unmap_early);
mremap_userfaultfd_complete(&uf, addr, new_addr, old_len);
userfaultfd_unmap_complete(mm, &uf_unmap);
+ if (ret == -ENOMEM) {
+ if ((current->sbox_flags & SBOX_MEMLIMITON)) {
+ current->sbox_flags |= SBOX_WAS_MEMLIMIT;
+ }
+ }
return ret;
}
diff -ruNp linux-5.4.42/mm/msync.c linux-5.4.42-cher1/mm/msync.c
--- linux-5.4.42/mm/msync.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/msync.c 2020-08-21 22:31:33.340039541 +0300
@@ -37,6 +37,9 @@ SYSCALL_DEFINE3(msync, unsigned long, st
int unmapped_error = 0;
int error = -EINVAL;
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
start = untagged_addr(start);
if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
diff -ruNp linux-5.4.42/mm/process_vm_access.c linux-5.4.42-cher1/mm/process_vm_access.c
--- linux-5.4.42/mm/process_vm_access.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/process_vm_access.c 2020-08-21 22:35:46.155767698 +0300
@@ -295,6 +295,8 @@ SYSCALL_DEFINE6(process_vm_readv, pid_t,
unsigned long, liovcnt, const struct iovec __user *, rvec,
unsigned long, riovcnt, unsigned long, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
return process_vm_rw(pid, lvec, liovcnt, rvec, riovcnt, flags, 0);
}
@@ -303,6 +305,8 @@ SYSCALL_DEFINE6(process_vm_writev, pid_t
unsigned long, liovcnt, const struct iovec __user *, rvec,
unsigned long, riovcnt, unsigned long, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
return process_vm_rw(pid, lvec, liovcnt, rvec, riovcnt, flags, 1);
}
@@ -354,6 +358,9 @@ COMPAT_SYSCALL_DEFINE6(process_vm_readv,
compat_ulong_t, riovcnt,
compat_ulong_t, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return compat_process_vm_rw(pid, lvec, liovcnt, rvec,
riovcnt, flags, 0);
}
@@ -365,6 +372,9 @@ COMPAT_SYSCALL_DEFINE6(process_vm_writev
compat_ulong_t, riovcnt,
compat_ulong_t, flags)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return compat_process_vm_rw(pid, lvec, liovcnt, rvec,
riovcnt, flags, 1);
}
diff -ruNp linux-5.4.42/mm/readahead.c linux-5.4.42-cher1/mm/readahead.c
--- linux-5.4.42/mm/readahead.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/readahead.c 2020-08-21 22:38:49.479626454 +0300
@@ -23,6 +23,8 @@
#include <linux/blk-cgroup.h>
#include <linux/fadvise.h>
+#include <linux/sched.h>
+
#include "internal.h"
/*
@@ -603,5 +605,8 @@ out:
SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count)
{
+ if (SBOX_IS_RESTRICTED())
+ return -EPERM;
+
return ksys_readahead(fd, offset, count);
}
diff -ruNp linux-5.4.42/mm/swapfile.c linux-5.4.42-cher1/mm/swapfile.c
--- linux-5.4.42/mm/swapfile.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/mm/swapfile.c 2020-08-21 22:46:27.039390478 +0300
@@ -40,6 +40,8 @@
#include <linux/swap_slots.h>
#include <linux/sort.h>
+#include <linux/sched.h>
+
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <linux/swapops.h>
@@ -2525,6 +2527,11 @@ SYSCALL_DEFINE1(swapoff, const char __us
int err, found = 0;
unsigned int old_block_size;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -3114,6 +3121,11 @@ SYSCALL_DEFINE2(swapon, const char __use
struct inode *inode = NULL;
bool inced_nr_rotate_swap = false;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (swap_flags & ~SWAP_FLAGS_VALID)
return -EINVAL;
diff -ruNp linux-5.4.42/net/compat.c linux-5.4.42-cher1/net/compat.c
--- linux-5.4.42/net/compat.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/net/compat.c 2020-08-22 09:44:49.329475584 +0300
@@ -33,6 +33,8 @@
#include <linux/uaccess.h>
#include <net/compat.h>
+#include <linux/sched.h>
+
int get_compat_msghdr(struct msghdr *kmsg,
struct compat_msghdr __user *umsg,
struct sockaddr __user **save_addr,
@@ -394,6 +396,11 @@ static int __compat_sys_setsockopt(int f
COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
char __user *, optval, unsigned int, optlen)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __compat_sys_setsockopt(fd, level, optname, optval, optlen);
}
@@ -428,6 +435,11 @@ static int __compat_sys_getsockopt(int f
COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
char __user *, optval, int __user *, optlen)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __compat_sys_getsockopt(fd, level, optname, optval, optlen);
}
@@ -646,6 +658,11 @@ static inline long __compat_sys_sendmsg(
COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg,
unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __compat_sys_sendmsg(fd, msg, flags);
}
@@ -660,6 +677,11 @@ static inline long __compat_sys_sendmmsg
COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
unsigned int, vlen, unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __compat_sys_sendmmsg(fd, mmsg, vlen, flags);
}
@@ -674,6 +696,11 @@ static inline long __compat_sys_recvmsg(
COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg,
unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __compat_sys_recvmsg(fd, msg, flags);
}
@@ -688,6 +715,11 @@ static inline long __compat_sys_recvfrom
COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __compat_sys_recvfrom(fd, buf, len, flags, NULL, NULL);
}
@@ -695,6 +727,11 @@ COMPAT_SYSCALL_DEFINE6(recvfrom, int, fd
unsigned int, flags, struct sockaddr __user *, addr,
int __user *, addrlen)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __compat_sys_recvfrom(fd, buf, len, flags, addr, addrlen);
}
@@ -702,6 +739,11 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg_time64,
unsigned int, vlen, unsigned int, flags,
struct __kernel_timespec __user *, timeout)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
flags | MSG_CMSG_COMPAT, timeout, NULL);
}
@@ -711,6 +753,11 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg_time32,
unsigned int, vlen, unsigned int, flags,
struct old_timespec32 __user *, timeout)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
flags | MSG_CMSG_COMPAT, NULL, timeout);
}
@@ -723,6 +770,11 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int,
u32 a0, a1;
int ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (call < SYS_SOCKET || call > SYS_SENDMMSG)
return -EINVAL;
len = nas[call];
diff -ruNp linux-5.4.42/net/socket.c linux-5.4.42-cher1/net/socket.c
--- linux-5.4.42/net/socket.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/net/socket.c 2020-08-22 10:04:14.885098207 +0300
@@ -104,6 +104,8 @@
#include <net/busy_poll.h>
#include <linux/errqueue.h>
+#include <linux/sched.h>
+
#ifdef CONFIG_NET_RX_BUSY_POLL
unsigned int sysctl_net_busy_read __read_mostly;
unsigned int sysctl_net_busy_poll __read_mostly;
@@ -1517,6 +1519,11 @@ int __sys_socket(int family, int type, i
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_socket(family, type, protocol);
}
@@ -1619,6 +1626,11 @@ out:
SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
int __user *, usockvec)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_socketpair(family, type, protocol, usockvec);
}
@@ -1655,6 +1667,11 @@ int __sys_bind(int fd, struct sockaddr _
SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_bind(fd, umyaddr, addrlen);
}
@@ -1687,6 +1704,11 @@ int __sys_listen(int fd, int backlog)
SYSCALL_DEFINE2(listen, int, fd, int, backlog)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_listen(fd, backlog);
}
@@ -1786,6 +1808,11 @@ out_fd:
SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
int __user *, upeer_addrlen, int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags);
}
@@ -1836,6 +1863,11 @@ out:
SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
int, addrlen)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_connect(fd, uservaddr, addrlen);
}
@@ -1874,6 +1906,11 @@ out:
SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
int __user *, usockaddr_len)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_getsockname(fd, usockaddr, usockaddr_len);
}
@@ -1910,6 +1947,11 @@ int __sys_getpeername(int fd, struct soc
SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
int __user *, usockaddr_len)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_getpeername(fd, usockaddr, usockaddr_len);
}
@@ -1961,6 +2003,11 @@ SYSCALL_DEFINE6(sendto, int, fd, void __
unsigned int, flags, struct sockaddr __user *, addr,
int, addr_len)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_sendto(fd, buff, len, flags, addr, addr_len);
}
@@ -2024,6 +2071,11 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void
unsigned int, flags, struct sockaddr __user *, addr,
int __user *, addr_len)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len);
}
@@ -2097,6 +2149,11 @@ out_put:
SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
char __user *, optval, int, optlen)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_setsockopt(fd, level, optname, optval, optlen);
}
@@ -2141,6 +2198,11 @@ out_put:
SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
char __user *, optval, int __user *, optlen)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_getsockopt(fd, level, optname, optval, optlen);
}
@@ -2165,6 +2227,11 @@ int __sys_shutdown(int fd, int how)
SYSCALL_DEFINE2(shutdown, int, fd, int, how)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_shutdown(fd, how);
}
@@ -2403,6 +2470,11 @@ out:
SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_sendmsg(fd, msg, flags, true);
}
@@ -2480,6 +2552,11 @@ int __sys_sendmmsg(int fd, struct mmsghd
SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
unsigned int, vlen, unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
}
@@ -2624,6 +2701,11 @@ out:
SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
unsigned int, flags)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
return __sys_recvmsg(fd, msg, flags, true);
}
@@ -2777,6 +2859,11 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struc
unsigned int, vlen, unsigned int, flags,
struct __kernel_timespec __user *, timeout)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (flags & MSG_CMSG_COMPAT)
return -EINVAL;
@@ -2822,6 +2909,11 @@ SYSCALL_DEFINE2(socketcall, int, call, u
int err;
unsigned int len;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
if (call < 1 || call > SYS_SENDMMSG)
return -EINVAL;
call = array_index_nospec(call, SYS_SENDMMSG + 1);
diff -ruNp linux-5.4.42/security/keys/keyctl.c linux-5.4.42-cher1/security/keys/keyctl.c
--- linux-5.4.42/security/keys/keyctl.c 2020-05-20 09:20:41.000000000 +0300
+++ linux-5.4.42-cher1/security/keys/keyctl.c 2020-08-22 10:07:55.899168780 +0300
@@ -80,6 +80,11 @@ SYSCALL_DEFINE5(add_key, const char __us
void *payload;
long ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
ret = -EINVAL;
if (plen > 1024 * 1024 - 1)
goto error;
@@ -177,6 +182,11 @@ SYSCALL_DEFINE4(request_key, const char
char type[32], *description, *callout_info;
long ret;
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
/* pull the type into kernel space */
ret = key_get_type_from_user(type, _type, sizeof(type));
if (ret < 0)
@@ -1783,6 +1793,11 @@ long keyctl_capabilities(unsigned char _
SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
unsigned long, arg4, unsigned long, arg5)
{
+ if (SBOX_IS_RESTRICTED()) {
+ SBOX_SET_SECURITY_ERR();
+ return -EPERM;
+ }
+
switch (option) {
case KEYCTL_GET_KEYRING_ID:
return keyctl_get_keyring_ID((key_serial_t) arg2,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment