lkml.org 
[lkml]   [2004]   [Jun]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [Announce] Non Invasive Kernel Monitor for threads/processes

Andrew Morton wrote:

>Atul Sabharwal <atul_sabharwal@linux.jf.intel.com> wrote:
>
>
>> We have been working with a solution for non-intrusively trapping on
>> lifetime
>> of processes/threads.
>>
>>
>
>I expect this functionality can be provided without kernel changes via
>auditing of the relevant system calls. See
>http://people.redhat.com/faith/audit/.
>
>Maybe there are shortcomings in the current auditing/filtering framework.
>If so, perhaps they could be addressed.
>
>For you, the next step should be to send the patch and description (without
>wordwrapping this time, please) to linux-kernel, and cc Rik Faith
><faith@redhat.com>, see what Rik and the SELinux guys have to say about it.
>

Hi Rick,

I have attached the description and patch about the non-invasive kernel
monitor. Looking
for comments/feedback from you about the differences/value add between
the two solutions ?

Thanks,

Atul

>I have been experimenting with the CGL 2.0 AVL 8.2 requirement on Non-intrusive kernel
>based monitoring of processes and threads. For your reference, the requirement is
>quoted below :
>
>AVL 8.2 requirement :
>~~~~~~~~~~~~~~~~~~~~~
>CGL shall support methods to non-intrusively monitor processes at the kernel level.
>It would use a notfication mechanism in the kernel that allows registration of events
>of interest regarding processes. Events of interest could be the following :
>Process creation (fork), Process exit ( exit ), Process calls ( exec ), thread
>creation & thread exit.
>
>The implementation needs to provide high performance with low overhead. Monitoring
>would be driven directly by the events in the kernel to ensure low latency access
>to interesting events.
>
>Solution Approach:
>~~~~~~~~~~~~~~~~~~
>This method requires a user space process (called monitor) to start and stop
>monitoring in the system. The monitor sends the list of pids and the events
>to be monitored for that pid. Once the ioctl is received, the kernel establishes
>a filter for it. Events get flooded in the system as each call (fork, exec and
> exit) has been modified to generate events. The events which match the filter
>become interesting and require that a notification is sent to the monitor process.
>Events which do no match the filter get dropped.
>
>In the case when we have multiple monitor processes, signals are sent to each monitor
>whose filters match the event which has occurred.
>
>
>Solution Description :
>~~~~~~~~~~~~~~~~~~~~~~
>The registration and de-registration command are implemented as ioctls. The notification
>command is implemented as a sigqueue signal. The system calls such as fork, exit, and
>exec have been changed to add a notification call to the monitor process. The filter
>for events is populated with the registration command. Events & their respective
>thread/process get removed from the filter with the de-registration command.
>
>Threads and processes follow the same code path for task creation and termination.
>Hence, the code path is the same for threads and processes. There is no equivalent
>of an exec call with threads. The only distinction for a thread is that in the
>task struct, the thread group id (tgid) and process id (pid) are different. For
>a process, they are the same.
>
>The signal used for notification is also specified with the registration command.
>If it is a real-time signal, it would perform better as signals would get queued
>for the monitor. With non-real time signals, signals would get dropped if one
>signal exists. Hence, it is recommended to specify a real time signal.
>
>Also, it is to be noted that the solution is totally architecture independent.
>So, would just need a re-compile on the respective platform.
>
>Kmonitor has been implemented as a miscellaneous character driver built into the
>Linux kernel. It cannot be compiled as a loadable module. It supports the relevant
>driver calls for open, release, ioctl, init, cleanup calls. The character driver
>code contains the filtering, registration/de-registration and notification functions
>of Kmonitor as wells as routines to manage the linked list(s) for filtering.
>
>Kmonitor has 256 buckets and each bucket contains a spinlock and a linked list.
>This works around the sequential search operation in linked list by using a
>hashing function to change the complexity from O(N) to O(N/M) where M is the
>number of buckets.
>
>Kernel Version & Code location:
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>The kernel used was the 2.6.6 kernel and the code is at http://kmonitor.bkbits.net
>
>
>User space programs:
>~~~~~~~~~~~~~~~~~~~~
>1. unit_test : A sample program to monitor future processes.
> http://kmonitor.bkbits.net:8080/tools/anno/unit_test.c@1.4?nav=index.html|ChangeSet@-3w|cset@1.35
>
>2. monitor_pid: A sample program to monitor a process sub-tree.
> http://kmonitor.bkbits.net:8080/tools/anno/monitor_pid.c@1.2?nav=index.html|ChangeSet@-2w|cset@1.37
>
>3. wait_on_pid : A sample program which waits till a pid dies.
> http://kmonitor.bkbits.net:8080/tools/anno/wait_on_pid.c@1.5?nav=index.html|ChangeSet@-2w|cset@1.37
>
>Source Code:
>~~~~~~~~~~~~
>The patch for Kmonitor is as below :
>
>
>diff -Nru a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
>--- a/Documentation/ioctl-number.txt 2004-06-14 11:24:08 -07:00
>+++ b/Documentation/ioctl-number.txt 2004-06-14 11:24:08 -07:00
>@@ -189,3 +189,4 @@
> <mailto:michael.klein@puffin.lb.shuttle.de>
> 0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
> <mailto:aherrman@de.ibm.com>
>+0xDE all drivers/char/kmonitor <mailto:atul.sabharwal@intel.com>
>diff -Nru a/Documentation/kmonitor.txt b/Documentation/kmonitor.txt
>--- /dev/null Wed Dec 31 16:00:00 196900
>+++ b/Documentation/kmonitor.txt 2004-06-14 11:24:08 -07:00
>@@ -0,0 +1,119 @@
>+Enabling Non-intrusive Application Monitoring with kmonitor
>+-----------------------------------------------------------
>+The kmonitor driver implements a kernel level non-intrusive
>+mechanism for rapidly notifying a monitoring user space process
>+of key (process/thread creation/exit) kernel events.
>+
>+The monitoring user space process registers and deregisters for events via
>+a new misc char device using two new ioctl's. The kernel notifies the
>+monitoring process(es) of the events via a signal that the monitor specifies
>+during registration.
>+
>+An example of how this would be used in an minimal command line utility
>+to wait for an arbitrary process to exit:
>+
>+<snip>rest of required headers...</snip>
>+#include <linux/kmonitor.h>
>+
>+void target_exit_handler (int signum , struct siginfo * info, void * buf)
>+{
>+ /*
>+ * Since we only registered for one type of event,
>+ * KMONITOR_PROCESS_EXIT, on one process, then we already
>+ * know our target process has exited
>+ *
>+ * If we were doing something more complex, then the data in
>+ * info might be usefull:
>+ * 1. info->si_pid: process id of target process
>+ * 2. info->si_gid: group id of target process
>+ * 3. info->si_int: event that triggered this signal
>+ * (See include/linux/kmonitor.h for the list of events)
>+ *
>+ * The target process has exited, so we are done. Kmonitor
>+ * will do cleanup when we close the file descriptor for
>+ * /dev/kmonitor (which will happen automatically when we
>+ * exit.)
>+ */
>+ exit(0);
>+}
>+
>+int main(int argc, char *argv[])
>+{
>+<snip>...</snip>
>+
>+ /*
>+ * kmonitor will notify us that the target process has exited
>+ * by sending us a real-time signal with the payload containing
>+ * the event that triggered the notification.
>+ */
>+ action.sa_sigaction = target_exit_handler;
>+ action.sa_flags = SA_SIGINFO;
>+ if (-1 == sigaction(SIGRTMIN, &action, NULL)) {
>+ perror("sigaction");
>+ exit(-1);
>+ }
>+
>+ /*
>+ * The kmonitor is implemented as misc char device, so the
>+ * file that needs to be opened (assumed to be /dev/kmonitor
>+ * in this example) is a char device with a major number of 10
>+ * and a minor number of 221.
>+ *
>+ * mknod /dev/kmonitor c 10 221
>+ */
>+ fd = open("/dev/kmonitor", O_WRONLY);
>+ if (-1 == fd) {
>+ perror("open /dev/kmonitor");
>+ exit(-1);
>+ }
>+
>+ /*
>+ * To sign up for notification of an arbitrary event on an
>+ * arbitrary process then we send the KMONITOR_IOW_REGISTER
>+ * command to the device via the ioctl system call.
>+ *
>+ * We indicate the target process and event by sending a
>+ * kmonitor_cmd structure.
>+ *
>+ * NOTE: The 'type' field in the structure is actually
>+ * a bitmask, so it is possible to register for
>+ * multiple events on a given target process in one
>+ * ioctl call. The possible events are...
>+ * #define KMONITOR_THREAD_CREATE 0x01
>+ * #define KMONITOR_THREAD_ABORT 0x02
>+ * #define KMONITOR_THREAD_EXIT 0x04
>+ * #define KMONITOR_PROCESS_FORK 0x08
>+ * #define KMONITOR_PROCESS_ABORT 0x10
>+ * #define KMONITOR_PROCESS_EXEC 0x20
>+ * #define KMONITOR_PROCESS_EXIT 0x40
>+ */
>+ hdr.signal = SIGRTMIN;
>+ hdr.pid = args.pid;
>+ hdr.type = KMONITOR_PROCESS_EXIT;
>+ if (-1 == ioctl(fd, KMONITOR_IOW_REGISTER, &hdr)) {
>+ perror("ioctl");
>+ exit(-1);
>+ }
>+
>+ /*
>+ * In this very simple example all we need to do is wait
>+ * for a signal to be sent. The signal handler will exit
>+ * when it is notified of the target process exiting.
>+ */
>+ sigemptyset(&empty_mask);
>+ sigsuspend(&empty_mask);
>+
>+ /*
>+ * kmonitor will perform a cleanup of all request a given
>+ * monitoring process has made, so it is required to deregister
>+ * each of the specific request.
>+ *
>+ * If for some reason a monitoring process wanted to deregister
>+ * a specific request, then the procedure is just like registering,
>+ * other then the ioctl command is KMONITOR_IOW_DEREGISTER.
>+ */
>+ close(fd);
>+ exit (0);
>+}
>+
>+
>diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
>--- a/drivers/char/Kconfig 2004-06-14 11:24:08 -07:00
>+++ b/drivers/char/Kconfig 2004-06-14 11:24:08 -07:00
>@@ -974,5 +974,15 @@
> out to lunch past a certain margin. It can reboot the system
> or merely print a warning.
>
>+config KMONITOR
>+ bool "Kmonitor driver"
>+ help
>+ The kmonitor driver implements a kernel level non-intrusive
>+ mechanism for rapidly notifying a monitoring user space process
>+ of key (process/thread creation/exit) kernel events. For more
>+ info see Documentation/kmonitor.txt
>+
>+ If in doubt, say 'N'.
>+
> endmenu
>
>diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
>--- a/drivers/char/Makefile 2004-06-14 11:24:08 -07:00
>+++ b/drivers/char/Makefile 2004-06-14 11:24:08 -07:00
>@@ -79,6 +79,7 @@
> obj-$(CONFIG_DRM) += drm/
> obj-$(CONFIG_PCMCIA) += pcmcia/
> obj-$(CONFIG_IPMI_HANDLER) += ipmi/
>+obj-$(CONFIG_KMONITOR) += kmonitor.o
>
> obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
>
>diff -Nru a/drivers/char/kmonitor.c b/drivers/char/kmonitor.c
>--- /dev/null Wed Dec 31 16:00:00 196900
>+++ b/drivers/char/kmonitor.c 2004-06-14 11:24:08 -07:00
>@@ -0,0 +1,336 @@
>+/*
>+ * linux/kmonitor.c
>+ *
>+ * Copyright (C) 2004 Intel Corporation. All rights reserved.
>+ *
>+ * This program is free software; you can redistribute it and/or
>+ * modify it under the terms of the GNU General Public
>+ * License v2.0 as published by the Free Software Foundation;
>+ *
>+ * 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, write to the
>+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
>+ * Boston, MA 021110-1307, USA.
>+ *
>+ * Authors: Atul Sabharwal <atul.sabharwal@intel.com>
>+ *
>+ * The kmonitor driver implements a kernel level non-intrusive
>+ * mechanism for rapidly notifying a monitoring user space process
>+ * of key (process/thread creation/exit) kernel events.
>+ *
>+ * See Documentation/kmonitor.txt for more details
>+ */
>+
>+#include <linux/config.h>
>+#include <linux/module.h>
>+#include <linux/moduleparam.h>
>+#include <linux/fs.h>
>+#include <linux/hash.h>
>+#include <linux/init.h>
>+#include <linux/kmonitor.h>
>+#include <linux/miscdevice.h>
>+#include <linux/proc_fs.h>
>+#include <linux/sched.h>
>+#include <linux/types.h>
>+#include <linux/timer.h>
>+#include <asm/uaccess.h>
>+#include <asm/atomic.h>
>+
>+/*
>+ * kmonitor maintains a database of resources containing:
>+ * - the pid of the process being monitored (target)
>+ * - the pid of process that should be notified (monitor)
>+ * - an event mask
>+ * - a signal number to notify the monitor with
>+ * - a list_head
>+ *
>+ * To improve scalability, a hash of linked listed is maintained
>+ * with a per bucket read-write lock. KMONITOR_BITS defines the
>+ * order of the list size, so setting KMONITOR_BITS to 8 would translate
>+ * to 256 buckets. Using a hash of linked list improves the order of the
>+ * search from an O(n) to O(n/m) where n is the number of resources and
>+ * m is the number of buckets.
>+ *
>+ * Note that since we are using a per bucket read-write lock, the number
>+ * of buckets also as an effect on SMP performance since the smaller the
>+ * list of resources in each bucket, the less likely a processor will
>+ * spin waiting for another processor to finish writing to the same list.
>+ */
>+
>+struct kmonitor_bucket
>+{
>+ struct list_head list;
>+ rwlock_t lock;
>+};
>+
>+#define KMONITOR_BITS 0x8
>+
>+struct kmonitor_bucket kmonitor_resources[1<<KMONITOR_BITS];
>+
>+static inline unsigned long khash(pid_t target)
>+{
>+ return hash_long((unsigned long)target, KMONITOR_BITS);
>+}
>+
>+struct kmonitor_res
>+{
>+ struct list_head rlist;
>+ pid_t target;
>+ pid_t monitor;
>+ int signal;
>+ __u32 event_mask;
>+};
>+
>+#define to_kmonitor_res(r) \
>+ container_of(r, struct kmonitor_res, rlist);
>+
>+kmem_cache_t *kmonitor_cache;
>+
>+/*
>+ * kmonitor_active is used to improve the performance of searching
>+ * an empty resource database
>+ */
>+atomic_t kmonitor_active = { .counter = 0};
>+
>+/* #define DEBUG */
>+#ifdef DEBUG
>+#define DBG(format, arg...) printk("%s: " format "\n", __FUNCTION__ , ## arg)
>+#define TRACE(format, arg...) printk("%s(" format ")\n", __FUNCTION__, ## arg)
>+#else
>+#define DBG(format, arg...) do {} while(0);
>+#define TRACE(arg...) do {} while(0);
>+#endif
>+
>+static int kmonitor_add(pid_t target, int type, int signal)
>+{
>+ struct kmonitor_res *r;
>+ struct list_head *tmp;
>+ unsigned long bucket = khash(target);
>+
>+ TRACE("%i, %i, %i", target, type, signal);
>+ read_lock(&kmonitor_resources[bucket].lock);
>+ list_for_each(tmp, &kmonitor_resources[bucket].list) {
>+ r = to_kmonitor_res(tmp);
>+ if (r->monitor == current->pid && r->target == target) {
>+ /*
>+ * There is an existing resource for this
>+ * target/monitor combination so just flip
>+ * a bit in the event mask indicating that
>+ * this monitor also wants to be notified
>+ * for this type of event.
>+ */
>+ r->event_mask |= type;
>+ r->signal = signal;
>+ DBG("Added %i to existing res", type);
>+ read_unlock(&kmonitor_resources[bucket].lock);
>+ return 0;
>+ }
>+ }
>+ read_unlock(&kmonitor_resources[bucket].lock);
>+
>+ /*
>+ * This is the first event registered for this target
>+ * on this monitor. Allocate a new resource from our
>+ * cache and add the resource to the global list.
>+ *
>+ * Note: There is no race condition between the top half & the
>+ * bottom part of this function as if multiple monitors are active,
>+ * each will have a unique resource for itself. So, the function
>+ * is SMP safe.
>+ */
>+ r = kmem_cache_alloc(kmonitor_cache, SLAB_KERNEL);
>+ if (!r)
>+ return -ENOMEM;
>+
>+ r->target = target;
>+ r->monitor = current->pid;
>+ r->event_mask = type;
>+ r->signal = signal;
>+ write_lock(&kmonitor_resources[bucket].lock);
>+ list_add(&r->rlist, &kmonitor_resources[bucket].list);
>+ write_unlock(&kmonitor_resources[bucket].lock);
>+ return 0;
>+}
>+
>+static int kmonitor_remove(pid_t target, int type)
>+{
>+ struct list_head *tmp, *next;
>+ int ret = -EINVAL;
>+ int bucket = khash(target);
>+
>+ TRACE("%i, %i", target, type);
>+
>+ write_lock(&kmonitor_resources[bucket].lock);
>+ list_for_each_safe(tmp, next, &kmonitor_resources[bucket].list) {
>+ struct kmonitor_res *r = to_kmonitor_res(tmp);
>+ if (r->monitor == current->pid && r->target == target) {
>+ r->event_mask &= ~type;
>+ if (!r->event_mask) {
>+ /* No more events so go ahead and cleanup */
>+ list_del(tmp);
>+ kmem_cache_free(kmonitor_cache, r);
>+ }
>+ ret = 0;
>+ break;
>+ }
>+ }
>+
>+ write_unlock(&kmonitor_resources[bucket].lock);
>+ return ret;
>+}
>+
>+void __kmonitor_notify_event(struct task_struct *tsk, int type)
>+{
>+ struct siginfo info;
>+ struct list_head *tmp, *next;
>+ int bucket = khash(current->pid);
>+
>+ read_lock(&kmonitor_resources[bucket].lock);
>+ list_for_each_safe(tmp,next,&kmonitor_resources[bucket].list) {
>+ struct kmonitor_res *r = to_kmonitor_res(tmp);
>+ if (r->target == current->pid && type & r->event_mask) {
>+ info.si_signo = r->signal;
>+ info.si_code = SI_QUEUE;
>+ info.si_int = type;
>+ info.si_pid = tsk->pid;
>+ info.si_uid = tsk->uid;
>+ kill_proc_info(r->signal, &info, r->monitor);
>+ }
>+ }
>+ read_unlock(&kmonitor_resources[bucket].lock);
>+}
>+
>+static int kmonitor_open(struct inode *inode, struct file *file)
>+{
>+ atomic_inc(&kmonitor_active);
>+ return 0;
>+}
>+
>+static int kmonitor_release(struct inode *inode, struct file *file)
>+{
>+ struct list_head *tmp, *next;
>+ int i;
>+
>+ TRACE("%p, %p", inode, file);
>+ atomic_dec(&kmonitor_active);
>+
>+ /*
>+ * Remove any resources associated with this monitor
>+ */
>+ for (i=0; i<(1<<KMONITOR_BITS); i++) {
>+ write_lock(&kmonitor_resources[i].lock);
>+ list_for_each_safe(tmp, next, &kmonitor_resources[i].list) {
>+ struct kmonitor_res *r = to_kmonitor_res(tmp);
>+ if (r->monitor == current->pid) {
>+ list_del(tmp);
>+ kmem_cache_free(kmonitor_cache, r);
>+ }
>+ }
>+ write_unlock(&kmonitor_resources[i].lock);
>+ }
>+
>+ return 0;
>+}
>+
>+static int kmonitor_ioctl(struct inode *inode, struct file *file,
>+ unsigned int cmd, unsigned long arg)
>+{
>+ struct kmonitor_cmd hdr;
>+
>+ TRACE("%p, %p, %i, %i", inode, file, (int)cmd, (int)arg);
>+ if (copy_from_user((struct kmonitor_cmd *)&hdr,
>+ (struct kmonitor_cmd *)arg,
>+ sizeof(struct kmonitor_cmd)))
>+ return -EFAULT;
>+
>+ switch (cmd) {
>+ case KMONITOR_IOW_REGISTER:
>+ return kmonitor_add(hdr.pid, hdr.type, hdr.signal);
>+ case KMONITOR_IOW_DEREGISTER:
>+ return kmonitor_remove(hdr.pid, hdr.type);
>+ }
>+
>+ DBG("Unexpected ioctl, %i", cmd);
>+ return -EINVAL;
>+}
>+
>+static struct file_operations kmonitor_fops = {
>+ .owner = THIS_MODULE,
>+ .llseek = no_llseek,
>+ .open = kmonitor_open,
>+ .release = kmonitor_release,
>+ .ioctl = kmonitor_ioctl,
>+};
>+
>+static struct miscdevice kmonitor_miscdev = {
>+ .minor = KMONITOR_MINOR,
>+ .name = "kmonitor",
>+ .fops = &kmonitor_fops,
>+};
>+
>+static int __init kmonitor_init(void)
>+{
>+ int ret, i;
>+
>+ TRACE("void");
>+
>+ for (i=0; i<(1<<KMONITOR_BITS); i++) {
>+ INIT_LIST_HEAD(&kmonitor_resources[i].list);
>+ kmonitor_resources[i].lock = RW_LOCK_UNLOCKED;
>+ }
>+
>+ ret = misc_register(&kmonitor_miscdev);
>+ if (ret) {
>+ printk(KERN_ERR "unable to register kmonitor misc device\n");
>+ goto error_misc_drvr_register;
>+ }
>+
>+ kmonitor_cache = kmem_cache_create("kmonitor_res",
>+ sizeof(struct kmonitor_res), 0,
>+ SLAB_HWCACHE_ALIGN,
>+ NULL, NULL);
>+ if (!kmonitor_cache) {
>+ printk(KERN_ERR "unable to allocate kmonitor_cache\n");
>+ ret = -EINVAL;
>+ goto error_in_kmonitor_cache;
>+ }
>+
>+ return 0;
>+
>+ error_in_kmonitor_cache:
>+ misc_deregister(&kmonitor_miscdev);
>+ error_misc_drvr_register:
>+ return ret;
>+}
>+
>+static void __exit kmonitor_exit(void)
>+{
>+ struct list_head *tmp, *next;
>+ int i;
>+
>+ TRACE("void");
>+ misc_deregister(&kmonitor_miscdev);
>+ for (i=0; i<(1<<KMONITOR_BITS); i++) {
>+ write_lock(&kmonitor_resources[i].lock);
>+ list_for_each_safe(tmp, next, &kmonitor_resources[i].list) {
>+ struct kmonitor_res *r = to_kmonitor_res(tmp);
>+ list_del(tmp);
>+ kmem_cache_free(kmonitor_cache, r);
>+ }
>+ write_unlock(&kmonitor_resources[i].lock);
>+ }
>+ kmem_cache_destroy(kmonitor_cache);
>+}
>+
>+module_init(kmonitor_init);
>+module_exit(kmonitor_exit);
>+
>+MODULE_AUTHOR("Atul Sabharwal");
>+MODULE_DESCRIPTION("Kmonitor Char Driver");
>+MODULE_LICENSE("GPL");
>+MODULE_ALIAS_MISCDEV(KMONITOR_MINOR);
>diff -Nru a/fs/exec.c b/fs/exec.c
>--- a/fs/exec.c 2004-06-14 11:24:08 -07:00
>+++ b/fs/exec.c 2004-06-14 11:24:08 -07:00
>@@ -46,6 +46,7 @@
> #include <linux/security.h>
> #include <linux/syscalls.h>
> #include <linux/rmap.h>
>+#include <linux/kmonitor.h>
>
> #include <asm/uaccess.h>
> #include <asm/pgalloc.h>
>@@ -1144,6 +1145,7 @@
> free_arg_pages(&bprm);
>
> /* execve success */
>+ kmonitor_notify_event(current, KMONITOR_PROCESS_EXEC);
> security_bprm_free(&bprm);
> return retval;
> }
>diff -Nru a/include/linux/kmonitor.h b/include/linux/kmonitor.h
>--- /dev/null Wed Dec 31 16:00:00 196900
>+++ b/include/linux/kmonitor.h 2004-06-14 11:24:08 -07:00
>@@ -0,0 +1,62 @@
>+/*
>+ *
>+ * linux/kmonitor.h
>+ *
>+ * Copyright (C) 2004 Intel Corporation. All rights reserved.
>+ *
>+ * This program is free software; you can redistribute it and/or
>+ * modify it under the terms of the GNU General Public
>+ * License v2.0 as published by the Free Software Foundation;
>+ *
>+ * 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, write to the
>+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
>+ * Boston, MA 021110-1307, USA.
>+ *
>+ * Authors: Atul Sabharwal <atul.sabharwal@intel.com>
>+ *
>+ */
>+#ifndef _LINUX_KMONITOR_H_
>+#define _LINUX_KMONITOR_H_
>+
>+#include <asm/atomic.h>
>+
>+#define KMONITOR_THREAD_CREATE 0x01
>+#define KMONITOR_THREAD_ABORT 0x02
>+#define KMONITOR_THREAD_EXIT 0x04
>+#define KMONITOR_PROCESS_FORK 0x08
>+#define KMONITOR_PROCESS_ABORT 0x10
>+#define KMONITOR_PROCESS_EXEC 0x20
>+#define KMONITOR_PROCESS_EXIT 0x40
>+
>+struct kmonitor_cmd
>+{
>+ pid_t pid;
>+ int type;
>+ int signal;
>+};
>+
>+#define KMONITOR_IOW_REGISTER _IOW(0xDE, 1, struct kmonitor_cmd)
>+#define KMONITOR_IOW_DEREGISTER _IOW(0xDE, 2, struct kmonitor_cmd)
>+
>+#ifdef __KERNEL__
>+#include <linux/sysctl.h>
>+
>+extern atomic_t kmonitor_active;
>+extern void __kmonitor_notify_event(struct task_struct *tsk, int type);
>+
>+static inline void kmonitor_notify_event( struct task_struct *tsk, int type)
>+{
>+#ifdef CONFIG_KMONITOR
>+ if (atomic_read(&kmonitor_active))
>+ __kmonitor_notify_event(tsk, type);
>+#endif /* CONFIG_KMONITOR */
>+}
>+#endif /* __KERNEL__ */
>+#endif /* _LINUX_KMONITOR_H_ */
>+
>diff -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h
>--- a/include/linux/miscdevice.h 2004-06-14 11:24:08 -07:00
>+++ b/include/linux/miscdevice.h 2004-06-14 11:24:08 -07:00
>@@ -35,6 +35,7 @@
> #define SGI_USEMACLONE 151
>
> #define TUN_MINOR 200
>+#define KMONITOR_MINOR 221
>
> struct device;
>
>diff -Nru a/kernel/exit.c b/kernel/exit.c
>--- a/kernel/exit.c 2004-06-14 11:24:08 -07:00
>+++ b/kernel/exit.c 2004-06-14 11:24:08 -07:00
>@@ -22,6 +22,7 @@
> #include <linux/profile.h>
> #include <linux/mount.h>
> #include <linux/proc_fs.h>
>+#include <linux/kmonitor.h>
>
> #include <asm/uaccess.h>
> #include <asm/pgtable.h>
>@@ -748,6 +749,11 @@
> */
> _raw_write_unlock(&tasklist_lock);
> local_irq_enable();
>+
>+ if (tsk->pid == tsk->tgid)
>+ kmonitor_notify_event(tsk, KMONITOR_PROCESS_EXIT);
>+ else
>+ kmonitor_notify_event(tsk, KMONITOR_THREAD_EXIT);
>
> /* If the process is dead, release it - nobody will wait for it */
> if (state == TASK_DEAD)
>diff -Nru a/kernel/fork.c b/kernel/fork.c
>--- a/kernel/fork.c 2004-06-14 11:24:08 -07:00
>+++ b/kernel/fork.c 2004-06-14 11:24:08 -07:00
>@@ -41,6 +41,7 @@
> #include <asm/mmu_context.h>
> #include <asm/cacheflush.h>
> #include <asm/tlbflush.h>
>+#include <linux/kmonitor.h>
>
> /* The idle threads do not count..
> * Protected by write_lock_irq(&tasklist_lock)
>@@ -1167,6 +1168,11 @@
>
> if (!IS_ERR(p)) {
> struct completion vfork;
>+
>+ if (p->pid == p->tgid)
>+ kmonitor_notify_event(p, KMONITOR_PROCESS_FORK);
>+ else
>+ kmonitor_notify_event(p, KMONITOR_THREAD_CREATE);
>
> if (clone_flags & CLONE_VFORK) {
> p->vfork_done = &vfork;
>
>


-
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 14:03    [from the cache]
©2003-2014 Jasper Spaans. Advertise on this site