lkml.org 
[lkml]   [2003]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] add a stub by which a module can bind to the AFS syscall
    Date

    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/
    \
     
     \ /
      Last update: 2005-03-22 13:35    [W:0.028 / U:60.484 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site