[PATCH] add a stub by which a module can bind to the AFS syscall

From: David Howells (dhowells@redhat.com)
Date: Wed Apr 30 2003 - 08:44:54 EST


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/



This archive was generated by hypermail 2b29 : Wed Apr 30 2003 - 22:00:35 EST