From: "Török Edwin" <edwin@gurde.com>
To: Stephen Smalley <sds@tycho.nsa.gov>
Cc: linux-security-module@vger.kernel.org,
James Morris <jmorris@namei.org>,
linux-kernel@vger.kernel.org,
fireflier-devel@lists.sourceforge.net
Subject: Re: [RESEND][RFC][PATCH 2/7] implementation of LSM hooks
Date: Fri, 14 Apr 2006 23:01:09 +0300 [thread overview]
Message-ID: <200604142301.10188.edwin@gurde.com> (raw)
In-Reply-To: <1144863768.32059.67.camel@moss-spartans.epoch.ncsc.mil>
On Wednesday 12 April 2006 20:42, Stephen Smalley wrote:
> On Fri, 2006-04-07 at 21:38 +0300, Török Edwin wrote:
> > How could I write an SELinux policy that does this?
>
> I don't think you can without further changes to SELinux, as you are
> mutating object labels in response to events (aka floating labels).
Would there be a reason to implement floating labels in SELinux?
How can I substitute floating labels (i.e. what would be its closest
approximation)?
> But
> the real question is why do you want to, i.e. what is actual functional
> requirement,
Functional requirement:
- be able to control/know which programs have access to the internet
- be able to control/know which processes have access to a certain socket
- be able to control/know which processes share a socket, and which processes
are the only ones accessing a socket
I used the term 'control/know', because I don't actually want to restrict the
applications by using fireflier lsm, I just want it to provide information to
its userspace part.
-- plan for fireflier SELinux integration (fireflier target version 2.1)---
Possible approaches I thought of:
1) put programs needing to share a socket in the same domain, and match based
on the domain of the socket. But what happens if a program would need to be
in 2 or more domains (xinetd comes to mind)
But a problem remains: if there is a base policy that sets a context on a
program, and my module would try to set a domain for it too, won't they
conflict?
2) each program has its own domain, and xinetd is in a domain of its own, but
it has access to all the sockets of its childs (domains). The same for
postfix
Also run selinux in non-enforcing mode, with avc logging turned off. I only
need labeling, not restrictions.
3)Or should I assume, that if a user has a base policy set up, he has
configured that properly, and only those programs share sockets, that he
intends to?
In this case fireflier would need to do only this:
- if selinux is disabled, then run a policy generator, that generates a base
policy (not necessarely a module). fireflier will make sure user runs with
selinux enabled, avc logging off, enforcing off
- if selinux is enabled, fireflier won't do shared socket checks, assuming
that the policy will limit the sharing of sockets
Important question: can a file's context be set from the policy?
(without using setfiles, to relabel the file, the user might want to enable
selinux later, I don't want to mess up his labeling)
(this might sound silly: can a define a default auto-transition to a context?)
Looking at this now, it seems that 2+3 would be the best solution. Is there
anything I need to take care of, when starting to implement 2+3?
When (and if) (2+3) will be completed, fireflier lsm will make no sense, and
will be dropped. In the mean-time I'll try to make fireflier lsm usable.
----------------------------------------------------------
> not just how you have chosen to implement it.
>
> > diff -uprN null/hooks.c fireflier_lsm/hooks.c
> > --- null/hooks.c 1970-01-01 02:00:00.000000000 +0200
> > +++ fireflier_lsm/hooks.c 2006-04-07 17:43:37.000000000 +0300
> > + * This function might sleep.
> > + */
> > +static int task_alloc_security(struct task_struct *task)
> > +{
> > + struct fireflier_task_security_struct *tsec;
> > +
> > + tsec = kzalloc(sizeof(*tsec), GFP_ATOMIC);
>
> Why GFP_ATOMIC?
Oops, that should have been GFP_KERNEL
>
> > + if (!tsec)
> > + return -ENOMEM;
> > +
> > + tsec->magic = FIREFLIER_MAGIC;
>
> Drop the magic fields and tests; they are a relic of early LSM
> development and have been dropped from SELinux. Also you should
> naturally drop any fields you aren't using.
Good point.
>
> > + tsec_current = current->security;
> > + if(tsec_current) {
>
> Better if you can guarantee that all tasks have a security structure,
> either via early initialization
To have all tasks assigned a security structure, fireflier lsm needs to be
compiled into the kernel.
> or by processing them all during your
> own initialization.
I thought of this, see label_all_processes. Unfortunately I found no way of
actually doing this. I would need to iterate through the tasklist structure,
but the task_lock export is going to be removed from the kernel.
>
> > + return secondary_ops->task_alloc_security(tsk);
>
> Don't call a secondary module hook unless you truly need it and know
> that it can work. In particular, alloc_security hooks can't work
> properly without some mechanism for sharing the security field, so no
> point in doing this here.
Ok deleted most, except
bprm_set_security,bprm_apply_creds,bprm_post_apply_creds,socket_accept,file_receive,
socket_post_create
>
> > +static int fireflier_bprm_set_security(struct linux_binprm *bprm)
> > +{
> > + struct fireflier_bprm_security_struct *bsec;
> > +
> > + bsec = bprm->security;
> > + if(unlikely(!bsec)) {
> > + printk(KERN_DEBUG "Fireflier: bprm->security not set\n");
>
> Shouldn't be possible since you are allocating one in the other hook,
> right, so don't test for such conditions. You don't gain anything, and
> you may hide or lose useful info that you would have gotten from the
> Oops if it did occur.
Ok
> Naturally the printks have to go for real use.
I know
> <snip>
>
> > +/**
> > + * inode_update_perm - update the group SID of this inode
> > + * @tsk - the task that has accesses the inode
> > + * @inode - the inode who's SID has to be updated
> > + * A task has accessed this file, add the task's SID to the group SID of
> > tasks
> > + * accessing the file
> > + * based on inode_has_perm
> > + */
> > +static void inode_update_perm(struct task_struct *tsk,struct inode
> > *inode) +{
> > + struct fireflier_task_security_struct *tsec;
> > + struct fireflier_inode_security_struct *isec;
> > +
> > + tsec = tsk->security;
> > + isec = inode->i_security;
> > + if(!isec)
> > + return;
> > +
> > + if(unlikely(!tsec))
> > + isec->sid =
> > compute_inode_sid(isec->sid,FIREFLIER_SID_UNLABELED); + else
> > + isec->sid = compute_inode_sid(isec->sid,tsec->sid);
> > + printk(KERN_DEBUG "computed inode
> > sid: %ld->%d\n",inode->i_ino,isec->sid);
> > +}
>
> Locking? You are mutating the inode's SID, but many different tasks may
> be accessing (in this case, inheriting/receiving a descriptor to) the
> inode simultaneously.
Locking added. I use a lock every time the inode's sid is modified.
> Not clear that SIDs are even the right primitive
> for what you are doing here, essentially aggregating a list of all
> subjects that have gained a descriptor to the socket.
The term 'SID' might not fit what I actually do here, true. Should I call it:
access_id, ?
>
> > +static inline void file_update_perm(struct task_struct *tsk, struct
> > file *file)
> > +{
> > +
> > + struct fireflier_task_security_struct *tsec = tsk->security;
> > + struct fireflier_file_security_struct *fsec = file->f_security;
> > + struct dentry *dentry = file->f_dentry;
> > + struct inode *inode = dentry->d_inode;
> > +
> > + inode_update_perm(tsk, inode);
> > +
> > + if(!fsec)
> > + return;
> > + if(unlikely(!tsec))
> > + fsec->sid=compute_inode_sid(fsec->sid,FIREFLIER_SID_UNLABELED);
> > + else
> > + fsec->sid=compute_inode_sid(fsec->sid,tsec->sid);
>
> As before, locking required for safety. But also - where do you use
> this fsec->sid for anything (vs. the isec->sid)?
Thanks for noticing, I don't use that anywhere, inode security labels are
enough. Deleted now.
>
> > +static int fireflier_inode_getsecurity(struct inode *inode, const char
> > *name, void *buffer, size_t size, int err)
> > +{
>
> <snip>
>
> > + if (err > 0) {
> > + if ((len == err) && !(memcmp(context, buffer, len))) {
> > + /* Don't need to canonicalize value */
> > + rc = err;
> > + goto out_free;
> > + }
> > + memset(buffer, 0, size);
>
> IIUC, since you are dealing with sockets, this case is extraneous for
> you. In SELinux, it only exists for the case where you have an on-disk
> xattr that already matches the incore representation, and is actually
> eliminated in recent patches altogether.
Deleted. These are the disadvantages of not using a common code base, when
selinux gets updated, fireflier doesn't. It would be best if I could avoid
this situation. When (and if) I write the fireflier policy generator for
selinux, fireflier lsm won't be needed anymore.
> <snip>
P.S.: Thanks for taking time to provide detailed explanations. Sorry for my
late reply, I needed to think this over before replying.
I resend the hooks.c, and structures, with the modifications you suggested:
Cheers,
Edwin
---------
hooks.c | 631
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
structures.h | 62 +++++
2 files changed, 693 insertions(+)
diff -uprN null/hooks.c fireflier_lsm/hooks.c
--- null/hooks.c 1970-01-01 02:00:00.000000000 +0200
+++ fireflier_lsm/hooks.c 2006-04-14 22:53:40.000000000 +0300
@@ -0,0 +1,631 @@
+
+/*
+ * Fireflier security labeling module
+ *
+ *
+ * This file contains the Fireflier hook function implementations.
+ *
+ * Based on the SELinux hooks.c
+ *
+ * The Fireflier security module won't deny any operations
+ * Its sole purpose is to label processes, and files, so that the sk_filter
context match
+ * will be able to do context matching without selinux being active
+ *
+ * You shouldn't use SELinux and Fireflier LSM at the same time
+ * You can either have:
+ * - Having SELinux compiled in your kernel, and disabled at boot, and
fireflier enabled at boot /loaded as a module
+ * - Having SELinux compiled in your kernel, and enabled at boot, and
fireflier disabled on boot/not loaded.
+ *
+ * Currently you have to turn off the capability module
(capability.disable=1 on boot). See README for details
+ *
+ * Copyright (C) 2006 Török Edwin <edwin@gurde.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/security.h>
+
+#include <linux/mount.h>
+#include <linux/xattr.h>
+#include <net/sock.h>
+#include "fireflier_debug.h"
+#include "constants.h"
+#include "structures.h"
+#include "autolabel.h"
+
+//TODO: document all these functions here
+
+/* Original (dummy) security module. */
+static struct security_operations *original_ops = NULL;
+static struct security_operations *secondary_ops = NULL;
+static struct security_operations dummy_security_ops;
+
+
+#define XATTR_FIREFLIER_SUFFIX "fireflier"
+#define XATTR_NAME_FIREFLIER XATTR_SECURITY_PREFIX XATTR_FIREFLIER_SUFFIX
+
+
+/* module stacking operations */
+/**
+ * fireflier_register_security - register a stacked security module
+ * @name: the name of the secondary security module to register
+ * @ops: the stacked module's security_operations
+ */
+static int fireflier_register_security (const char *name, struct
security_operations *ops)
+{
+ if (secondary_ops != original_ops)
+ {
+ printk(KERN_INFO "%s: There is already a secondary
security "
+ "module registered.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ secondary_ops = ops;
+
+ printk(KERN_INFO "%s: Registering secondary module %s\n",
+ __FUNCTION__,
+ name);
+
+ return 0;
+}
+
+/**
+ * fireflier_unregister_security - unregister a stacked security
+ * @name: the name of the secondary security module to unregister
+ * @ops: the security_operations of the stacked module
+ */
+static int fireflier_unregister_security (const char *name, struct
security_operations *ops)
+{
+ if (ops != secondary_ops)
+ {
+ printk (KERN_INFO "%s: trying to unregister a security
module "
+ "that is not registered.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ secondary_ops = original_ops;
+
+ return 0;
+}
+
+
+/**
+ * task_alloc_security - allocate the security structure for a task
+ * @task: the task to allocate the security structure for
+ * Allocates and initializes the security structure of a task.
+ * Returns -ENOMEM in case of an allocation failure.
+ * This function might sleep.
+ */
+static int task_alloc_security(struct task_struct *task)
+{
+ struct fireflier_task_security_struct *tsec;
+
+ tsec = kzalloc(sizeof(*tsec), GFP_KERNEL);
+ if (!tsec)
+ return -ENOMEM;
+
+
+ tsec->task = task;
+ tsec->osid = tsec->sid = tsec->ptrace_sid = FIREFLIER_SID_UNLABELED;
+ task->security = tsec;
+
+ return 0;
+}
+
+/**
+ * task_free_security - free the security structure of a task
+ */
+static void task_free_security(struct task_struct *task)
+{
+ struct fireflier_task_security_struct *tsec = task->security;
+
+ if (!tsec)
+ return;
+
+ task->security = NULL;
+ kfree(tsec);
+}
+
+/**
+ * fireflier_task_alloc_security - allocate & initialize the security
structure of tsk from current
+ * @tsk: the task who's security context needs to be initialized
+ * In case of allocation failure returns -ENOMEM
+ * otherwise calls secondary security module.
+ * Might sleep.
+ */
+static int fireflier_task_alloc_security(struct task_struct *tsk)
+{
+ struct fireflier_task_security_struct *tsec_current, *tsec_tsk;
+
+
+ int rc;
+ rc = task_alloc_security(tsk);
+ if (rc)
+ return rc;
+ tsec_current = current->security;
+ if(tsec_current) {
+ tsec_tsk = tsk->security;
+
+ tsec_tsk->sid = tsec_current->sid;
+ tsec_tsk->osid = tsec_current->osid;
+ /* Retain ptracer SID across fork, if any.
+ This will be reset by the ptrace hook upon any
+ subsequent ptrace_attach operations. */
+ tsec_tsk->ptrace_sid = tsec_current->ptrace_sid;
+ }
+ //else printk(KERN_DEBUG "current has no security info\n");
+ return 0;
+}
+
+
+/**
+ * fireflier_bprm_alloc_security - allocate & initialize a linux_bprm
structure
+ * @bprm: the linux_bprm structure to initialize
+ * Returns -ENOMEM on allocation failure, otherwise calls stacked security
module.
+ * Might sleep.
+ */
+static int fireflier_bprm_alloc_security(struct linux_binprm *bprm)
+{
+ struct fireflier_bprm_security_struct *bsec;
+
+ bsec = kzalloc(sizeof(*bsec), GFP_KERNEL);
+ if (!bsec)
+ return -ENOMEM;
+
+
+ bsec->bprm = bprm;
+ bsec->sid = FIREFLIER_SID_UNLABELED;
+ bsec->set = 0;
+
+ bprm->security = bsec;
+
+ return 0;
+}
+
+/**
+ * fireflier_bprm_set_security - Sets the SID of bprm
+ * @bprm: linux_bprm structure, its SID will be calculated here
+ * This is where the (autolabeling) sid generation function is called, i.e.
+ * this function is responsible for computing the SID of the process that is
going to be executed
+ * Calls secondary security module.
+ * Can this sleep?
+ */
+static int fireflier_bprm_set_security(struct linux_binprm *bprm)
+{
+ struct fireflier_bprm_security_struct *bsec;
+
+ bsec = bprm->security;
+ if (bsec->set)
+ return secondary_ops->bprm_set_security(bprm);
+
+ bsec->sid = get_or_generate_sid(bprm->file,0);
+ printk(KERN_DEBUG "sid:%d\n",bsec->sid);
+ bsec->set = 1;
+ return secondary_ops->bprm_set_security(bprm);
+}
+
+/**
+ * fireflier_bprm_free_security - free the binbprm's security structure
+ * @bprm: linux_binprm structure, who's security structure is to be freed
+ */
+static void fireflier_bprm_free_security(struct linux_binprm *bprm)
+{
+ kfree(bprm->security);
+ bprm->security = NULL;
+}
+
+/**
+ * fireflier_bprm_apply_creds - compute the sid of the current task based on
bprm
+ * @bprm: linux_binprm structure
+ * @unsafe: reasons why the transition might be unsafe
+ * Compute the sid of a process being transformed by an execve operation
+ */
+static void fireflier_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
+{
+ struct fireflier_task_security_struct *tsec;
+ struct fireflier_bprm_security_struct *bsec;
+ u32 sid;
+
+
+ secondary_ops->bprm_apply_creds(bprm, unsafe);
+
+ tsec = current->security;
+ bsec = bprm->security;
+ sid = bsec->sid;
+
+
+ bsec->unsafe = 0;
+ if (tsec->sid != sid) {
+ /* hmmm unsafe&ptrace stuff.... need to think over this a bit*/
+ if(unsafe & (LSM_UNSAFE_SHARE | LSM_UNSAFE_PTRACE|LSM_UNSAFE_PTRACE_CAP))
+ {
+
+ printk(KERN_DEBUG "marking SID as unsafe\n");
+ bsec->unsafe=unsafe;
+ }
+
+ tsec->sid = sid;
+ }
+}
+
+
+/**
+ * inode_update_perm - update the group SID of this inode
+ * @tsk - the task that has accesses the inode
+ * @inode - the inode who's SID has to be updated
+ * A task has accessed this file, add the task's SID to the group SID of
tasks
+ * accessing the file
+ * based on inode_has_perm
+ */
+static void inode_update_perm(struct task_struct *tsk,struct inode *inode)
+{
+ struct fireflier_task_security_struct *tsec;
+ struct fireflier_inode_security_struct *isec;
+ u32 sid;
+
+ tsec = tsk->security;
+ isec = inode->i_security;
+ if(!isec)
+ return;
+
+ if(unlikely(!tsec))
+ sid = compute_inode_sid(isec->sid,FIREFLIER_SID_UNLABELED);
+ else
+ sid = compute_inode_sid(isec->sid,tsec->sid);
+ spin_lock(&isec->sid_lock);
+ isec->sid=sid;
+ spin_unlock(&isec->sid_lock);
+
+ printk(KERN_DEBUG "computed inode sid: %ld->%d\n",inode->i_ino,isec->sid);
+}
+
+
+
+/**
+ * file_update_perm - update the group SID of this file
+ * @tsk - the task that has accessed the file
+ * @file - the file that has been accessed
+ * A task has accessed this file, add the task's SID to the group SID of
tasks
+ * accessing the file
+ * Based on file_has_perm
+ */
+static inline void file_update_perm(struct task_struct *tsk, struct file
*file)
+{
+ inode_update_perm(tsk, file->f_dentry->d_inode);
+}
+
+
+
+
+/**
+ * update_files_auth - update the group SID of the files
+ * @files - a files_struct containing all files of the forked process
+ * Derived from fs/exec.c:flush_old_files.
+ * Should deal only with sockets
+ */
+static inline void update_files_auth(struct files_struct * files)
+{
+
+
+ struct file *file;
+ struct fdtable *fdt;
+ long j = -1;
+
+ /* Revalidate access to inherited open files. */
+ spin_lock(&files->file_lock);
+ for (;;)
+ {
+ unsigned long set, i;
+
+ j++;
+ i = j * __NFDBITS;
+ fdt = files_fdtable(files);
+ if (i >= fdt->max_fds || i >= fdt->max_fdset)
+ break;
+ set = fdt->open_fds->fds_bits[j];
+ if (!set)
+ continue;
+ spin_unlock(&files->file_lock);
+ for ( ; set ; i++,set >>= 1)
+ {
+ if (set & 1)
+ {
+ file = fget(i);
+ if (!file)
+ continue;
+ file_update_perm(current,file);
+ fput(file);
+ }
+ }
+ spin_lock(&files->file_lock);
+ }
+ spin_unlock(&files->file_lock);
+}
+
+
+/**
+ * fireflier_bprm_post_apply_creds - updates files' SID
+ * @bprm - a linux_bprm structure
+ * update the security field of bprm
+ */
+static void fireflier_bprm_post_apply_creds(struct linux_binprm *bprm)
+{
+ struct fireflier_task_security_struct *tsec = current->security;
+ struct fireflier_bprm_security_struct *bsec = bprm->security;
+ secondary_ops->bprm_post_apply_creds(bprm);
+
+ if(bsec->unsafe)
+ {
+
+ printk(KERN_DEBUG "computing unsafe SID\n");
+ tsec->sid = get_or_generate_unsafe_sid(tsec->sid,bsec->unsafe);
+
+ }
+
+ ff_debug_map_pidsid(tsec->sid);
+ if (tsec->osid == tsec->sid)
+ return;
+ //SID changed, so update the files's SIDs, i.e. turn them into group SIDs
+ update_files_auth(current->files);
+}
+
+/**
+ * fireflier_inode_alloc_security - allocate the security structure of an
inode
+ * @inode - inode
+ * allocate the security field of inode
+ */
+static int inode_alloc_security(struct inode *inode)
+{
+ struct fireflier_task_security_struct *tsec = current->security;
+ struct fireflier_inode_security_struct *isec;
+
+ isec = kzalloc(sizeof(struct fireflier_inode_security_struct), GFP_KERNEL);
+ if (!isec)
+ return -ENOMEM;
+
+ isec->inode = inode;
+ //isec->sclass = SECCLASS_FILE;
+ if (tsec)
+ isec->sid = tsec->sid;
+ else
+ isec->sid = FIREFLIER_SID_UNLABELED;
+ spin_lock_init(&isec->sid_lock);
+ inode->i_security = isec;
+ return 0;
+}
+
+/**
+ * fireflier_inode_free_security - free the security structure of the inode
+ * @inode - inode
+ * free the security field of inode
+ */
+static void fireflier_inode_free_security(struct inode *inode)
+{
+ struct fireflier_inode_security_struct *isec = inode->i_security;
+// struct fireflier_superblock_security_struct *sbsec =
inode->i_sb->s_security;
+
+ if (!isec)// || !sbsec)
+ return;
+
+ inode->i_security = NULL;
+ kfree(isec);
+}
+
+static int fireflier_socket_accept(struct socket *sock, struct socket
*newsock)
+{
+ struct fireflier_inode_security_struct *isec = SOCK_INODE(sock)->i_security;
+ struct inode* newinode = SOCK_INODE(newsock);
+ struct fireflier_inode_security_struct *newisec;
+
+ inode_alloc_security(newinode);
+
+ newisec = newinode->i_security;
+ spin_lock(&isec->sid_lock);
+ newisec->sid = isec->sid;
+ spin_unlock(&isec->sid_lock);
+
+ return secondary_ops->socket_accept(sock,newsock);
+}
+
+/** fireflier_file_receive - file received (via SysV IPC?)
+ * update group SID of file
+ */
+
+static int fireflier_file_receive(struct file* file)
+{
+ file_update_perm(current,file);
+ return secondary_ops->file_receive(file);
+}
+
+/*
+ * Copy the in-core inode security context value to the user. If the
+ * getxattr() prior to this succeeded, check to see if we need to
+ * canonicalize the value to be finally returned to the user.
+ *
+ * Permission check is handled by selinux_inode_getxattr hook.
+ */
+static int fireflier_inode_getsecurity(struct inode *inode, const char *name,
void *buffer, size_t size, int err)
+{
+ struct fireflier_inode_security_struct *isec = inode->i_security;
+ char *context=NULL;/* required!*/
+ unsigned len;
+ int rc;
+
+ if (strcmp(name, XATTR_FIREFLIER_SUFFIX) || !isec) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
+
+ rc = fireflier_sid_to_context(isec->sid, &context, &len);
+ if (rc)
+ goto out;
+
+ /* Probe for required buffer size */
+ if (!buffer || !size) {
+ rc = len;
+ goto out_free;
+ }
+
+ if (size < len) {
+ rc = -ERANGE;
+ goto out_free;
+ }
+
+ memcpy(buffer, context, len);
+ rc = len;
+ out_free:
+ kfree(context);
+ out:
+ return 0;
+}
+
+static int fireflier_inode_listsecurity(struct inode *inode, char *buffer,
size_t buffer_size)
+{
+ if(inode->i_security)
+ {
+
+ const int len = sizeof(XATTR_NAME_FIREFLIER);
+ if (buffer && len <= buffer_size)
+ memcpy(buffer, XATTR_NAME_FIREFLIER, len);
+ return len;
+ }
+ else
+ return 0;
+
+
+}
+
+static void fireflier_socket_post_create(struct socket *sock, int family,
+ int type, int protocol, int kern)
+{
+ struct fireflier_inode_security_struct *isec;
+ struct fireflier_task_security_struct *tsec = current->security;
+ struct inode* inode=SOCK_INODE(sock);
+
+ secondary_ops->socket_post_create(sock,family,type,protocol,kern);
+
+ inode_alloc_security(inode);
+ isec = inode->i_security;
+
+ spin_lock(&isec->sid_lock);
+ isec->sid = kern ? FIREFLIER_SECINITSID_KERNEL : tsec->sid;
+ spin_unlock(&isec->sid_lock);
+
+ return;
+}
+
+/**
+ * fireflier_ops - our security_operations hooks
+ * Unused security hooks will be automatically redirected to the dummy
security module
+ * Does the dummy module call the secondary module? Maybe we should implement
all the hooks, and call
+ * the secondary module
+ */
+static struct security_operations fireflier_ops =
+{
+ .bprm_alloc_security = fireflier_bprm_alloc_security,
+ .bprm_free_security = fireflier_bprm_free_security,
+ .bprm_apply_creds = fireflier_bprm_apply_creds,
+ .bprm_post_apply_creds = fireflier_bprm_post_apply_creds,
+ .bprm_set_security = fireflier_bprm_set_security,
+ .inode_free_security = fireflier_inode_free_security,
+ .inode_getsecurity = fireflier_inode_getsecurity,
+ .inode_listsecurity = fireflier_inode_listsecurity,
+ .file_receive = fireflier_file_receive,
+ .task_alloc_security = fireflier_task_alloc_security,
+ .task_free_security = task_free_security,
+ .socket_post_create = fireflier_socket_post_create,
+ .socket_accept = fireflier_socket_accept,
+ .register_security = fireflier_register_security,
+ .unregister_security = fireflier_unregister_security,
+};
+
+/**
+ * stacked - is a secondary module registered
+ */
+static int stacked=0;
+
+/**
+ * label_all_processes - labels already running processes
+ * Can this be done at all? Or do we need to have fireflier loaded during
boot?
+ */
+static void label_all_processes(void)
+{
+ /* Labeling running processes without using the task_lock seems not possible
for now*/
+ /* TODO: label processes that are already running */
+ /* TODO: prevent processes from being spawned while we label the
running ones */
+ /* TODO Priority:Low, it works without this too */
+}
+
+/**
+ * fireflier_cleanup - Cleans up fireflier module
+ * Unregisters security module
+ */
+static void __exit fireflier_cleanup(void)
+{
+ if(stacked) {
+ if(mod_unreg_security("fireflier",&fireflier_ops))
+ printk(KERN_ERR "Fireflier: Error unregistering stacked security module.
\n");
+ }
+ else
+ if(unregister_security(&fireflier_ops))
+ printk(KERN_ERR "Fireflier: Error unregistering security module.\n");
+}
+
+int ff_debug;
+module_param(ff_debug,int,0);
+MODULE_PARM_DESC(ff_debug,"Enable debug info dumping in debugfs");
+/**
+ * fireflier_init - module loading initialization
+ * Registers fireflier as primary or secondary security module
+ */
+static int __init fireflier_init(void)
+{
+ /*Register security_ops with kernel*/
+ int err;
+
+ original_ops = security_ops;
+ /* initialize dummy_security_ops to dummy ops */
+ register_security(&dummy_security_ops);
+ unregister_security(&dummy_security_ops);
+ secondary_ops = &dummy_security_ops;//avoid recursion with capability
module
+ if (!secondary_ops) {
+ printk (KERN_ERR "Fireflier: No initial security
operations\n");
+ return -EAGAIN;
+ }
+ if ((err=register_security (&fireflier_ops))) {
+ printk(KERN_INFO "Fireflier: Unable to register as primary
security module. Attempting to register as stacked security module\n");
+ stacked=1;
+ if((err=mod_reg_security("fireflier",&fireflier_ops))) {
+ printk(KERN_ERR "Fireflier: Unable to register with
kernel.\n");
+ return err;
+ }
+ }
+ else
+ stacked=0;
+ /* Do initialization */
+ if((err=autolabel_init())) {
+ printk(KERN_ERR "Fireflier: autolabeling initialization failed (OOM?)\n");
+ fireflier_cleanup();
+ return err;
+ }
+ label_all_processes();
+
+ /* Debugging stuff */
+ ff_debug_startup();
+
+ return 0;
+}
+
+security_initcall(fireflier_init);
+module_exit(fireflier_cleanup);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Török Edwin <edwin@gurde.com>");
+MODULE_DESCRIPTION("Fireflier security module");
+MODULE_VERSION("0.01");
+
diff -uprN null/structures.h fireflier_lsm/structures.h
--- null/structures.h 1970-01-01 02:00:00.000000000 +0200
+++ fireflier_lsm/structures.h 2006-04-14 22:48:13.000000000 +0300
@@ -0,0 +1,62 @@
+/*
+ * Fireflier security labeling module
+ *
+ *
+ * This file contains the Fireflier hook function implementations.
+ *
+ * Based on the SELinux hooks.c
+ *
+ * Copyright (C) 2006 Török Edwin <edwin@gurde.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ */
+#ifndef _FF_STRUCTURES_H_
+#define _FF_STRUCTURES_H_
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include "constants.h"
+/* Structures copied from SELinux, and prefixed with fireflier_ to avoid
conflicts
+ * I don't want to use SELinux internal structures.
+ */
+
+
+struct fireflier_task_security_struct {
+ struct task_struct *task; /* back pointer to task object */
+ u32 sid; /* current SID */
+ u32 osid; /* SID prior to execve */
+ u32 ptrace_sid; /* SID of ptrace parent */
+};
+
+struct fireflier_inode_security_struct {
+ struct inode *inode; /* back pointer to inode object */
+ spinlock_t sid_lock;
+ u32 sid; /* SID of this object */
+};
+
+struct fireflier_bprm_security_struct {
+ struct linux_binprm *bprm; /* back pointer to bprm object */
+ u32 sid; /* SID for transformed process */
+ unsigned char set;
+
+ /*
+ * unsafe is used to share failure information from bprm_apply_creds()
+ * to bprm_post_apply_creds().
+ */
+ char unsafe;
+};
+/**
+ * getsid_safe - returns the SID, safe to be called with a NULL pointer
+ * @tsec: a task's security structure to get the SID from, it can be NULL
+ */
+static inline u32 getsid_safe(const struct fireflier_task_security_struct*
tsec)
+{
+ if(likely(tsec))
+ return tsec->sid;
+ else
+ return FIREFLIER_SID_UNLABELED;
+}
+
+#endif
next prev parent reply other threads:[~2006-04-14 20:02 UTC|newest]
Thread overview: 272+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-02 9:40 [RFC] packet/socket owner match (fireflier) using skfilter Török Edwin
2006-04-03 15:18 ` James Morris
2006-04-03 15:39 ` Török Edwin
2006-04-05 15:06 ` Stephen Smalley
2006-04-07 17:34 ` Török Edwin
2006-04-07 18:24 ` [RFC][PATCH 0/7] fireflier LSM for labeling sockets based on its creator (owner) Török Edwin
2006-04-07 18:27 ` [RFC][PATCH 1/7] " Török Edwin
2006-04-12 19:11 ` Stephen Smalley
2006-04-14 20:02 ` Török Edwin
2006-04-07 18:38 ` [RFC][PATCH 2/7] implementation of LSM hooks Török Edwin
2006-04-12 17:42 ` Stephen Smalley
2006-04-14 20:01 ` Török Edwin [this message]
2006-04-17 16:06 ` [RESEND][RFC][PATCH " Stephen Smalley
2006-04-17 16:23 ` Christoph Hellwig
2006-04-17 17:03 ` Stephen Smalley
2006-04-17 17:08 ` Arjan van de Ven
2006-04-17 17:33 ` Christoph Hellwig
2006-04-17 18:02 ` Casey Schaufler
2006-04-17 18:15 ` Stephen Smalley
2006-04-17 19:26 ` Serge E. Hallyn
2006-04-17 19:31 ` James Morris
2006-04-17 19:47 ` Serge E. Hallyn
2006-04-17 20:02 ` Stephen Smalley
2006-04-19 14:52 ` David Safford
2006-04-19 15:26 ` Stephen Smalley
2006-04-19 17:57 ` Emily Ratliff
2006-04-19 18:33 ` Stephen Smalley
2006-04-20 12:27 ` Stephen Smalley
2006-04-19 15:47 ` Stephen Smalley
2006-04-17 22:15 ` Gerrit Huizenga
2006-04-17 22:48 ` Alan Cox
2006-04-17 22:58 ` James Morris
2006-04-18 2:00 ` Crispin Cowan
2006-04-17 22:55 ` Christoph Hellwig
2006-04-18 1:44 ` Gerrit Huizenga
2006-04-18 11:58 ` Christoph Hellwig
2006-04-18 16:50 ` Gerrit Huizenga
2006-04-18 17:27 ` Karl MacMillan
2006-04-18 19:31 ` Crispin Cowan
2006-04-18 19:50 ` Arjan van de Ven
2006-04-18 20:13 ` [Fireflier-devel] " Török Edwin
2006-04-18 20:31 ` Alan Cox
2006-04-18 19:33 ` [Fireflier-devel] Re: [RESEND][RFC][PATCH 2/7] implementationof " David Lang
2006-04-18 20:42 ` [Fireflier-devel] Re: [RESEND][RFC][PATCH 2/7] implementation of " Serge E. Hallyn
2006-04-18 20:23 ` Serge E. Hallyn
2006-04-19 18:32 ` Crispin Cowan
2006-04-19 18:48 ` Arjan van de Ven
2006-04-19 19:50 ` Jan Engelhardt
2006-04-19 18:50 ` Valdis.Kletnieks
2006-04-19 23:24 ` Tony Jones
2006-04-18 20:14 ` Stephen Smalley
2006-04-18 20:35 ` Crispin Cowan
2006-04-18 21:07 ` Greg KH
2006-04-19 12:22 ` Stephen Smalley
2006-04-18 20:26 ` Alan Cox
2006-04-18 20:57 ` Crispin Cowan
2006-04-18 21:36 ` James Morris
2006-04-18 23:09 ` Crispin Cowan
2006-04-18 23:27 ` Chris Wright
2006-04-18 23:57 ` James Morris
2006-04-19 1:48 ` Casey Schaufler
2006-04-19 6:40 ` Kyle Moffett
2006-04-19 6:56 ` Valdis.Kletnieks
2006-04-19 11:41 ` Serge E. Hallyn
2006-04-19 15:51 ` Valdis.Kletnieks
2006-04-19 16:00 ` Gene Heskett
2006-04-20 6:51 ` Kyle Moffett
2006-04-20 12:40 ` Stephen Smalley
2006-04-21 1:00 ` Nix
2006-04-21 14:24 ` Stephen Smalley
2006-04-24 8:14 ` Lars Marowsky-Bree
2006-04-25 0:19 ` Valdis.Kletnieks
2006-04-25 7:21 ` Nix
2006-04-19 7:44 ` Arjan van de Ven
2006-04-19 11:53 ` Serge E. Hallyn
2006-04-19 12:56 ` Stephen Smalley
2006-04-19 12:54 ` Stephen Smalley
2006-04-19 16:42 ` Casey Schaufler
2006-04-19 18:01 ` Stephen Smalley
2006-04-20 4:10 ` Casey Schaufler
2006-04-20 4:29 ` James Morris
2006-04-20 4:56 ` Chris Wright
2006-04-18 23:16 ` Casey Schaufler
2006-04-18 23:19 ` Christoph Hellwig
2006-04-19 5:22 ` Arjan van de Ven
2006-04-19 12:40 ` Stephen Smalley
2006-04-18 23:09 ` Casey Schaufler
2006-04-19 5:23 ` Arjan van de Ven
2006-04-18 18:46 ` Alan Cox
2006-04-18 19:59 ` Serge E. Hallyn
2006-04-18 20:20 ` Stephen Smalley
2006-04-18 20:36 ` Serge E. Hallyn
2006-04-18 23:00 ` Casey Schaufler
2006-04-19 9:03 ` Bernhard R. Link
2006-04-18 21:38 ` Kurt Garloff
2006-04-19 7:04 ` Valdis.Kletnieks
2006-04-19 7:36 ` Arjan van de Ven
2006-04-19 12:10 ` Serge E. Hallyn
2006-04-19 12:55 ` Yuichi Nakamura
2006-04-19 15:44 ` Greg KH
2006-04-19 16:02 ` Stephen Smalley
2006-04-19 16:06 ` Greg KH
2006-04-19 21:10 ` Crispin Cowan
2006-04-19 21:48 ` Yuichi Nakamura
2006-04-20 12:44 ` Karl MacMillan
2006-04-19 13:09 ` Stephen Smalley
2006-04-18 11:59 ` Stephen Smalley
2006-04-17 23:09 ` Chris Wright
2006-04-17 19:37 ` Stephen Smalley
2006-04-18 13:05 ` Kazuki Omo(Company)
2006-04-18 13:37 ` James Morris
2006-04-18 14:45 ` Greg KH
2006-04-18 15:51 ` Casey Schaufler
2006-04-18 16:07 ` Greg KH
2006-04-17 19:20 ` Time to remove LSM (was Re: [RESEND][RFC][PATCH 2/7] implementation of LSM hooks) James Morris
2006-04-17 19:51 ` Greg KH
2006-04-17 20:08 ` Arjan van de Ven
2006-04-17 21:26 ` Alan Cox
2006-04-17 23:26 ` Casey Schaufler
2006-04-18 2:29 ` Valdis.Kletnieks
2006-04-18 12:22 ` Serge E. Hallyn
2006-04-18 12:59 ` Stephen Smalley
[not found] ` <20060418132121.GE7562@sergelap.austin.ibm.com>
2006-04-18 13:40 ` Stephen Smalley
2006-04-18 20:13 ` Crispin Cowan
2006-04-18 23:01 ` Valdis.Kletnieks
2006-04-20 0:19 ` Crispin Cowan
2006-04-20 15:27 ` Valdis.Kletnieks
2006-04-21 15:23 ` Ken Brush
2006-04-21 19:51 ` Valdis.Kletnieks
2006-04-22 20:52 ` Ken Brush
2006-04-23 9:45 ` Valdis.Kletnieks
2006-04-24 8:24 ` Lars Marowsky-Bree
2006-04-24 12:42 ` Alan Cox
2006-04-24 12:44 ` Lars Marowsky-Bree
2006-04-24 12:45 ` Olivier Galibert
2006-04-24 12:54 ` Arjan van de Ven
2006-04-24 13:09 ` Serge E. Hallyn
2006-04-24 13:16 ` Arjan van de Ven
2006-04-24 13:29 ` Serge E. Hallyn
2006-04-24 13:40 ` Arjan van de Ven
2006-04-24 13:54 ` Serge E. Hallyn
2006-04-24 14:07 ` Arjan van de Ven
2006-04-25 19:06 ` Serge E. Hallyn
2006-04-25 4:07 ` Casey Schaufler
2006-04-24 14:08 ` Olivier Galibert
2006-04-25 16:29 ` Stephen Smalley
2006-04-25 22:26 ` Olivier Galibert
2006-04-26 12:14 ` Stephen Smalley
2006-04-26 16:03 ` Olivier Galibert
2006-04-27 6:56 ` Thomas Bleher
2006-04-24 12:55 ` Serge E. Hallyn
2006-04-24 12:56 ` Serge E. Hallyn
2006-04-24 14:02 ` Alan Cox
2006-04-24 14:04 ` Serge E. Hallyn
2006-04-24 14:31 ` Alan Cox
2006-04-24 14:28 ` Serge E. Hallyn
2006-04-24 14:45 ` David Lang
2006-04-24 16:50 ` Arjan van de Ven
2006-04-25 16:31 ` Stephen Smalley
2006-04-25 16:23 ` Stephen Smalley
2006-04-25 2:06 ` Valdis.Kletnieks
2006-04-25 7:36 ` Lars Marowsky-Bree
2006-04-20 21:13 ` Pavel Machek
2006-04-23 3:50 ` Crispin Cowan
2006-04-23 9:33 ` Valdis.Kletnieks
2006-04-23 14:58 ` Thomas Bleher
2006-04-24 8:28 ` Lars Marowsky-Bree
2006-04-24 8:37 ` Arjan van de Ven
2006-04-24 8:54 ` Lars Marowsky-Bree
2006-04-24 9:12 ` Arjan van de Ven
2006-04-25 0:31 ` Valdis.Kletnieks
2006-04-20 17:46 ` Pavel Machek
2006-04-18 2:38 ` Valdis.Kletnieks
2006-04-19 8:16 ` Jan Engelhardt
2006-04-19 15:40 ` Greg KH
2006-04-19 16:33 ` James Morris
2006-04-19 18:10 ` Greg KH
2006-04-19 19:33 ` Chris Wright
2006-04-20 12:39 ` Stephen Smalley
2006-04-20 12:51 ` Serge E. Hallyn
2006-04-20 15:00 ` Removing EXPORT_SYMBOL(security_ops) (was Re: Time to remove LSM) Greg KH
2006-04-20 14:20 ` Stephen Smalley
2006-04-20 16:15 ` Greg KH
2006-04-20 16:23 ` Christoph Hellwig
2006-04-20 16:34 ` Stephen Smalley
2006-04-20 16:46 ` Greg KH
2006-04-20 17:00 ` Stephen Smalley
2006-04-20 17:01 ` [PATCH] make security_ops EXPORT_SYMBOL_GPL() Greg KH
2006-04-20 18:08 ` Linus Torvalds
2006-04-20 19:34 ` Greg KH
2006-04-21 16:50 ` Greg KH
2006-04-21 17:34 ` Chris Wright
2006-04-20 17:02 ` Removing EXPORT_SYMBOL(security_ops) (was Re: Time to remove LSM) Tony Jones
2006-04-20 20:14 ` Chris Wright
2006-04-19 19:22 ` Time to remove LSM (was Re: [RESEND][RFC][PATCH 2/7] implementation of LSM hooks) Jan Engelhardt
2006-04-19 20:48 ` Greg KH
2006-04-19 20:59 ` Serge E. Hallyn
2006-04-19 21:08 ` Randy.Dunlap
2006-04-19 16:00 ` Arjan van de Ven
2006-04-19 19:06 ` Jan Engelhardt
2006-04-19 20:11 ` Greg KH
2006-04-19 20:52 ` Randy.Dunlap
2006-04-19 20:54 ` Arjan van de Ven
2006-04-19 21:05 ` Jan Engelhardt
2006-04-20 12:20 ` Stephen Smalley
2006-04-21 13:30 ` Jan Engelhardt
2006-04-21 15:05 ` Greg KH
2006-05-01 13:45 ` [PATCH 0/4] MultiAdmin LSM Jan Engelhardt
2006-05-01 13:48 ` [PATCH 1/4] security_cap_extra() and more Jan Engelhardt
2006-05-01 13:49 ` [PATCH 2/4] Use of capable_light() Jan Engelhardt
2006-05-01 13:49 ` [PATCH 3/4] task_post_setgid() Jan Engelhardt
2006-05-01 13:50 ` [PATCH 4/4] MultiAdmin module Jan Engelhardt
2006-05-01 14:56 ` James Morris
2006-05-01 15:05 ` Greg KH
2006-05-01 13:50 ` [PATCH 0/4] MultiAdmin LSM Arjan van de Ven
2006-05-01 16:03 ` [PATCH 4a/4] MultiAdmin LSM (LKCS'ed) Jan Engelhardt
2006-05-01 16:47 ` Greg KH
2006-05-01 17:42 ` Jan Engelhardt
2006-05-01 18:07 ` Greg KH
2006-05-01 20:19 ` Jan Engelhardt
2006-05-01 21:47 ` Adrian Bunk
2006-05-01 20:56 ` [PATCH 0/4] MultiAdmin LSM Pavel Machek
2006-05-02 4:22 ` James Morris
2006-04-21 16:25 ` Time to remove LSM (was Re: [RESEND][RFC][PATCH 2/7] implementation of LSM hooks) Stephen Smalley
2006-04-21 18:57 ` Jan Engelhardt
2006-04-21 19:56 ` Stephen Smalley
2006-04-22 11:13 ` Jan Engelhardt
2006-04-20 23:41 ` Pavel Machek
2006-04-19 17:00 ` Valdis.Kletnieks
2006-04-17 20:20 ` Chris Wright
2006-04-17 20:24 ` Arjan van de Ven
2006-04-17 20:27 ` Time to remove LSM David S. Miller
2006-04-17 20:27 ` Time to remove LSM (was Re: [RESEND][RFC][PATCH 2/7] implementation of LSM hooks) Chris Wright
2006-04-17 20:34 ` Greg KH
2006-04-17 20:38 ` Chris Wright
2006-04-17 20:43 ` Arjan van de Ven
2006-04-17 20:53 ` Chris Wright
2006-04-17 20:45 ` alan
[not found] ` <2e00cdfd0604171437g1d6c6923w5db82f317ed0f56@mail.gmail.com>
2006-04-17 22:07 ` Chris Wright
2006-04-17 22:10 ` Arjan van de Ven
2006-04-17 20:51 ` Adrian Bunk
2006-04-17 20:08 ` [RESEND][RFC][PATCH 2/7] implementation of LSM hooks David S. Miller
2006-04-17 18:20 ` Török Edwin
2006-04-23 19:58 ` Labeling only policy and problems with booleans Török Edwin
2006-04-26 13:37 ` Stephen Smalley
2006-04-26 14:13 ` Christopher J. PeBenito
2006-04-26 18:18 ` Török Edwin
2006-04-26 19:23 ` Christopher J. PeBenito
2006-04-26 18:13 ` Török Edwin
2006-04-26 19:26 ` Stephen Smalley
2006-04-26 20:08 ` Török Edwin
2006-04-27 19:17 ` Török Edwin
2006-04-27 19:53 ` Karl MacMillan
2006-05-01 16:06 ` [PATCH ] consistent labeling of block|character devices Török Edwin
2006-05-01 19:51 ` Stephen Smalley
2006-05-01 16:17 ` [1/4] Labeling only policy for fireflier Török Edwin
2006-05-01 16:34 ` [2/4] Labeling only policy for fireflier (fireflier.pp) Török Edwin
2006-05-01 16:38 ` [3/4] Labeling only policy for fireflier (example module) Török Edwin
2006-05-03 14:35 ` [2/4] Labeling only policy for fireflier (fireflier.pp) Christopher J. PeBenito
2006-05-01 16:43 ` [4/4] Labeling only policy for fireflier (install) Török Edwin
2006-05-01 18:55 ` [1/4] Labeling only policy for fireflier Christopher J. PeBenito
2006-05-02 15:36 ` Török Edwin
2006-04-07 18:39 ` [RFC][PATCH 3/7] sidtab - hashtable to store SIDs Török Edwin
2006-04-07 18:41 ` [RFC][PATCH 4/7] exports Török Edwin
2006-04-07 18:43 ` [RFC][PATCH 5/7] debugging/testing support Török Edwin
2006-04-07 18:44 ` [RFC][PATCH 6/7] userspace Török Edwin
2006-04-07 18:46 ` [RFC][PATCH 7/7] stacking support for capability module Török Edwin
2006-04-07 19:18 ` Serge E. Hallyn
2006-04-07 19:45 ` [RFC][PATCH 0/7] fireflier LSM for labeling sockets based on its creator (owner) Chris Wright
2006-04-08 7:41 ` edwin
2006-04-21 15:26 ` [RFC] packet/socket owner match (fireflier) using skfilter Mikado
2006-04-21 16:18 ` Török Edwin
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=200604142301.10188.edwin@gurde.com \
--to=edwin@gurde.com \
--cc=fireflier-devel@lists.sourceforge.net \
--cc=jmorris@namei.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=sds@tycho.nsa.gov \
/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.