|
|
Subject: Re: [Kgem-devel] [PATCH][RFC][7/22] - KGEM - gem_eventfs.c - msg#00072
List: linux.kernel.mentors
On Thu, 2005-06-30 at 10:24 -0400, Bob Bennett wrote:
> diff -urNp linux-2.6.12.1/security/kgem/gem_eventfs.c
> linux-2.6.12.1.patched/security/kgem/gem_eventfs.c
> --- linux-2.6.12.1/security/kgem/gem_eventfs.c 1969-12-31
> 19:00:00.000000000 -0500
> +++ linux-2.6.12.1.patched/security/kgem/gem_eventfs.c 2005-06-29
> 10:21:45.000000000 -0400
> @@ -0,0 +1,356 @@
> +/*
> + * gem_eventfs.c - Process event requests through procfs.
please don't add more cruft to procfs.
> +/*
> + * eventfs_ioctl - Call an application-defined function. The functions are
> + * defined by calling gem_ioctl_define. If the request code does not
> + * match a command that has been defined, -EINVAL is returned.
Oh and please please don't add more ioctls, esp not generic ones like
this.
Was this page helpful?
Thread at a glance:
Previous Message by Date:
click to view message preview
Re: [PATCH][RFC][0/22] - Kernel Generalized Event Management
On Thu, 2005-06-30 at 10:11 -0400, Bob Bennett wrote:
> Following are a set of patches which provide a mechanism for allowing
> access control rules to be evaluated from user space. I have attempted
> to build this in such a way that there is some flexibility in the data
> that is associated with a particular security event. The main kernel
> module, gem_main_mod, exports a set of functions that can be called from
> an LSM to signal occurrence of a security event and get a response from
> the listener, and also registers a special filesystem, kgemfs, which is
> used by the user space application to send and receive data. This patch
> also includes a module, gem_hook_av_mod, which registers with LSM and
> provides on-access virus scanning ability for an Anti-Virus application
> in user space.
How do you deal with different namespaces? In the kernel you can.. but
in userspace.. .how does the ficticious (GPL ?) virus scanner know which
file is being accessed? From which namespace?
Next Message by Date:
click to view message preview
Re: [Kgem-devel] [PATCH][RFC][8/22] - KGEM - gem_hook_av.c
On Thu, 2005-06-30 at 10:25 -0400, Bob Bennett wrote:
> +
> +/*
> + * In the case that an LSM is already registered (This is most likely
> SELinux
> + * or capability), we save the current security_ops pointer and replace it
> + * with our pointer. We make sure that we subscribe to every available
> + * security_operations method, and call the function from the original LSM
> + * first. We also do not use the *_security pointers in any of the
> structures
> + * so as not to interfere with another LSM. The only problem will occur if
> + * the original LSM attempts to unregister itself, unregister_security()
> will
> + * fail with -EINVAL.
> + */
> +
> +static struct security_operations *secondary_ops;
> +static int security_ops_replaced = 0;
eewwww
I assume you don't want distro vendors to ever ship this stuff, right ?
Also... I suspect you care more about audit than LSM for anti virus
stuff..
> +/*
> + * find_vfsmount - Find the vfsmount structure that corresponds to a dentry
> + * This function is used for those cases where a callout does not provide a
> + * nameidata structure, and we need to generate a full path name for a
in which namespace do you provide the so called "full path name" ?
> +static int __init gem_hook_av_init(void)
> +{
> + int rc;
> + struct security_operations *prevops;
> +
> + secondary_ops = security_ops;
> +
> + rc = register_security(&gem_ops);
> +
> + if (rc) {
> + printk(KERN_ERR "%s: register_security() failed rc=%d\n",
> + THIS_MODULE->name,-rc);
> + printk(KERN_INFO "%s: replacing primary security module\n",
> + THIS_MODULE->name);
> + do {
> + secory_ops = security_ops;
> + prevops = (struct security_operations *)
> + cmpxchg(&security_ops,secondary_ops,&gem_ops);
> + } while (prevops != secondary_ops);
> + security_ops_replaced = 1;
> + }
Oh my god, you got to be kidding, right ?
Previous Message by Thread:
click to view message preview
Re: [Kgem-devel] [PATCH][RFC][7/22] - KGEM - gem_eventfs.c
diff -urNp linux-2.6.12.1/security/kgem/gem_eventfs.c
linux-2.6.12.1.patched/security/kgem/gem_eventfs.c
--- linux-2.6.12.1/security/kgem/gem_eventfs.c 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.12.1.patched/security/kgem/gem_eventfs.c 2005-06-29
10:21:45.000000000 -0400
@@ -0,0 +1,356 @@
+/*
+ * gem_eventfs.c - Process event requests through procfs.
+ *
+ * Copyright (C) 2004 Computer Associates
+ * Author/Maintainer - Bob Bennett <Robert.Bennett@xxxxxx>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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.
+ *
+ * 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 02111-1307 USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+#include "gem_event.h"
+#include "gem_internal.h"
+#include "eventdata.h"
+#include "gem_data.h"
+
+/*
+ * Function prototypes (forward declarations)
+ */
+
+int eventfs_open(struct inode *inode, struct file *file);
+ssize_t eventfs_read(struct file *file, char __user *page,
+ size_t count, loff_t *ppos);
+ssize_t eventfs_write(struct file *file, const char __user *page,
+ size_t count, loff_t *ppos);
+int eventfs_release(struct inode *inode, struct file *file);
+int eventfs_ioctl(struct inode *inode, struct file *file,
+ unsigned int request, unsigned long arg);
+
+struct file_operations eventfs_fops = {
+ .llseek = no_llseek,
+ .open = eventfs_open,
+ .read = eventfs_read,
+ .write = eventfs_write,
+ .ioctl = eventfs_ioctl,
+ .release = eventfs_release
+};
+
+struct gem_ioctl_def *gem_ioctl_tab = NULL;
+int gem_ioctl_num = 0;
+int gem_ioctl_max = 128;
+
+/*
+ * eventfs_ioctl - Call an application-defined function. The functions are
+ * defined by calling gem_ioctl_define. If the request code does not
+ * match a command that has been defined, -EINVAL is returned.
+ */
+
+int eventfs_ioctl(struct inode *inode, struct file *file,
+ unsigned int request, unsigned long arg)
+{
+ int buflen = 0;
+ int rc;
+ int i;
+ char *argbuf;
+ struct gem_listener *lp = file->private_data;
+
+ if (!lp)
+ return -EFAULT;
+
+ /* Check to see if this is an application-defined IOCTL. If so,
+ * call the appropriate function, otherwise return error.
+ */
+ rc = -EINVAL;
+ for (i = 0; i < gem_ioctl_num ; i++)
+ if (gem_ioctl_tab[i].ioctl_num == request)
+ rc = gem_ioctl_tab[i].ioctl_fn(inode, file,
+ request, arg);
+ if ( rc == -EINVAL )
+ printk(KERN_ERR "kgem: Invalid IOCTL (%d)\n",
+ (int) request);
+ return rc;
+}
+
+/*
+ * eventfs_open - Initialize connection from a passive event subscriber
+ */
+
+int eventfs_open(struct inode *inode, struct file *file)
+{
+ struct gem_listener *new_listener;
+
+ new_listener = alloc_listener(current->tgid);
+ if (!new_listener)
+ return -ENOMEM;
+
+ file->private_data = new_listener;
+ new_listener->fp = file;
+ set_task_kgem_exempt(current);
+ printk(KERN_INFO "kgem: New listener created, pid %d, comm %s\n",
+ current->pid,current->comm);
+
+ return 0;
+}
+
+/*
+ * eventfs_write - Receive subscription information from listener
+ * After the procfs entry is opened, a set of records is written by the
+ * subscriber. Each record defines an event that it wishes to listen for.
+ */
+
+ssize_t eventfs_write(struct file *file, const char __user *page,
+ size_t count, loff_t *ppos)
+{
+ struct gem_listener *lp;
+ struct event_subscribe *subp;
+ struct event_response eresp;
+ int rc;
+
+ lp = file->private_data;
+ if (!lp)
+ return -EFAULT;
+
+ if (count == sizeof(struct event_response))
+ subp = (struct event_subscribe *) &eresp;
+ else { /* kmalloc storage for larger structure */
+ subp = kmalloc(count, GFP_KERNEL);
+ if (subp == NULL)
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(subp,page,count))
+ return -EFAULT;
+ switch (subp->type) {
+
+ case EVENT_REC_RESPONSE:
+ rc = post_response_to_inst(lp,
+ (struct event_response *) subp);
+ break;
+
+ case EVENT_REC_SUBSCRIBE:
+ subp->type = count;
+ rc = new_event_subscription(lp,subp,NULL,NULL);
+ break;
+
+ default:
+ printk(KERN_ERR "gem_eventfs: write: invalid type %d\n",
+ subp->type);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc ? rc : count;
+}
+
+/*
+ * eventfs_read - Read information about the next kernel event which occurs.
+ * This function will block if there is not an event instance present in the
+ * queue. The event_inst will need to be requeued to the response queue.
+ */
+
+ssize_t eventfs_read(struct file *file, char __user *page,
+ size_t count, loff_t *ppos)
+{
+ struct gem_event_inst *event_inst;
+ struct gem_listener *listener;
+ struct gem_event *event;
+ struct event_rec *out = NULL;
+ int outlen;
+
+ listener = file->private_data;
+ if (!listener)
+ return -EFAULT;
+
+ if (count > PAGE_SIZE)
+ return -E2BIG;
+
+ if (file->f_flags & O_NONBLOCK)
+ listener->flags |= GEM_LISTENER_NONBLOCK;
+
+ /* Insure that only one thread does this at a time, if app is
+ multi-threaded. */
+ outlen = down_interruptible(&listener->readsem);
+ if (outlen)
+ return outlen;
+
+ if (listener->flags & GEM_LISTENER_SHUTDOWN) {
+ outlen = -EPIPE;
+ goto error_sem_cleanup;
+ }
+
+ out = (struct event_rec *)listener->iobuf;
+ event_inst = next_event_inst(listener); /* may block on this call */
+ if (!event_inst) {
+ outlen = -listener->errno;
+ goto error_sem_cleanup;
+ }
+
+ event = event_inst->event;
+
+ outlen = gen_event_rec(event_inst, out, count);
+ if (outlen < 0)
+ goto error_cleanup;
+
+ if (event_inst->flags & GEM_INST_ACTIVE_EVENT)
+ queue_inst_for_response(listener,event_inst);
+ else
+ free_event_inst(event_inst);
+
+ if (copy_to_user(page, out, outlen))
+ outlen = -EFAULT;
+ up(&listener->readsem);
+ return outlen;
+
+error_cleanup:
+ event_inst->errno = 0;
+ post_event_complete(event_inst);
+ free_event_inst(event_inst);
+error_sem_cleanup:
+ up(&listener->readsem);
+ return outlen;
+}
+
+/*
+ * eventfs_release - Terminate a listener and clean up all related data.
+ */
+
+int eventfs_release(struct inode *inode, struct file *file)
+{
+ struct gem_listener *listener;
+ int rc;
+
+ listener = file->private_data;
+ if (!listener)
+ return -EFAULT;
+
+ listener->flags |= GEM_LISTENER_SHUTDOWN;
+
+ rc = terminate_listener(listener);
+
+ file->private_data = NULL;
+
+ return rc;
+}
+
+/*
+ * The following functions are exported for use by other kernel modules that
+ * want to listen for events but do not want to incur the overhead of going
+ * through the procfs code.
+ */
+
+/*
+ * gem_event_open - Establish a connection with Generalized Event
+ * Management. Returns a pointer to the new gem_listener structure,
+ * which is hidden as a token.
+ */
+
+gem_token_t gem_event_open(void)
+{
+ struct file dummy_file;
+ struct inode dummy_inode;
+ int rc;
+
+ rc = eventfs_open(&dummy_inode,&dummy_file);
+
+ if (!rc) {
+ struct gem_listener *lp = dummy_file.private_data;
+ lp->fp = NULL;
+ return dummy_file.private_data;
+ }
+ else
+ return NULL;
+}
+
+/*
+ * eventfs_event_subscribe - Subscribe to an event. You have the option of
+ * specifying a callback function pointer and argument that will be called
+ * and passed every time an event occurs. If callback is NULL, you must use
+ * the eventfs_event_read and eventfs_event_response functions to process the
+ * events. The 'type' field of the event_subscribe structure must contain
+ * the total length of the structure, including the selection criteria, if
+ * any.
+ */
+
+int gem_event_subscribe(gem_token_t token, struct event_subscribe *subp,
+ callback_t callback, void *arg)
+{
+ struct gem_listener *lp = token;
+
+ if (!subp)
+ return -EINVAL;
+
+ return new_event_subscription(lp,subp,callback,arg);
+}
+
+/*
+ * gem_event_read - Read the next event data. This function may block
+ * if no events are in the queue.
+ */
+
+ssize_t gem_event_read(gem_token_t token, struct event_rec *recp,
+ int length)
+{
+ struct file dummy_file;
+
+ dummy_file.private_data = token;
+
+ return eventfs_read(&dummy_file, (char __user *) recp, length, NULL);
+}
+
+/*
+ * eventfs_event_write - Write a response for an active event.
+ */
+
+ssize_t gem_event_response(gem_token_t token, struct event_response *resp,
+ int length)
+{
+ return post_response_to_inst((struct gem_listener *) token, resp);
+}
+
+/*
+ * eventfs_event_release - Terminate connection with kgem
+ */
+
+int gem_event_release(gem_token_t token)
+{
+ return terminate_listener((struct gem_listener *)token);
+}
+
+
+EXPORT_SYMBOL_GPL(gem_event_open);
+EXPORT_SYMBOL_GPL(gem_event_subscribe);
+EXPORT_SYMBOL_GPL(gem_event_read);
+EXPORT_SYMBOL_GPL(gem_event_response);
+EXPORT_SYMBOL_GPL(gem_event_release);
Next Message by Thread:
click to view message preview
Re: [Kgem-devel] [PATCH][RFC][7/22] - KGEM - gem_eventfs.c
On Thu, 2005-06-30 at 13:19, Arjan van de Ven wrote:
> On Thu, 2005-06-30 at 10:24 -0400, Bob Bennett wrote:
> > diff -urNp linux-2.6.12.1/security/kgem/gem_eventfs.c
> > linux-2.6.12.1.patched/security/kgem/gem_eventfs.c
> > --- linux-2.6.12.1/security/kgem/gem_eventfs.c 1969-12-31
> > 19:00:00.000000000 -0500
> > +++ linux-2.6.12.1.patched/security/kgem/gem_eventfs.c 2005-06-29
> > 10:21:45.000000000 -0400
> > @@ -0,0 +1,356 @@
> > +/*
> > + * gem_eventfs.c - Process event requests through procfs.
>
> please don't add more cruft to procfs.
I ripped out the procfs stuff in favor of kgemfs. Forgot to change
the comment
>
> > +/*
> > + * eventfs_ioctl - Call an application-defined function. The functions
> > are
> > + * defined by calling gem_ioctl_define. If the request code does not
> > + * match a command that has been defined, -EINVAL is returned.
>
> Oh and please please don't add more ioctls, esp not generic ones like
> this.
Point taken.
>
>
>
|
|