Messages in this thread Patch in this message | | | From | David Howells <> | Subject | [PATCH] add a stub by which a module can bind to the AFS syscall | Date | Wed, 30 Apr 2003 14:44:54 +0100 |
| |
Hi Linus,
This patch makes it possible for a module to bind safely to the AFS syscall, without having to modify the syscall table directly.
David
diff -uNr -x'*.o' -x'.*' -xTAGS linux-2.5.67/include/linux/syscallstub.h linux-2.5.67-afs/include/linux/syscallstub.h --- linux-2.5.67/include/linux/syscallstub.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.5.67-afs/include/linux/syscallstub.h 2003-04-07 13:17:38.000000000 +0100 @@ -0,0 +1,28 @@ +/* syscallstub.h: system call stub management + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * 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. + */ + +#ifndef _LINUX_SYSCALLSTUB_H +#define _LINUX_SYSCALLSTUB_H + +#include <linux/module.h> + +/* + * AFS system call stub management + */ +typedef int (*afs_syscall_handler_t)(long cmd, va_list va); + +extern int register_afs_syscall_handler(afs_syscall_handler_t handler, struct module *owner); +extern void unregister_afs_syscall_handler(afs_syscall_handler_t handler, struct module *owner); + +extern asmlinkage int sys_afs(long cmd, ...); + + +#endif /* _LINUX_SYSCALLSTUB_H */ diff -uNr -x'*.o' -x'.*' -xTAGS linux-2.5.67/kernel/Makefile linux-2.5.67-afs/kernel/Makefile --- linux-2.5.67/kernel/Makefile 2003-03-05 03:29:02.000000000 +0000 +++ linux-2.5.67-afs/kernel/Makefile 2003-04-07 13:16:52.000000000 +0100 @@ -6,7 +6,8 @@ exit.o itimer.o time.o softirq.o resource.o \ sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o futex.o pid.o \ - rcupdate.o intermodule.o extable.o params.o posix-timers.o + rcupdate.o intermodule.o extable.o params.o posix-timers.o \ + syscallstub.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o obj-$(CONFIG_SMP) += cpu.o diff -uNr -x'*.o' -x'.*' -xTAGS linux-2.5.67/kernel/syscallstub.c linux-2.5.67-afs/kernel/syscallstub.c --- linux-2.5.67/kernel/syscallstub.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.5.67-afs/kernel/syscallstub.c 2003-04-30 14:35:11.000000000 +0100 @@ -0,0 +1,88 @@ +/* syscallstub.c: module providable syscall stub management + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * 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. + */ +#include <linux/syscallstub.h> +#include <linux/spinlock.h> +#include <linux/errno.h> + +/* + * AFS system call stub management + */ +static afs_syscall_handler_t afs_syscall_handler; +static struct module *afs_syscall_owner; +static rwlock_t afs_syscall_handler_lock = RW_LOCK_UNLOCKED; + +int register_afs_syscall_handler(afs_syscall_handler_t handler, struct module *owner) +{ + int ret; + + if (!handler || !owner) + return -EINVAL; + + ret = -EEXIST; + write_lock(&afs_syscall_handler_lock); + + if (!afs_syscall_handler) { + afs_syscall_handler = handler; + afs_syscall_owner = owner; + ret = 0; + } + + write_unlock(&afs_syscall_handler_lock); + + return ret; +} + +EXPORT_SYMBOL(register_afs_syscall_handler); + +void unregister_afs_syscall_handler(afs_syscall_handler_t handler, struct module *owner) +{ + write_lock(&afs_syscall_handler_lock); + + if (afs_syscall_handler==handler && afs_syscall_owner==owner) { + afs_syscall_handler = NULL; + afs_syscall_owner = NULL; + } + else { + printk("module %s tried to free AFS syscall which it did not own\n", + owner->name); + } + + write_unlock(&afs_syscall_handler_lock); +} + +EXPORT_SYMBOL(unregister_afs_syscall_handler); + +asmlinkage int sys_afs(long cmd, ...) +{ + afs_syscall_handler_t handler; + struct module *owner; + va_list va; + int ret; + + ret = -ENOSYS; + read_lock(&afs_syscall_handler_lock); + handler = afs_syscall_handler; + owner = afs_syscall_owner; + if (handler && try_module_get(owner)) + ret = 0; + read_unlock(&afs_syscall_handler_lock); + + if (ret<0) + return ret; + + va_start(va,cmd); + ret = handler(cmd,va); + va_end(va); + + module_put(owner); + return ret; +} + diff -uNr -x'*.o' -x'.*' -xTAGS linux-2.5.67/arch/i386/kernel/entry.S linux-2.5.67-afs/arch/i386/kernel/entry.S --- linux-2.5.67/arch/i386/kernel/entry.S 2003-03-28 11:37:52.000000000 +0000 +++ linux-2.5.67-afs/arch/i386/kernel/entry.S 2003-04-30 14:38:32.000000000 +0100 @@ -721,7 +721,7 @@ .long sys_bdflush .long sys_sysfs /* 135 */ .long sys_personality - .long sys_ni_syscall /* reserved for afs_syscall */ + .long sys_afs .long sys_setfsuid16 .long sys_setfsgid16 .long sys_llseek /* 140 */ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |