All of lore.kernel.org
 help / color / mirror / Atom feed
From: Atul Sabharwal <atul_sabharwal@linux.jf.intel.com>
To: linux-kernel@vger.kernel.org
Cc: faith@redhat.com
Subject: Re: [Announce] Non Invasive Kernel Monitor for threads/processes
Date: Tue, 15 Jun 2004 17:25:38 -0700	[thread overview]
Message-ID: <40CF9382.2010008@linux.jf.intel.com> (raw)
In-Reply-To: <20040615142304.5d9591d5.akpm@osdl.org>


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;
>  
>



  parent reply	other threads:[~2004-06-16  0:30 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-06-15 18:38 [Announce] Non Invasive Kernel Monitor for threads/processes Atul Sabharwal
2004-06-15 19:54 ` Atul Sabharwal
     [not found] ` <40CF5D39.1060701@linux.jf.intel.com>
     [not found]   ` <20040615142304.5d9591d5.akpm@osdl.org>
2004-06-16  0:25     ` Atul Sabharwal [this message]
2004-06-16  1:01       ` Rusty Lynch
2004-06-16  0:39 ` Chris Wright
2004-06-16 12:32 ` Karim Yaghmour
  -- strict thread matches above, loose matches on Subject: below --
2004-06-15 22:48 Sabharwal, Atul
2004-06-16  0:54 Sabharwal, Atul
2004-06-16  1:12 ` Chris Wright
2004-06-16 14:28 ` Chris Friesen
2004-06-16 17:36   ` Rusty Lynch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40CF9382.2010008@linux.jf.intel.com \
    --to=atul_sabharwal@linux.jf.intel.com \
    --cc=faith@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.