ADDED Makefile Index: Makefile ================================================================== --- /dev/null +++ Makefile @@ -0,0 +1,36 @@ +# Copyright (C) 2011 Alessandro Ghedini +# Updated 2012 by Mike Perry to extract syscall table addresses +# Updated 2014 by Francis Brosnan Blázquez to check for ia32 support +obj-m += nokeyctl.o + +ifdef M +include $(M)/Makefile.inc +ifndef SYSTEM_MAP_FILE +SYSTEM_MAP_FILE := $(KERNEL_DIR)/System.map +endif + +SCT := $(shell grep " sys_call_table" '$(SYSTEM_MAP_FILE)' | awk '{ print $$1; }') +SCT32 := $(shell grep "ia32_sys_call_table" '$(SYSTEM_MAP_FILE)' | awk '{ print $$1; }') + +EXTRA_CFLAGS += -Dsys_call_table_addr="((void**)0x$(SCT))" +ifdef SCT32 +EXTRA_CFLAGS += -Dia32_sys_call_table_addr="((void**)0x$(SCT32))" -D__enable_32bits_support +endif +else +include Makefile.inc +endif + +all: + @echo "Building with " $(EXTRA_CFLAGS) + make -C '$(KERNEL_DIR)' 'M=$(PWD)' + +install: all + -mkdir -p '$(DESTDIR)/lib/modules/$(KERNEL_VER)/misc' + cp nokeyctl.ko '$(DESTDIR)/lib/modules/$(KERNEL_VER)/misc/' + +clean: + make -C '$(KERNEL_DIR)' 'M=$(PWD)' clean + rm -f Module.symvers built-in.o modules.order nokeyctl.ko nokeyctl.mod.c nokeyctl.mod.o nokeyctl.o + +distclean: clean + rm -f Makefile.inc ADDED configure Index: configure ================================================================== --- /dev/null +++ configure @@ -0,0 +1,45 @@ +#! /bin/bash + +if [ -z "${KERNEL_DIR}" ]; then + for tryKernelDir in "/lib/modules/$(uname -r)"/{build,source} "/usr/src/linux-$(uname -r)"; do + if [ -f "${tryKernelDir}/.config" ]; then + kernelDir="${tryKernelDir}" + + break + fi + done + +else + kernelDir="${KERNEL_DIR}" +fi + +if [ -z "${kernelDir}" ]; then + echo "error: Unable to determine kernel build directory. Try specifying the KERNEL_DIR environment variable" >&2 + + exit 1 +fi + +if [ -z "${SYSTEM_MAP_FILE}" ]; then + for trySystemMapFile in /proc/kallsyms "${kernelDir}/System.map" "/boot/System.map"; do + if grep ' sys_call_table' "${trySystemMapFile}" >/dev/null 2>/dev/null; then + systemMapFile="${trySystemMapFile}" + + break + fi + done +else + systemMapFile="${SYSTEM_MAP_FILE}" +fi + +if [ -z "${systemMapFile}" ]; then + echo "error: Unable to determine system map file. Try specifying the SYSTEM_MAP_FILE environment variable." >&2 + + exit 1 +fi + +rm -f Makefile.inc +echo "SYSTEM_MAP_FILE = ${systemMapFile}" > Makefile.inc +echo "KERNEL_DIR = ${kernelDir}" >> Makefile.inc +echo "KERNEL_VER = $(uname -r)" >> Makefile.inc + +exit 0 ADDED nokeyctl.c Index: nokeyctl.c ================================================================== --- /dev/null +++ nokeyctl.c @@ -0,0 +1,118 @@ +/* + * Kernel module to disable the keyctl() system call. + * + * Compile: + * $ make + * + * Usage: + * # insmod nokeyctl.ko + * # rmmod nokeyctl + * + * Copyright (C) 2011 Alessandro Ghedini + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alessandro Ghedini and Mike Perry"); +MODULE_DESCRIPTION("disable the keyctl() system call"); + +/* ia32 entry */ +#define __NR_compat_keyctl 311 + +static asmlinkage long (*o_ptr)(int cmd, ...); +#if defined(__enable_32bits_support) +static asmlinkage long (*o_ptr32)(int cmd, ...); +#endif + +asmlinkage long nokeyctl(int cmd, ...) { + printk("[nokeyctl] keyctl() invoked by process %i\n", current->pid); + + return(-EPERM); +} + +static void sys_call_table_make_rw(void **addr); +static void sys_call_table_make_ro(void **addr); + +static int __init init_nokeyctl(void) { + void **sys_call_tbl = sys_call_table_addr; +#if defined(__enable_32bits_support) + void **ia32_sys_call_tbl = ia32_sys_call_table_addr; +#endif + + sys_call_table_make_rw(sys_call_tbl); + o_ptr = sys_call_tbl[__NR_keyctl]; + sys_call_tbl[__NR_keyctl] = nokeyctl; + sys_call_table_make_ro(sys_call_tbl); + +#if defined(__enable_32bits_support) + sys_call_table_make_rw(ia32_sys_call_tbl); + o_ptr32 = ia32_sys_call_tbl[__NR_compat_keyctl]; + ia32_sys_call_tbl[__NR_compat_keyctl] = nokeyctl; + sys_call_table_make_ro(ia32_sys_call_tbl); +#endif + + printk("[nokeyctl] keyctl syscall disabled\n"); + + return 0; +} + +static void __exit exit_nokeyctl(void) { + void **sys_call_tbl = sys_call_table_addr; +#if defined(__enable_32bits_support) + void **ia32_sys_call_tbl = ia32_sys_call_table_addr; +#endif + + sys_call_table_make_rw(sys_call_tbl); + sys_call_tbl[__NR_keyctl] = o_ptr; + sys_call_table_make_ro(sys_call_tbl); + +#if defined(__enable_32bits_support) + sys_call_table_make_rw(ia32_sys_call_tbl); + ia32_sys_call_tbl[__NR_compat_keyctl] = o_ptr32; + sys_call_table_make_ro(ia32_sys_call_tbl); +#endif + + printk("[nokeyctl] keyctl syscall restored\n"); +} + +module_init(init_nokeyctl); +module_exit(exit_nokeyctl); + +static void sys_call_table_make_rw(void **addr) { + unsigned int lvl; + + pte_t *pte = lookup_address((unsigned long) addr, &lvl); + + if (pte -> pte &~ _PAGE_RW) + pte -> pte |= _PAGE_RW; + + write_cr0(read_cr0() & (~ 0x10000)); +} + +static void sys_call_table_make_ro(void **addr) { + unsigned int lvl; + + pte_t *pte = lookup_address((unsigned long) addr, &lvl); + pte -> pte = pte -> pte &~_PAGE_RW; + + write_cr0(read_cr0() | 0x10000); +}