Skip to content

pr accident #1252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ source "scripts/Kconfig.include"
source "init/Kconfig"

source "kernel/Kconfig.freezer"
source "kernel/Kconfig.sysectl"

source "fs/Kconfig.binfmt"

Expand Down
3 changes: 3 additions & 0 deletions arch/x86/entry/syscalls/syscall_64.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
#ifdef CONFIG_SYSECTL
468 common sysectl sys_sysectl
#endif

#
# Due to a historical design error, certain syscalls are numbered differently
Expand Down
1 change: 1 addition & 0 deletions include/linux/entry-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
SYSCALL_WORK_SYSCALL_EMU | \
SYSCALL_WORK_SYSCALL_AUDIT | \
SYSCALL_WORK_SYSCALL_USER_DISPATCH | \
SYSCALL_WORK_SYSECTL | \
ARCH_SYSCALL_WORK_ENTER)
#define SYSCALL_WORK_EXIT (SYSCALL_WORK_SYSCALL_TRACEPOINT | \
SYSCALL_WORK_SYSCALL_TRACE | \
Expand Down
11 changes: 11 additions & 0 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/hrtimer_types.h>
#include <linux/timer_types.h>
#include <linux/seccomp_types.h>
#include <linux/sysectl_types.h>
#include <linux/nodemask_types.h>
#include <linux/refcount_types.h>
#include <linux/resource.h>
Expand Down Expand Up @@ -1646,6 +1647,16 @@ struct task_struct {
struct user_event_mm *user_event_mm;
#endif

#ifdef CONFIG_SYSECTL
struct sysectl sysectl;
#endif

/*
* New fields for task_struct should be added above here, so that
* they are included in the randomized portion of task_struct.
*/
randomized_struct_fields_end

/* CPU-specific state of this task: */
struct thread_struct thread;

Expand Down
4 changes: 4 additions & 0 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,10 @@ asmlinkage long sys_ni_syscall(void);

asmlinkage long sys_ni_posix_timers(void);

#ifdef CONFIG_SYSECTL
asmlinkage long sys_sysectl(void);
#endif

/*
* Kernel code should not call syscalls (i.e., sys_xyzyyz()) directly.
* Instead, use one of the functions which work equivalently, such as
Expand Down
15 changes: 15 additions & 0 deletions include/linux/sysectl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef _LINUX_SYSECTL_H_
#define _LINUX_SYSECTL_H_

#ifdef CONFIG_SYSECTL
#include "sysectl_types.h"


// Entry from system call to sysectl filtering
long sysectl_entry(long nbr);

void sysectl_release(struct sysectl *sysectl);

#endif /* CONFIG_SYSECTL */
#endif /* _LINUX_SYSECTL_H_ */

62 changes: 62 additions & 0 deletions include/linux/sysectl_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef _LINUX_SYSECTL_TYPES_H_
#define _LINUX_SYSECTL_TYPES_H_

#ifdef CONFIG_SYSECTL

// Initialize everything to 0 and all bits in the bitmap to 1
#define SYSECTL_DEFAULTS ((struct sysectl){0})

#define sysectl_bitmap(tsk) tsk->sysectl.top->bitmap.bits

// .section .secfilterbitmap
struct sysectl_filter_bitmap {
unsigned char bits[64]; // 64 = One bit per syscall
};

// .section .secmap
struct sysectlmap {
void *pc;
unsigned int opcode;
unsigned int next;

union {
struct sysectl_filter_bitmap *bitmap;
unsigned short syscalls[4];
} filter;
};

// Lookup table: PC to Map
struct sysectltable {
// Page sized array, lookup table, PC to index
// index is the *maps array index
short *index;

// Arrays of maps and bitmaps, contains the data
struct sysectlmap *maps;
struct sysectl_filter_bitmap *bitmaps;
};

// map = Which map was used to set or modify the bitmap
// Notice: map is used to create restore - deny/allow pair
struct sysectlstack {
struct sysectlmap *map;
struct sysectl_filter_bitmap bitmap;
};

// Declared in task_structure
struct sysectl {
// TODO - Direct reference to filter itself?
// There can be many kind of filters? Copy type is not clear?
// If we want many kind of filters, we may need an interface.
struct sysectlstack *stack;
struct sysectlstack *stackend;
struct sysectlstack *top;

struct sysectltable ltable;
};

#else
#define sysectl_entry(nbr) 1
#endif /* CONFIG_SYSECTL */
#endif /* _LINUX_SYSECTL_TYPES_H_ */

2 changes: 2 additions & 0 deletions include/linux/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum syscall_work_bit {
SYSCALL_WORK_BIT_SYSCALL_AUDIT,
SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH,
SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP,
SYSCALL_WORK_BIT_SYSECTL,
};

#define SYSCALL_WORK_SECCOMP BIT(SYSCALL_WORK_BIT_SECCOMP)
Expand All @@ -55,6 +56,7 @@ enum syscall_work_bit {
#define SYSCALL_WORK_SYSCALL_AUDIT BIT(SYSCALL_WORK_BIT_SYSCALL_AUDIT)
#define SYSCALL_WORK_SYSCALL_USER_DISPATCH BIT(SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH)
#define SYSCALL_WORK_SYSCALL_EXIT_TRAP BIT(SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP)
#define SYSCALL_WORK_SYSECTL BIT(SYSCALL_WORK_BIT_SYSECTL)
#endif

#include <asm/thread_info.h>
Expand Down
3 changes: 3 additions & 0 deletions init/init_task.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ struct task_struct init_task __aligned(L1_CACHE_BYTES) = {
#ifdef CONFIG_SECCOMP_FILTER
.seccomp = { .filter_count = ATOMIC_INIT(0) },
#endif
#ifdef CONFIG_SYSECTL
.sysectl = SYSECTL_DEFAULTS,
#endif
};
EXPORT_SYMBOL(init_task);

Expand Down
6 changes: 6 additions & 0 deletions kernel/Kconfig.sysectl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
config SYSECTL
bool "Enable System call extended control"
default y
help
Say Y to enable the System call extended control

1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o
obj-$(CONFIG_HARDLOCKUP_DETECTOR_BUDDY) += watchdog_buddy.o
obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_perf.o
obj-$(CONFIG_SECCOMP) += seccomp.o
obj-$(CONFIG_SYSECTL) += sysectl.o
obj-$(CONFIG_RELAY) += relay.o
obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
Expand Down
7 changes: 7 additions & 0 deletions kernel/entry/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/livepatch.h>
#include <linux/audit.h>
#include <linux/tick.h>
#include <linux/sysectl.h>

#include "common.h"

Expand Down Expand Up @@ -66,6 +67,12 @@ long syscall_trace_enter(struct pt_regs *regs, long syscall,
syscall = syscall_get_nr(current, regs);
}

if (work & SYSCALL_WORK_SYSECTL) {
if (unlikely(sysectl_entry(syscall) == -1L)) {
return -1L;
}
}

syscall_enter_audit(regs, syscall);

return ret ? : syscall;
Expand Down
4 changes: 4 additions & 0 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include <linux/user_events.h>
#include <linux/uaccess.h>
#include <linux/pidfs.h>
#include <linux/sysectl.h>

#include <uapi/linux/wait.h>

Expand Down Expand Up @@ -916,6 +917,9 @@ void __noreturn do_exit(long code)
exit_signals(tsk); /* sets PF_EXITING */

seccomp_filter_release(tsk);
#ifdef CONFIG_SYSECTL
sysectl_release(&tsk->sysectl);
#endif

acct_update_integrals(tsk);
group_dead = atomic_dec_and_test(&tsk->signal->live);
Expand Down
5 changes: 5 additions & 0 deletions kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <linux/security.h>
#include <linux/hugetlb.h>
#include <linux/seccomp.h>
#include <linux/sysectl_types.h>
#include <linux/swap.h>
#include <linux/syscalls.h>
#include <linux/syscall_user_dispatch.h>
Expand Down Expand Up @@ -1157,6 +1158,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
tsk->seccomp.filter = NULL;
#endif

#ifdef CONFIG_SYSECTL
tsk->sysectl = SYSECTL_DEFAULTS;
#endif

setup_thread_stack(tsk, orig);
clear_user_return_notifier(tsk);
clear_tsk_need_resched(tsk);
Expand Down
Loading