Android ashmem driver update

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

 



Attached are two patches for SE Android to check SE policy in the ashmem driver.  The changes include both the driver changes and the corresponding changes to policy to make use of the driver changes.
From dcd1e8d2941ab9ea97ce9110779a24cde50d8cd1 Mon Sep 17 00:00:00 2001
From: Subramani V <subramani.venkatesh@xxxxxxxxxxxxx>
Date: Tue, 6 Mar 2012 18:53:20 -0500
Subject: [PATCH] Define Ashmem Policy for trusted daemons

Trusted type Daemons which access ashmem( self open and close), can perform ioctl operations
without any security.

Change-Id: Id15a72a70603d427211dc165d10f15ebef9cd67c
Signed-off-by: Subramani V <subramani.venkatesh@xxxxxxxxxxxxx>
---
 access_vectors    |   12 ++++++++++++
 app.te            |    4 ++++
 cts.te            |    1 +
 installd.te       |    1 +
 mediaserver.te    |    1 +
 rild.te           |    1 +
 security_classes  |    1 +
 servicemanager.te |    1 +
 surfaceflinger.te |    1 +
 system.te         |    2 ++
 ueventd.te        |    1 +
 vold.te           |    1 +
 zygote.te         |    1 +
 13 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/access_vectors b/access_vectors
index 90927e7..386393b 100644
--- a/access_vectors
+++ b/access_vectors
@@ -880,3 +880,15 @@ class zygote
 	specifyinvokewith
 	specifyseinfo
 }
+
+class ashmem
+{
+	set_name
+	get_name
+	set_size
+	get_size
+	set_prot_mask
+	get_prot_mask
+	pin
+	purge_all_caches
+}
diff --git a/app.te b/app.te
index 976b6bc..1538c7c 100644
--- a/app.te
+++ b/app.te
@@ -30,6 +30,7 @@ allow trusted_app sdcard:file create_file_perms;
 # Populate /data/app/vmdl*.tmp file created by system server.
 # It would be better if this was labeled differently.
 allow trusted_app apk_data_file:file write;
+allow trusted_app self:ashmem *;
 # Perform binder IPC to any app domain.
 binder_call(trusted_app, appdomain)
 binder_transfer(trusted_app, appdomain)
@@ -97,6 +98,9 @@ allow appdomain system:fifo_file rw_file_perms;
 allow appdomain app_data_file:dir create_dir_perms;
 allow appdomain app_data_file:notdevfile_class_set create_file_perms;
 
+#App domain can access ashmem
+allow appdomain self:ashmem *;
+
 # lib subdirectory of /data/data dir is system-owned.
 allow appdomain system_data_file:dir r_dir_perms;
 
diff --git a/cts.te b/cts.te
index 3600e94..5afcecc 100644
--- a/cts.te
+++ b/cts.te
@@ -36,6 +36,7 @@ dontaudit appdomain alarm_device:chr_file write;
 # Tries to create and use a netlink kobject uevent socket
 # to test for a vulnerable vold.
 dontaudit appdomain self:netlink_kobject_uevent_socket create;
+dontaudit appdomain self:ashmem *;
 
 # Tries to override DAC restrictions but expects to fail.
 dontaudit shell self:capability dac_override;
diff --git a/installd.te b/installd.te
index e4b0b18..ce2a637 100644
--- a/installd.te
+++ b/installd.te
@@ -15,6 +15,7 @@ allow installd apk_data_file:file r_file_perms;
 allow installd system_file:file x_file_perms;
 allow installd cgroup:dir create_dir_perms;
 dontaudit installd self:capability sys_admin;
+dontaudit installd self:ashmem *;
 # Check validity of SELinux context before use.
 selinux_check_context(installd)
 # Read /seapp_contexts, presently on the rootfs.
diff --git a/mediaserver.te b/mediaserver.te
index 16bbefa..cdbd340 100644
--- a/mediaserver.te
+++ b/mediaserver.te
@@ -20,6 +20,7 @@ allow mediaserver video_device:chr_file rw_file_perms;
 allow mediaserver audio_device:dir r_dir_perms;
 allow mediaserver audio_device:chr_file rw_file_perms;
 allow mediaserver qemu_device:chr_file rw_file_perms;
+allow mediaserver self:ashmem *;
 # XXX Label with a specific type?
 allow mediaserver sysfs:file rw_file_perms;
 # XXX Why?
diff --git a/rild.te b/rild.te
index 2857892..648ae1f 100644
--- a/rild.te
+++ b/rild.te
@@ -16,6 +16,7 @@ allow rild mtd_device:dir search;
 allow rild efs_file:dir create_dir_perms;
 allow rild efs_file:file create_file_perms;
 allow rild shell_exec:file rx_file_perms;
+allow rild self:ashmem *;
 dontaudit rild self:capability sys_admin;
 # XXX Label sysfs files with a specific type?
 allow rild sysfs:file rw_file_perms;
diff --git a/security_classes b/security_classes
index 38d78eb..e9e51d5 100644
--- a/security_classes
+++ b/security_classes
@@ -133,5 +133,6 @@ class db_language		# userspace
 
 class binder
 class zygote
+class ashmem
 
 # FLASK
diff --git a/servicemanager.te b/servicemanager.te
index fefbe08..a5ef646 100644
--- a/servicemanager.te
+++ b/servicemanager.te
@@ -11,4 +11,5 @@ init_daemon_domain(servicemanager)
 # created by other domains.  It never passes its own references
 # or initiates a Binder IPC.
 allow servicemanager self:binder set_context_mgr;
+allow servicemanager self:ashmem *;
 allow servicemanager domain:binder { receive transfer };
diff --git a/surfaceflinger.te b/surfaceflinger.te
index 80607da..21908e2 100644
--- a/surfaceflinger.te
+++ b/surfaceflinger.te
@@ -19,6 +19,7 @@ allow surfaceflinger graphics_device:chr_file rw_file_perms;
 
 # Access /dev/video1.
 allow surfaceflinger video_device:chr_file rw_file_perms;
+allow surfaceflinger self:ashmem *;
 
 # Create and use netlink kobject uevent sockets.
 allow surfaceflinger self:netlink_kobject_uevent_socket *;
diff --git a/system.te b/system.te
index ef0d12e..6268255 100644
--- a/system.te
+++ b/system.te
@@ -17,6 +17,7 @@ allow system_app system_data_file:file create_file_perms;
 
 # Write to dalvikcache.
 allow system_app dalvikcache_data_file:file { write setattr };
+allow system_app self:ashmem *;
 
 # Talk to keystore.
 unix_socket_connect(system_app, keystore, keystore)
@@ -104,6 +105,7 @@ allow system mediaserver:process getattr;
 
 # Specify any arguments to zygote.
 allow system self:zygote *;
+allow system self:ashmem *;
 
 # Check SELinux permissions.
 selinux_check_access(system)
diff --git a/ueventd.te b/ueventd.te
index 89dd9ee..606335b 100644
--- a/ueventd.te
+++ b/ueventd.te
@@ -16,6 +16,7 @@ allow ueventd dev_type:lnk_file { create unlink };
 allow ueventd dev_type:chr_file { create setattr unlink };
 allow ueventd dev_type:blk_file { create setattr unlink };
 allow ueventd self:netlink_kobject_uevent_socket *;
+allow ueventd self:ashmem *;
 # Read properties.
 allow ueventd kernel:fd use;
 allow ueventd tmpfs:file read;
diff --git a/vold.te b/vold.te
index 85a58f9..fa01a64 100644
--- a/vold.te
+++ b/vold.te
@@ -51,6 +51,7 @@ allow vold kernel:system module_request;
 # Write to /proc/sysrq-trigger
 # XXX Label with a distinct type?
 allow vold proc:file write;
+allow vold self:ashmem *;
 
 # Create and mount on /data/tmp_mnt.
 allow vold system_data_file:dir { write create add_name mounton };
diff --git a/zygote.te b/zygote.te
index 0601707..11e06fa 100644
--- a/zygote.te
+++ b/zygote.te
@@ -22,6 +22,7 @@ allow zygote system_file:file x_file_perms;
 # Control cgroups.
 allow zygote cgroup:dir create_dir_perms;
 allow zygote self:capability sys_admin;
+allow zygote self:ashmem *;
 # Check validity of SELinux context before use.
 selinux_check_context(zygote)
 # Check SELinux permissions.
-- 
1.7.1

From 6334ba7b263e2c81e17a81cba307b93e14a6092a Mon Sep 17 00:00:00 2001
From: Subramani V <subramani.venkatesh@xxxxxxxxxxxxx>
Date: Tue, 28 Feb 2012 22:14:17 -0500
Subject: [PATCH] WP0235: Add Ashmem to security hooks

This patch currently includes
1. hooks for ashmem with new permissions for Ashmem Ioctl
permissions for class ashmem are
"ashmem", { "set_name", "get_name", "set_size", "get_size", "set_prot_mask",
"get_prot_mask", "pin", "purge_all_caches" }

2. Security hook is called from mm/ashmem.c on ioctl.

Signed-off-by: Subramani V <subramani.venkatesh@xxxxxxxxxxxxx>
---
 include/linux/ashmem.h              |    9 ++++++
 include/linux/security.h            |    9 ++++++
 mm/ashmem.c                         |   33 +++++++++++++-------
 security/security.c                 |    5 +++
 security/selinux/hooks.c            |   55 ++++++++++++++++++++++++++++++++++-
 security/selinux/include/classmap.h |    1 +
 6 files changed, 99 insertions(+), 13 deletions(-)

diff --git a/include/linux/ashmem.h b/include/linux/ashmem.h
index 1976b10..1d7faf8 100644
--- a/include/linux/ashmem.h
+++ b/include/linux/ashmem.h
@@ -45,4 +45,13 @@ struct ashmem_pin {
 #define ASHMEM_GET_PIN_STATUS	_IO(__ASHMEMIOC, 9)
 #define ASHMEM_PURGE_ALL_CACHES	_IO(__ASHMEMIOC, 10)
 
+
+#define SET_NAME 			1
+#define GET_NAME 			2
+#define SET_SIZE 			3
+#define GET_SIZE 			4
+#define SET_PROT_MASK 		5
+#define GET_PROT_MASK 		6
+#define PIN 				7
+#define PURGE_ALL_CACHES 	8
 #endif	/* _LINUX_ASHMEM_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index ffdcc21..d6b5769 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -37,6 +37,7 @@
 #include <linux/xfrm.h>
 #include <linux/slab.h>
 #include <net/flow.h>
+#include <linux/ashmem.h>
 
 /* Maximum number of letters for an LSM name string */
 #define SECURITY_NAME_MAX	10
@@ -1554,6 +1555,8 @@ struct security_operations {
 	int (*shm_shmat) (struct shmid_kernel *shp,
 			  char __user *shmaddr, int shmflg);
 
+	int (*ashmem_has_perm) (struct file *file, int cmd);
+
 	int (*sem_alloc_security) (struct sem_array *sma);
 	void (*sem_free_security) (struct sem_array *sma);
 	int (*sem_associate) (struct sem_array *sma, int semflg);
@@ -1806,6 +1809,7 @@ void security_shm_free(struct shmid_kernel *shp);
 int security_shm_associate(struct shmid_kernel *shp, int shmflg);
 int security_shm_shmctl(struct shmid_kernel *shp, int cmd);
 int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg);
+int security_ashmem_has_perm(struct file *file, int cmd);
 int security_sem_alloc(struct sem_array *sma);
 void security_sem_free(struct sem_array *sma);
 int security_sem_associate(struct sem_array *sma, int semflg);
@@ -2491,6 +2495,11 @@ static inline int security_shm_shmat(struct shmid_kernel *shp,
 	return 0;
 }
 
+static inline void security_ashmem_has_perm(struct file *file, int cmd)
+{
+	return 0;
+}
+
 static inline int security_sem_alloc(struct sem_array *sma)
 {
 	return 0;
diff --git a/mm/ashmem.c b/mm/ashmem.c
index 66e3f23..36d2f30 100644
--- a/mm/ashmem.c
+++ b/mm/ashmem.c
@@ -630,6 +630,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct ashmem_area *asma = file->private_data;
 	long ret = -ENOTTY;
+	int err;
 
 	switch (cmd) {
 	case ASHMEM_SET_NAME:
@@ -639,20 +640,27 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		ret = get_name(asma, (void __user *) arg);
 		break;
 	case ASHMEM_SET_SIZE:
-		ret = -EINVAL;
 		if (!asma->file) {
-			ret = 0;
-			asma->size = (size_t) arg;
+				ret = 0;
+				asma->size = (size_t) arg;
 		}
 		break;
 	case ASHMEM_GET_SIZE:
 		ret = asma->size;
 		break;
 	case ASHMEM_SET_PROT_MASK:
-		ret = set_prot_mask(asma, arg);
+		err = security_ashmem_has_perm(file, SET_PROT_MASK);
+		if(!err)
+			ret = set_prot_mask(asma, arg);
+		else
+			ret = err;
 		break;
 	case ASHMEM_GET_PROT_MASK:
-		ret = asma->prot_mask;
+		err = security_ashmem_has_perm(file, GET_PROT_MASK);
+		if(!err)
+			ret = asma->prot_mask;
+		else
+			ret = err;
 		break;
 	case ASHMEM_PIN:
 	case ASHMEM_UNPIN:
@@ -662,17 +670,18 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case ASHMEM_PURGE_ALL_CACHES:
 		ret = -EPERM;
 		if (capable(CAP_SYS_ADMIN)) {
-			struct shrink_control sc = {
-				.gfp_mask = GFP_KERNEL,
-				.nr_to_scan = 0,
-			};
-			ret = ashmem_shrink(&ashmem_shrinker, &sc);
-			sc.nr_to_scan = ret;
-			ashmem_shrink(&ashmem_shrinker, &sc);
+				struct shrink_control sc = {
+					.gfp_mask = GFP_KERNEL,
+					.nr_to_scan = 0,
+				};
+				ret = ashmem_shrink(&ashmem_shrinker, &sc);
+				sc.nr_to_scan = ret;
+				ashmem_shrink(&ashmem_shrinker, &sc);
 		}
 		break;
 	}
 
+	printk(KERN_INFO "ERR return = %d", err);
 	return ret;
 }
 
diff --git a/security/security.c b/security/security.c
index e3e18a4..ae8b826 100644
--- a/security/security.c
+++ b/security/security.c
@@ -919,6 +919,11 @@ int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmfl
 	return security_ops->shm_shmat(shp, shmaddr, shmflg);
 }
 
+int security_ashmem_has_perm(struct file *file, int cmd)
+{
+	return security_ops->ashmem_has_perm(file, cmd);
+}
+
 int security_sem_alloc(struct sem_array *sma)
 {
 	return security_ops->sem_alloc_security(sma);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b695066..764a18a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1867,7 +1867,6 @@ static int selinux_binder_transfer_file(struct task_struct *from, struct task_st
 	return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
 			    &ad);
 }
-
 static int selinux_ptrace_access_check(struct task_struct *child,
 				     unsigned int mode)
 {
@@ -5155,6 +5154,57 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg)
 			    SEM__ASSOCIATE, &ad);
 }
 
+
+/* Shared Memory security operations */
+
+
+static inline u32 ashmem_cmd_to_av(int cmd)
+{
+	u32 av;
+	switch(cmd) {
+	case SET_NAME:
+		av = ASHMEM__SET_NAME;
+		break;
+	case GET_NAME:
+		av = ASHMEM__GET_NAME;
+		break;
+	case SET_SIZE:
+		av = ASHMEM__SET_SIZE;
+		break;
+	case GET_SIZE:
+		av = ASHMEM__GET_SIZE;
+		break;
+	case SET_PROT_MASK:
+		av = ASHMEM__SET_PROT_MASK;
+		break;
+	case GET_PROT_MASK:
+		av = ASHMEM__GET_PROT_MASK;
+		break;
+	case PIN:
+		av = ASHMEM__PIN;
+		break;
+	case PURGE_ALL_CACHES:
+		av = ASHMEM__PURGE_ALL_CACHES;
+		break;
+	};
+	return av;
+}
+
+static int selinux_ashmem_has_perm(struct file *file, int cmd )
+{
+	int err = 0;
+	int perms;
+	struct file_security_struct *fsec = file->f_security;
+	const struct cred *cred = current_cred();
+	u32 sid = current_sid();
+
+	if(sid != fsec->sid)
+		err = avc_has_perm(sid, fsec->sid, SECCLASS_ASHMEM, ashmem_cmd_to_av(cmd), NULL );
+
+	return err;
+}
+
+
 /* Note, at this point, sma is locked down */
 static int selinux_sem_semctl(struct sem_array *sma, int cmd)
 {
@@ -5645,6 +5695,9 @@ static struct security_operations selinux_ops = {
 	.sem_semctl =			selinux_sem_semctl,
 	.sem_semop =			selinux_sem_semop,
 
+
+	.ashmem_has_perm =		selinux_ashmem_has_perm,
+
 	.d_instantiate =		selinux_d_instantiate,
 
 	.getprocattr =			selinux_getprocattr,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index e105160..aa6be3b 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -150,5 +150,6 @@ struct security_class_mapping secclass_map[] = {
 	{ "tun_socket",
 	  { COMMON_SOCK_PERMS, NULL } },
 	{ "binder", { "impersonate", "call", "set_context_mgr", "transfer", "receive", NULL } },
+	{ "ashmem", { "set_name", "get_name", "set_size", "get_size", "set_prot_mask", "get_prot_mask", "pin", "purge_all_caches", NULL } },
 	{ NULL }
   };
-- 
1.7.1


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

  Powered by Linux