Re: [PATCH] security: report the module name to security_module_request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 3 Nov 2009, Eric Paris wrote:

> For SELinux to do better filtering in userspace we send the name of the
> module along with the AVC denial when a program is denied module_request.
> 
> Example output:
> 
> type=SYSCALL msg=audit(11/03/2009 10:59:43.510:9) : arch=x86_64 syscall=write success=yes exit=2 a0=3 a1=7fc28c0d56c0 a2=2 a3=7fffca0d7440 items=0 ppid=1727 pid=1729 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=rpc.nfsd exe=/usr/sbin/rpc.nfsd subj=system_u:system_r:nfsd_t:s0 key=(null)
> type=AVC msg=audit(11/03/2009 10:59:43.510:9) : avc:  denied  { module_request } for  pid=1729 comm=rpc.nfsd kmod="net-pf-10" scontext=system_u:system_r:nfsd_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=system
> 
> Signed-off-by: Eric Paris <eparis@xxxxxxxxxx>

Needs to be reviewed on the LSM list.. (cc'd)


> ---
> 
>  include/linux/lsm_audit.h |   18 ++++++++++--------
>  include/linux/security.h  |    7 ++++---
>  kernel/kmod.c             |    8 ++++----
>  security/capability.c     |    2 +-
>  security/lsm_audit.c      |    4 ++++
>  security/security.c       |    4 ++--
>  security/selinux/hooks.c  |   13 +++++++++++--
>  7 files changed, 36 insertions(+), 20 deletions(-)
> 
> diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
> index 190c378..f78f83d 100644
> --- a/include/linux/lsm_audit.h
> +++ b/include/linux/lsm_audit.h
> @@ -26,14 +26,15 @@
>  
>  /* Auxiliary data to use in generating the audit record. */
>  struct common_audit_data {
> -	char    type;
> -#define LSM_AUDIT_DATA_FS      1
> -#define LSM_AUDIT_DATA_NET     2
> -#define LSM_AUDIT_DATA_CAP     3
> -#define LSM_AUDIT_DATA_IPC     4
> -#define LSM_AUDIT_DATA_TASK    5
> -#define LSM_AUDIT_DATA_KEY     6
> -#define LSM_AUDIT_NO_AUDIT     7
> +	char type;
> +#define LSM_AUDIT_DATA_FS	1
> +#define LSM_AUDIT_DATA_NET	2
> +#define LSM_AUDIT_DATA_CAP	3
> +#define LSM_AUDIT_DATA_IPC	4
> +#define LSM_AUDIT_DATA_TASK	5
> +#define LSM_AUDIT_DATA_KEY	6
> +#define LSM_AUDIT_NO_AUDIT	7
> +#define LSM_AUDIT_DATA_KMOD	8
>  	struct task_struct *tsk;
>  	union 	{
>  		struct {
> @@ -66,6 +67,7 @@ struct common_audit_data {
>  			char *key_desc;
>  		} key_struct;
>  #endif
> +		char *kmod_name;
>  	} u;
>  	/* this union contains LSM specific data */
>  	union {
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 3f3844a..9c3a43b 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -706,6 +706,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
>   * @kernel_module_request:
>   *	Ability to trigger the kernel to automatically upcall to userspace for
>   *	userspace to load a kernel module with the given name.
> + *	@kmod_name name of the module requested by the kernel
>   *	Return 0 if successful.
>   * @task_setuid:
>   *	Check permission before setting one or more of the user identity
> @@ -1577,7 +1578,7 @@ struct security_operations {
>  	void (*cred_transfer)(struct cred *new, const struct cred *old);
>  	int (*kernel_act_as)(struct cred *new, u32 secid);
>  	int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
> -	int (*kernel_module_request)(void);
> +	int (*kernel_module_request)(char *kmod_name);
>  	int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
>  	int (*task_fix_setuid) (struct cred *new, const struct cred *old,
>  				int flags);
> @@ -1843,7 +1844,7 @@ void security_commit_creds(struct cred *new, const struct cred *old);
>  void security_transfer_creds(struct cred *new, const struct cred *old);
>  int security_kernel_act_as(struct cred *new, u32 secid);
>  int security_kernel_create_files_as(struct cred *new, struct inode *inode);
> -int security_kernel_module_request(void);
> +int security_kernel_module_request(char *kmod_name);
>  int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
>  int security_task_fix_setuid(struct cred *new, const struct cred *old,
>  			     int flags);
> @@ -2409,7 +2410,7 @@ static inline int security_kernel_create_files_as(struct cred *cred,
>  	return 0;
>  }
>  
> -static inline int security_kernel_module_request(void)
> +static inline int security_kernel_module_request(char *kmod_name)
>  {
>  	return 0;
>  }
> diff --git a/kernel/kmod.c b/kernel/kmod.c
> index 9fcb53a..25b1031 100644
> --- a/kernel/kmod.c
> +++ b/kernel/kmod.c
> @@ -80,16 +80,16 @@ int __request_module(bool wait, const char *fmt, ...)
>  #define MAX_KMOD_CONCURRENT 50	/* Completely arbitrary value - KAO */
>  	static int kmod_loop_msg;
>  
> -	ret = security_kernel_module_request();
> -	if (ret)
> -		return ret;
> -
>  	va_start(args, fmt);
>  	ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
>  	va_end(args);
>  	if (ret >= MODULE_NAME_LEN)
>  		return -ENAMETOOLONG;
>  
> +	ret = security_kernel_module_request(module_name);
> +	if (ret)
> +		return ret;
> +
>  	/* If modprobe needs a service that is in a module, we get a recursive
>  	 * loop.  Limit the number of running kmod threads to max_threads/2 or
>  	 * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
> diff --git a/security/capability.c b/security/capability.c
> index d30a8e8..10f23a4 100644
> --- a/security/capability.c
> +++ b/security/capability.c
> @@ -421,7 +421,7 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode)
>  	return 0;
>  }
>  
> -static int cap_kernel_module_request(void)
> +static int cap_kernel_module_request(char *kmod_name)
>  {
>  	return 0;
>  }
> diff --git a/security/lsm_audit.c b/security/lsm_audit.c
> index e04566a..acba3df 100644
> --- a/security/lsm_audit.c
> +++ b/security/lsm_audit.c
> @@ -354,6 +354,10 @@ static void dump_common_audit_data(struct audit_buffer *ab,
>  		}
>  		break;
>  #endif
> +	case LSM_AUDIT_DATA_KMOD:
> +		audit_log_format(ab, " kmod=");
> +		audit_log_untrustedstring(ab, a->u.kmod_name);
> +		break;
>  	} /* switch (a->type) */
>  }
>  
> diff --git a/security/security.c b/security/security.c
> index 48ec2b4..739033e 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -761,9 +761,9 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
>  	return security_ops->kernel_create_files_as(new, inode);
>  }
>  
> -int security_kernel_module_request(void)
> +int security_kernel_module_request(char *kmod_name)
>  {
> -	return security_ops->kernel_module_request();
> +	return security_ops->kernel_module_request(kmod_name);
>  }
>  
>  int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 0c0c1bf..18e2e5b 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3338,9 +3338,18 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
>  	return 0;
>  }
>  
> -static int selinux_kernel_module_request(void)
> +static int selinux_kernel_module_request(char *kmod_name)
>  {
> -	return task_has_system(current, SYSTEM__MODULE_REQUEST);
> +	u32 sid;
> +	struct common_audit_data ad;
> +
> +	sid = task_sid(current);
> +
> +	COMMON_AUDIT_DATA_INIT(&ad, KMOD);
> +	ad.u.kmod_name = kmod_name;
> +
> +	return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
> +			    SYSTEM__MODULE_REQUEST, &ad);
>  }
>  
>  static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
> 

-- 
James Morris
<jmorris@xxxxxxxxx>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux