stripsignal.c

/*
 * This code is originally based on work provided by:
 * Solutions sets for the Axian Linux Developer: 
 *   Developer: Jerry Cooperstein
 *   email: coop@axian.com
 *   website: http://www.axian.com
 *
 * This Copyright is retained for the purpose of protecting free
 * redistribution of source.
 *
 * The primary maintainer for this code is 
 * (jonEbird@gmail.com) at http://jonebird.com/
 *
 * This code is distributed under Version 2 of the GNU General Public
 * License, which you should have received with the source.
 */

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/init.h>

#define PROCNAME "stripsignal_pid"
#define TARGET_SIGNAL    SIGABRT
#define TARGET_SIGNAL_s "SIGABRT"

static int pid = -1;
static struct proc_dir_entry *my_proc;
struct task_struct *p;

static int
my_proc_read (char *page, char **start, off_t off, int count,
              int *eof, void *data)
{
    *eof = 1;
    if (data == my_proc)
        return sprintf (page, "stripsignal: last pid [%d]: write a pid here to have it's %s signal handler reverted to SIG_DFL\n",
			pid, TARGET_SIGNAL_s);
    return -EINVAL;
}
static int
my_proc_write (struct file *file, const char __user * buffer,
               unsigned long count, void *data)
{

    unsigned long flags;
    struct sighand_struct *sig;

    char *str = kmalloc (count, GFP_KERNEL);

    if (copy_from_user (str, buffer, count)) {
        kfree (str);
        return -EFAULT;
    }

    if (data == my_proc) {
        sscanf (str, "%d", &pid);

	p = find_task_by_pid(pid);
	if (!p) {
	  printk("Invalid PID %d specified\n", pid);
	  return -EINVAL;
	}

	sig = p->sighand;
	spin_lock_irqsave(&sig->siglock, flags);
	sig->action[TARGET_SIGNAL-1].sa.sa_handler = SIG_DFL;
	spin_unlock_irqrestore(&sig->siglock, flags);

	printk("Resetting process %s[%d] signal handler for %s to SIG_DFL\n",
	       p->comm, p->pid, TARGET_SIGNAL_s);

        kfree (str);
        return count;
    }

    kfree (str);
    return -EINVAL;
}
static int __init my_init (void)
{
    my_proc = create_proc_entry (PROCNAME, S_IRUGO | S_IWUSR, NULL);
    if (!my_proc) {
        printk ("stripsignal: failed to make %s\n", PROCNAME);
        remove_proc_entry (PROCNAME, NULL);
        return -1;
    }
    printk ("stripsignal created /proc/%s\n", PROCNAME);
    my_proc->read_proc = my_proc_read;
    my_proc->write_proc = my_proc_write;
    my_proc->data = my_proc;
    my_proc->owner = THIS_MODULE;

    return 0;
}

static void __exit my_exit (void)
{
    if (my_proc) {
        remove_proc_entry (PROCNAME, NULL);
        printk ("Removed /proc/%s\n", PROCNAME);
    }
}

module_init (my_init);
module_exit (my_exit);

MODULE_AUTHOR ("Jon Miller");
MODULE_DESCRIPTION ("Reverting a process's signal handler for signal SIG_ABRT to be SIG_DFL");
MODULE_LICENSE ("GPL v2");

Generated by GNU enscript 1.6.4.