[PATCH] LSPP audit enablement: storing selinux ocontext and scontext

Amy Griffis amy.griffis at hp.com
Sat Sep 3 05:19:33 UTC 2005


Hi Dustin,

On Mon, Aug 29, 2005 at 04:18:04PM -0500, Dustin Kirkland wrote:
> Updated patch attached.

Some comments inline.

> diff -uprN linux-2.6.13-rc6-mm2/include/linux/audit.h linux-2.6.13-rc6-mm2-lspp_audit/include/linux/audit.h
> --- linux-2.6.13-rc6-mm2/include/linux/audit.h	2005-08-29 11:32:14.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/include/linux/audit.h	2005-08-29 10:44:08.000000000 -0500
> @@ -68,6 +68,7 @@
>  #define AUDIT_CONFIG_CHANGE	1305	/* Audit system configuration change */
>  #define AUDIT_SOCKADDR		1306	/* sockaddr copied as syscall arg */
>  #define AUDIT_CWD		1307	/* Current working directory */
> +#define AUDIT_SECURITY_CONTEXT	1350	/* security context */
>  
>  #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
>  #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
> @@ -238,6 +239,8 @@ extern int audit_sockaddr(int len, void 
>  extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
>  extern void audit_signal_info(int sig, struct task_struct *t);
>  extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
> +extern int audit_ipc_security_context(struct kern_ipc_perm *ipcp);
> +extern int audit_set_macxattr(const char *name);
>  #else
>  #define audit_alloc(t) ({ 0; })
>  #define audit_free(t) do { ; } while (0)
> @@ -255,6 +258,8 @@ extern int audit_filter_user(struct netl
>  #define audit_avc_path(dentry, mnt) ({ 0; })
>  #define audit_signal_info(s,t) do { ; } while (0)
>  #define audit_filter_user(cb,t) ({ 1; })
> +#define audit_ipc_security_context(p) ({ 0; })
> +#define audit_set_macxattr(n) ({ 0; })
>  #endif
>  
>  #ifdef CONFIG_AUDIT
> @@ -283,6 +288,7 @@ extern void		    audit_send_reply(int pi
>  					     int done, int multi,
>  					     void *payload, int size);
>  extern void		    audit_log_lost(const char *message);
> +extern void		    audit_panic(const char *message);
>  extern struct semaphore audit_netlink_sem;
>  #else
>  #define audit_log(c,g,t,f,...) do { ; } while (0)
> @@ -293,6 +299,7 @@ extern struct semaphore audit_netlink_se
>  #define audit_log_hex(a,b,l) do { ; } while (0)
>  #define audit_log_untrustedstring(a,s) do { ; } while (0)
>  #define audit_log_d_path(b,p,d,v) do { ; } while (0)
> +#define audit_panic(m) do { ; } while (0)
>  #endif
>  #endif
>  #endif
> diff -uprN linux-2.6.13-rc6-mm2/include/linux/security.h linux-2.6.13-rc6-mm2-lspp_audit/include/linux/security.h
> --- linux-2.6.13-rc6-mm2/include/linux/security.h	2005-08-29 11:32:16.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/include/linux/security.h	2005-08-29 10:37:50.000000000 -0500
> @@ -792,6 +792,11 @@ struct swap_info_struct;
>   *	@ipcp contains the kernel IPC permission structure
>   *	@flag contains the desired (requested) permission set
>   *	Return 0 if permission is granted.
> + * @ipc_getsecurity:
> + *      Copy the security label associated with the ipc object into
> + *      @buffer.  @buffer may be NULL to request the size of the buffer 
> + *      required.  @size indicates the size of @buffer in bytes. Return 
> + *      number of bytes used/required on success.
>   *
>   * Security hooks for individual messages held in System V IPC message queues
>   * @msg_msg_alloc_security:
> @@ -1140,6 +1145,7 @@ struct security_operations {
>  	void (*task_to_inode)(struct task_struct *p, struct inode *inode);
>  
>  	int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
> +	int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size);
>  
>  	int (*msg_msg_alloc_security) (struct msg_msg * msg);
>  	void (*msg_msg_free_security) (struct msg_msg * msg);
> @@ -1775,6 +1781,11 @@ static inline int security_ipc_permissio
>  	return security_ops->ipc_permission (ipcp, flag);
>  }
>  
> +static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
> +{
> +	return security_ops->ipc_getsecurity(ipcp, buffer, size);
> +}
> +
>  static inline int security_msg_msg_alloc (struct msg_msg * msg)
>  {
>  	return security_ops->msg_msg_alloc_security (msg);
> @@ -2405,6 +2416,11 @@ static inline int security_ipc_permissio
>  	return 0;
>  }
>  
> +static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
>  static inline int security_msg_msg_alloc (struct msg_msg * msg)
>  {
>  	return 0;
> diff -uprN linux-2.6.13-rc6-mm2/ipc/msg.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/msg.c
> --- linux-2.6.13-rc6-mm2/ipc/msg.c	2005-08-29 11:32:16.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/msg.c	2005-08-29 10:37:51.000000000 -0500
> @@ -443,6 +443,13 @@ asmlinkage long sys_msgctl (int msqid, i
>  	if (msq == NULL)
>  		goto out_up;
>  
> +	ipcp = &msq->q_perm;

Please double check that ipcp isn't being set twice, as it appears.

> +
> +	if (cmd == IPC_SET) {
> +		if ((err = audit_ipc_security_context(ipcp)))

I think it's desirable to limit the proliferation of audit hooks where
possible.  In this case, grabbing q_perm could be consolidated with
the current audit_ipc_perms hook, although this would mean processing
under the spinlock more of the time.

> +			goto out_unlock_up;
> +	}
> +
>  	err = -EIDRM;
>  	if (msg_checkid(msq,msqid))
>  		goto out_unlock_up;
> diff -uprN linux-2.6.13-rc6-mm2/ipc/sem.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/sem.c
> --- linux-2.6.13-rc6-mm2/ipc/sem.c	2005-08-29 11:32:16.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/sem.c	2005-08-29 10:37:51.000000000 -0500
> @@ -813,12 +813,18 @@ static int semctl_down(int semid, int se
>  	if(sma==NULL)
>  		return -EINVAL;
>  
> +	ipcp = &sma->sem_perm;
> +
> +	if(cmd == IPC_SET) {
> +		if ((err = audit_ipc_security_context(ipcp)))
> +			goto out_unlock;
> +	}
> +	
>  	if (sem_checkid(sma,semid)) {
>  		err=-EIDRM;
>  		goto out_unlock;
>  	}	
> -	ipcp = &sma->sem_perm;
> -	
> +
>  	if (current->euid != ipcp->cuid && 
>  	    current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
>  	    	err=-EPERM;
> diff -uprN linux-2.6.13-rc6-mm2/ipc/shm.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/shm.c
> --- linux-2.6.13-rc6-mm2/ipc/shm.c	2005-08-29 11:32:16.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/shm.c	2005-08-29 10:37:51.000000000 -0500
> @@ -611,6 +611,9 @@ asmlinkage long sys_shmctl (int shmid, i
>  		err=-EINVAL;
>  		if(shp==NULL)
>  			goto out_up;
> +		err = audit_ipc_security_context(&(shp->shm_perm));
> +		if(err)
> +			goto out_unlock_up;
>  		err = shm_checkid(shp,shmid);
>  		if(err)
>  			goto out_unlock_up;
> diff -uprN linux-2.6.13-rc6-mm2/ipc/util.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/util.c
> --- linux-2.6.13-rc6-mm2/ipc/util.c	2005-08-29 11:32:16.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/util.c	2005-08-29 10:39:17.000000000 -0500
> @@ -26,6 +26,7 @@
>  #include <linux/workqueue.h>
>  #include <linux/seq_file.h>
>  #include <linux/proc_fs.h>
> +#include <linux/audit.h>
>  
>  #include <asm/unistd.h>
>  
> @@ -466,6 +467,8 @@ int ipcperms (struct kern_ipc_perm *ipcp
>  {	/* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
>  	int requested_mode, granted_mode;
>  
> +	audit_ipc_security_context(ipcp);

Why no error check?

Does hooking ipcperms cover all the ipc operations where we need the
security context?

> +
>  	requested_mode = (flag >> 6) | (flag >> 3) | flag;
>  	granted_mode = ipcp->mode;
>  	if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
> diff -uprN linux-2.6.13-rc6-mm2/kernel/audit.c linux-2.6.13-rc6-mm2-lspp_audit/kernel/audit.c
> --- linux-2.6.13-rc6-mm2/kernel/audit.c	2005-08-29 11:32:16.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/kernel/audit.c	2005-08-29 11:29:16.000000000 -0500
> @@ -142,7 +142,7 @@ static void audit_set_pid(struct audit_b
>  	nlh->nlmsg_pid = pid;
>  }
>  
> -static void audit_panic(const char *message)
> +void audit_panic(const char *message)
>  {
>  	switch (audit_failure)
>  	{
> @@ -893,3 +893,4 @@ void audit_log(struct audit_context *ctx
>  		audit_log_end(ab);
>  	}
>  }
> +
> diff -uprN linux-2.6.13-rc6-mm2/kernel/auditsc.c linux-2.6.13-rc6-mm2-lspp_audit/kernel/auditsc.c
> --- linux-2.6.13-rc6-mm2/kernel/auditsc.c	2005-08-29 11:32:16.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/kernel/auditsc.c	2005-08-29 11:09:43.000000000 -0500
> @@ -43,6 +43,7 @@
>  #include <linux/netlink.h>
>  #include <linux/compiler.h>
>  #include <asm/unistd.h>
> +#include <linux/security.h>
>  
>  /* 0 = no checking
>     1 = put_count checking
> @@ -99,6 +100,7 @@ struct audit_names {
>  	gid_t		gid;
>  	dev_t		rdev;
>  	unsigned	flags;
> +	char		*security_context;
>  };
>  
>  struct audit_aux_data {
> @@ -108,6 +110,12 @@ struct audit_aux_data {
>  
>  #define AUDIT_AUX_IPCPERM	0
>  
> +struct audit_aux_data_security_context {
> +	struct			audit_aux_data d;
> +	char			*security_context;
> +	size_t			security_context_len;
> +};

I'd prefer not to add another aux struct just to hold ipc security
context.  I don't see any reason why this couldn't be added to
audit_aux_data_ipcctl below.  Also, the security_context_len field is
unused.

> +
>  struct audit_aux_data_ipcctl {
>  	struct audit_aux_data	d;
>  	struct ipc_perm		p;
> @@ -167,6 +175,8 @@ struct audit_context {
>  #endif
>  };
>  
> +static const char *audit_macxattr;
> +
>  				/* Public API */
>  /* There are three lists of rules -- one to search at task creation
>   * time, one to search at syscall entry time, and another to search at
> @@ -670,9 +680,11 @@ static inline void audit_free_names(stru
>  	context->ino_count  = 0;
>  #endif
>  
> -	for (i = 0; i < context->name_count; i++)
> +	for (i = 0; i < context->name_count; i++) {
>  		if (context->names[i].name)
>  			__putname(context->names[i].name);
> +		kfree(context->names[i].security_context);
> +	}
>  	context->name_count = 0;
>  	if (context->pwd)
>  		dput(context->pwd);
> @@ -771,6 +783,37 @@ static inline void audit_free_context(st
>  		printk(KERN_ERR "audit: freed %d contexts\n", count);
>  }
>  
> +static void audit_log_task_security_context(struct audit_buffer *ab)
> +{
> +	char *security_context;
> +	ssize_t len = 0;
> +
> +	len = security_getprocattr(current, "current", NULL, 0);
> +	if (len < 0) {
> +		if (len != -EINVAL) 
> +			audit_panic("security_getprocattr error in audit_log_task_security_context");
> +		return;
> +	}
> +
> +	security_context = kmalloc(len, GFP_KERNEL);
> +	if (!security_context) {
> +		audit_panic("memory allocation error in audit_log_task_security_context");
> +		return;
> +	}
> +
> +	len = security_getprocattr(current, "current", security_context, len);
> +	if (len < 0 ) {
> +		audit_panic("security_getprocattr error in audit_log_task_security_context");
> +		goto out;
> +	}
> +	
> +	audit_log_format(ab, " scontext=%s", security_context);
> +	
> +out:
> +	kfree(security_context);
> +	return;
> +}
> +
>  static void audit_log_task_info(struct audit_buffer *ab)
>  {
>  	char name[sizeof(current->comm)];
> @@ -797,6 +840,7 @@ static void audit_log_task_info(struct a
>  		vma = vma->vm_next;
>  	}
>  	up_read(&mm->mmap_sem);
> +	audit_log_task_security_context(ab);
>  }
>  
>  static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask)
> @@ -868,6 +912,11 @@ static void audit_log_exit(struct audit_
>  			struct audit_aux_data_path *axi = (void *)aux;
>  			audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
>  			break; }
> +		case AUDIT_SECURITY_CONTEXT: {
> +			struct audit_aux_data_security_context *axi = (void *)aux;
> +			audit_log_format(ab, " ocontext=%s", axi->security_context);
> +			kfree(axi->security_context);

Freeing the security context in audit_free_aux() would be more
consistent with the current code.

> +			break; }
>  
>  		}
>  		audit_log_end(ab);
> @@ -903,6 +952,10 @@ static void audit_log_exit(struct audit_
>  					 context->names[i].gid,
>  					 MAJOR(context->names[i].rdev),
>  					 MINOR(context->names[i].rdev));
> +		if (context->names[i].security_context) {
> +			audit_log_format(ab, " ocontext=%s",
> +				context->names[i].security_context);
> +		}
>  		audit_log_end(ab);
>  	}
>  }
> @@ -1118,6 +1171,37 @@ void audit_putname(const char *name)
>  #endif
>  }
>  
> +void audit_inode_security_context(int idx, const struct inode *inode)
> +{
> +	struct audit_context *context = current->audit_context;
> +	int len = 0;
> +
> +	if (!audit_macxattr)
> +		return;
> +
> +	len = security_inode_getsecurity((struct inode *)inode, audit_macxattr, NULL, 0);
> +	if (len < 0) {
> +		if (len != -EOPNOTSUPP) 
> +			audit_panic("security_inode_getsecurity error in audit_inode_security_context");

I don't think audit_panic is needed anywhere in this function, as the
syscall operation hasn't occured yet.

> +		return;
> +	}
> +
> +	context->names[idx].security_context = kmalloc(len, GFP_KERNEL);
> +	if (!(context->names[idx].security_context)) {
> +		audit_panic("memory allocation error in audit_inode_security_context");
> +		return;
> +	}
> +
> +	len = security_inode_getsecurity((struct inode *)inode, audit_macxattr,
> +					context->names[idx].security_context, len);
> +	if (len < 0) {
> +		kfree(context->names[idx].security_context);
> +		audit_panic("security_inode_getsecurity error in audit_inode_security_context");
> +	}
> +
> +	return;
> +}
> +
>  /* Store the inode and device from a lookup.  Called from
>   * fs/namei.c:path_lookup(). */
>  void audit_inode(const char *name, const struct inode *inode, unsigned flags)
> @@ -1153,6 +1237,8 @@ void audit_inode(const char *name, const
>  	context->names[idx].uid   = inode->i_uid;
>  	context->names[idx].gid   = inode->i_gid;
>  	context->names[idx].rdev  = inode->i_rdev;
> +
> +	audit_inode_security_context(idx, inode);
>  }
>  
>  void auditsc_get_stamp(struct audit_context *ctx,
> @@ -1292,3 +1378,58 @@ void audit_signal_info(int sig, struct t
>  	}
>  }
>  
> +int audit_ipc_security_context(struct kern_ipc_perm *ipcp)
> +{
> +	struct audit_aux_data_security_context *ax;
> +	struct audit_context *context = current->audit_context;
> +	int len = 0;
> +
> +	if (likely(!context))
> +		return 0;
> +
> +	ax = kmalloc(sizeof(*ax), GFP_ATOMIC);

Might add a comment as to why you're using GFP_ATOMIC here.

> +	if (!ax) {
> +		audit_panic("memory allocation error in audit_ipc_security_context");

Again, don't think audit_panic is needed.

> +		return -ENOMEM;
> +	}
> +
> +	len = security_ipc_getsecurity(ipcp, NULL, 0);
> +	if (len < 0) {
> +		if (len != -EOPNOTSUPP)
> +			audit_panic("security_ipc_getsecurity error in audit_ipc_security_context");
> +			return len;
> +	}
> +
> +	ax->security_context = kmalloc(len, GFP_ATOMIC);
> +	if (!ax->security_context) {
> +		audit_panic("memory allocation error in audit_ipc_security_context");
> +		kfree(ax);
> +		return -ENOMEM;
> +	}
> +
> +	len = security_ipc_getsecurity(ipcp, ax->security_context, len);
> +	if (len < 0) {
> +		audit_panic("security_ipc_getsecurity error in audit_ipc_security_context");
> +		kfree(ax->security_context);
> +		kfree(ax);
> +		return len;
> +	}
> +
> +	ax->security_context_len = len;
> +
> +	ax->d.type = AUDIT_SECURITY_CONTEXT;
> +	ax->d.next = context->aux;
> +	context->aux = (void *)ax;
> +	return 0;
> +}
> +
> +/* Set the security XATTR name. This is needed for audit functions
> + * to obtain the security context of file system objects. */
> +int audit_set_macxattr(const char *name)
> +{
> +	if (audit_macxattr)
> +		return -EINVAL;
> +
> +	audit_macxattr = kstrdup(name, GFP_KERNEL);
> +	return 0;
> +}
> diff -uprN linux-2.6.13-rc6-mm2/security/dummy.c linux-2.6.13-rc6-mm2-lspp_audit/security/dummy.c
> --- linux-2.6.13-rc6-mm2/security/dummy.c	2005-08-29 11:32:17.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/security/dummy.c	2005-08-29 10:37:51.000000000 -0500
> @@ -557,6 +557,11 @@ static int dummy_ipc_permission (struct 
>  	return 0;
>  }
>  
> +static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
>  static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
>  {
>  	return 0;
> @@ -907,6 +912,7 @@ void security_fixup_ops (struct security
>  	set_to_dummy_if_null(ops, task_reparent_to_init);
>   	set_to_dummy_if_null(ops, task_to_inode);
>  	set_to_dummy_if_null(ops, ipc_permission);
> +	set_to_dummy_if_null(ops, ipc_getsecurity);
>  	set_to_dummy_if_null(ops, msg_msg_alloc_security);
>  	set_to_dummy_if_null(ops, msg_msg_free_security);
>  	set_to_dummy_if_null(ops, msg_queue_alloc_security);
> diff -uprN linux-2.6.13-rc6-mm2/security/selinux/hooks.c linux-2.6.13-rc6-mm2-lspp_audit/security/selinux/hooks.c
> --- linux-2.6.13-rc6-mm2/security/selinux/hooks.c	2005-08-29 11:32:17.000000000 -0500
> +++ linux-2.6.13-rc6-mm2-lspp_audit/security/selinux/hooks.c	2005-08-29 10:37:51.000000000 -0500
> @@ -116,6 +116,35 @@ static struct security_operations *secon
>  static LIST_HEAD(superblock_security_head);
>  static DEFINE_SPINLOCK(sb_security_lock);
>  
> +/* Return security context for a given sid or just the context 
> +   length if the buffer is null or length is 0 */
> +static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
> +{
> +	char *context;
> +	unsigned len;
> +	int rc;
> +
> +	if (buffer && !size)
> +		return -ERANGE;
> +
> +	rc = security_sid_to_context(sid, &context, &len);
> +	if (rc)
> +		return rc;
> +
> +	if (!buffer || !size)

You don't need to check !size here.  Based on your other conditionals,
it can only be possible if you have !buffer, which you've already
checked.

> +		goto getsecurity_exit;
> +
> +	if (size < len) {
> +		kfree(context);
> +		return -ERANGE;

Use getsecurity_exit here.

> +	}
> +	memcpy(buffer, context, len);
> +
> +getsecurity_exit:
> +	kfree(context);
> +	return len;
> +}
> +
>  /* Allocate and free functions for each kind of security blob. */
>  
>  static int task_alloc_security(struct task_struct *task)
> @@ -2234,30 +2263,13 @@ static int selinux_inode_removexattr (st
>  static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
>  {
>  	struct inode_security_struct *isec = inode->i_security;
> -	char *context;
> -	unsigned len;
> -	int rc;
>  
>  	/* Permission check handled by selinux_inode_getxattr hook.*/
>  
>  	if (strcmp(name, XATTR_SELINUX_SUFFIX))
>  		return -EOPNOTSUPP;
>  
> -	rc = security_sid_to_context(isec->sid, &context, &len);
> -	if (rc)
> -		return rc;
> -
> -	if (!buffer || !size) {
> -		kfree(context);
> -		return len;
> -	}
> -	if (size < len) {
> -		kfree(context);
> -		return -ERANGE;
> -	}
> -	memcpy(buffer, context, len);
> -	kfree(context);
> -	return len;
> +	return(selinux_getsecurity(isec->sid, buffer, size));
>  }
>  
>  static int selinux_inode_setsecurity(struct inode *inode, const char *name,
> @@ -3362,6 +3374,13 @@ out:	
>  	return err;
>  }
>  
> +static int selinux_socket_getsecurity(struct socket *sock, void *buffer, size_t size)
> +{
> +	struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
> +
> +	return(selinux_getsecurity(isec->sid, buffer, size));
> +}

This patch appears to be unfinished (?)  
I don't see any code using this function.

> + 
>  static int selinux_sk_alloc_security(struct sock *sk, int family, int priority)
>  {
>  	return sk_alloc_security(sk, family, priority);
> @@ -4027,6 +4046,13 @@ static int selinux_ipc_permission(struct
>  	return ipc_has_perm(ipcp, av);
>  }
>  
> +static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
> +{
> +	struct ipc_security_struct *isec = ipcp->security;
> +
> +	return(selinux_getsecurity(isec->sid, buffer, size));
> +}
> +
>  /* module stacking operations */
>  static int selinux_register_security (const char *name, struct security_operations *ops)
>  {
> @@ -4068,8 +4094,7 @@ static int selinux_getprocattr(struct ta
>  			       char *name, void *value, size_t size)
>  {
>  	struct task_security_struct *tsec;
> -	u32 sid, len;
> -	char *context;
> +	u32 sid;
>  	int error;
>  
>  	if (current != p) {
> @@ -4078,9 +4103,6 @@ static int selinux_getprocattr(struct ta
>  			return error;
>  	}
>  
> -	if (!size)
> -		return -ERANGE;
> -
>  	tsec = p->security;
>  
>  	if (!strcmp(name, "current"))
> @@ -4097,16 +4119,7 @@ static int selinux_getprocattr(struct ta
>  	if (!sid)
>  		return 0;
>  
> -	error = security_sid_to_context(sid, &context, &len);
> -	if (error)
> -		return error;
> -	if (len > size) {
> -		kfree(context);
> -		return -ERANGE;
> -	}
> -	memcpy(value, context, len);
> -	kfree(context);
> -	return len;
> +	return(selinux_getsecurity(sid, value, size));
>  }
>  
>  static int selinux_setprocattr(struct task_struct *p,
> @@ -4301,6 +4314,7 @@ static struct security_operations selinu
>  	.task_to_inode =                selinux_task_to_inode,
>  
>  	.ipc_permission =		selinux_ipc_permission,
> +	.ipc_getsecurity =		selinux_ipc_getsecurity,
>  
>  	.msg_msg_alloc_security =	selinux_msg_msg_alloc_security,
>  	.msg_msg_free_security =	selinux_msg_msg_free_security,
> @@ -4381,6 +4395,10 @@ static __init int selinux_init(void)
>  	if (register_security (&selinux_ops))
>  		panic("SELinux: Unable to register with kernel.\n");
>  
> +	if (audit_set_macxattr(XATTR_SELINUX_SUFFIX)) {
> +		printk(KERN_WARNING "SELinux: Unable to register xattr name with audit.\n");	
> +	}
> +
>  	if (selinux_enforcing) {
>  		printk(KERN_INFO "SELinux:  Starting in enforcing mode\n");
>  	} else {




> --
> Linux-audit mailing list
> Linux-audit at redhat.com
> http://www.redhat.com/mailman/listinfo/linux-audit




More information about the Linux-audit mailing list