aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorTodd Poynor <toddpoynor@google.com>2012-04-19 15:15:48 -0700
committerTodd Poynor <toddpoynor@google.com>2012-04-19 15:20:03 -0700
commit94225ab0bef6f32108eaa410bb894caa2b4317e2 (patch)
tree3696c83cc5109c7e439c8228fe6be72a3a4a74fe /security
parent801cb6260fb5cae3bbc513927b583447c38d9deb (diff)
parent0527fde0639955203ad48a9fd83bd6fc35e82e07 (diff)
downloadkernel_samsung_aries-94225ab0bef6f32108eaa410bb894caa2b4317e2.zip
kernel_samsung_aries-94225ab0bef6f32108eaa410bb894caa2b4317e2.tar.gz
kernel_samsung_aries-94225ab0bef6f32108eaa410bb894caa2b4317e2.tar.bz2
Merge linux-stable 3.0.28 into android-3.0
Change-Id: Iee820738e53627f5d0447a87ceff34443aa72786 Signed-off-by: Todd Poynor <toddpoynor@google.com>
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/path.c65
-rw-r--r--security/integrity/ima/ima_api.c4
-rw-r--r--security/integrity/ima/ima_queue.c17
-rw-r--r--security/keys/user_defined.c3
-rw-r--r--security/selinux/netport.c4
-rw-r--r--security/tomoyo/mount.c38
-rw-r--r--security/tomoyo/realpath.c9
7 files changed, 83 insertions, 57 deletions
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 36cc0cc..b566eba 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -57,23 +57,44 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
static int d_namespace_path(struct path *path, char *buf, int buflen,
char **name, int flags)
{
- struct path root, tmp;
char *res;
- int connected, error = 0;
+ int error = 0;
+ int connected = 1;
+
+ if (path->mnt->mnt_flags & MNT_INTERNAL) {
+ /* it's not mounted anywhere */
+ res = dentry_path(path->dentry, buf, buflen);
+ *name = res;
+ if (IS_ERR(res)) {
+ *name = buf;
+ return PTR_ERR(res);
+ }
+ if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
+ strncmp(*name, "/sys/", 5) == 0) {
+ /* TODO: convert over to using a per namespace
+ * control instead of hard coded /proc
+ */
+ return prepend(name, *name - buf, "/proc", 5);
+ }
+ return 0;
+ }
- /* Get the root we want to resolve too, released below */
+ /* resolve paths relative to chroot?*/
if (flags & PATH_CHROOT_REL) {
- /* resolve paths relative to chroot */
+ struct path root;
get_fs_root(current->fs, &root);
- } else {
- /* resolve paths relative to namespace */
- root.mnt = current->nsproxy->mnt_ns->root;
- root.dentry = root.mnt->mnt_root;
- path_get(&root);
+ res = __d_path(path, &root, buf, buflen);
+ if (res && !IS_ERR(res)) {
+ /* everything's fine */
+ *name = res;
+ path_put(&root);
+ goto ok;
+ }
+ path_put(&root);
+ connected = 0;
}
- tmp = root;
- res = __d_path(path, &tmp, buf, buflen);
+ res = d_absolute_path(path, buf, buflen);
*name = res;
/* handle error conditions - and still allow a partial path to
@@ -84,7 +105,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
*name = buf;
goto out;
}
+ if (!our_mnt(path->mnt))
+ connected = 0;
+ok:
/* Handle two cases:
* 1. A deleted dentry && profile is not allowing mediation of deleted
* 2. On some filesystems, newly allocated dentries appear to the
@@ -97,10 +121,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
goto out;
}
- /* Determine if the path is connected to the expected root */
- connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt;
-
- /* If the path is not connected,
+ /* If the path is not connected to the expected root,
* check if it is a sysctl and handle specially else remove any
* leading / that __d_path may have returned.
* Unless
@@ -112,17 +133,9 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
* namespace root.
*/
if (!connected) {
- /* is the disconnect path a sysctl? */
- if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
- strncmp(*name, "/sys/", 5) == 0) {
- /* TODO: convert over to using a per namespace
- * control instead of hard coded /proc
- */
- error = prepend(name, *name - buf, "/proc", 5);
- } else if (!(flags & PATH_CONNECT_PATH) &&
+ if (!(flags & PATH_CONNECT_PATH) &&
!(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
- (tmp.mnt == current->nsproxy->mnt_ns->root &&
- tmp.dentry == tmp.mnt->mnt_root))) {
+ our_mnt(path->mnt))) {
/* disconnected path, don't return pathname starting
* with '/'
*/
@@ -133,8 +146,6 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
}
out:
- path_put(&root);
-
return error;
}
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index da36d2c..5335605 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -177,8 +177,8 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
result = ima_store_template(entry, violation, inode);
- if (!result)
+ if (!result || result == -EEXIST)
iint->flags |= IMA_MEASURED;
- else
+ if (result < 0)
kfree(entry);
}
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 8e28f04..55a6271 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -23,6 +23,8 @@
#include <linux/slab.h>
#include "ima.h"
+#define AUDIT_CAUSE_LEN_MAX 32
+
LIST_HEAD(ima_measurements); /* list of all measurements */
/* key: inode (before secure-hashing a file) */
@@ -94,7 +96,8 @@ static int ima_pcr_extend(const u8 *hash)
result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
if (result != 0)
- pr_err("IMA: Error Communicating to TPM chip\n");
+ pr_err("IMA: Error Communicating to TPM chip, result: %d\n",
+ result);
return result;
}
@@ -106,14 +109,16 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
{
u8 digest[IMA_DIGEST_SIZE];
const char *audit_cause = "hash_added";
+ char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
int audit_info = 1;
- int result = 0;
+ int result = 0, tpmresult = 0;
mutex_lock(&ima_extend_list_mutex);
if (!violation) {
memcpy(digest, entry->digest, sizeof digest);
if (ima_lookup_digest_entry(digest)) {
audit_cause = "hash_exists";
+ result = -EEXIST;
goto out;
}
}
@@ -128,9 +133,11 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
if (violation) /* invalidate pcr */
memset(digest, 0xff, sizeof digest);
- result = ima_pcr_extend(digest);
- if (result != 0) {
- audit_cause = "TPM error";
+ tpmresult = ima_pcr_extend(digest);
+ if (tpmresult != 0) {
+ snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
+ tpmresult);
+ audit_cause = tpm_audit_cause;
audit_info = 0;
}
out:
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 5b366d7..69ff52c 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -102,7 +102,8 @@ int user_update(struct key *key, const void *data, size_t datalen)
key->expiry = 0;
}
- kfree_rcu(zap, rcu);
+ if (zap)
+ kfree_rcu(zap, rcu);
error:
return ret;
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index cfe2d72..e2b74eb 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -139,7 +139,9 @@ static void sel_netport_insert(struct sel_netport *port)
if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) {
struct sel_netport *tail;
tail = list_entry(
- rcu_dereference(sel_netport_hash[idx].list.prev),
+ rcu_dereference_protected(
+ sel_netport_hash[idx].list.prev,
+ lockdep_is_held(&sel_netport_lock)),
struct sel_netport, list);
list_del_rcu(&tail->list);
call_rcu(&tail->rcu, sel_netport_free);
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 9fc2e15..892494a 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -205,30 +205,32 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
if (flags & MS_REMOUNT) {
type = TOMOYO_MOUNT_REMOUNT_KEYWORD;
flags &= ~MS_REMOUNT;
- }
- if (flags & MS_MOVE) {
- type = TOMOYO_MOUNT_MOVE_KEYWORD;
- flags &= ~MS_MOVE;
- }
- if (flags & MS_BIND) {
+ } else if (flags & MS_BIND) {
type = TOMOYO_MOUNT_BIND_KEYWORD;
flags &= ~MS_BIND;
- }
- if (flags & MS_UNBINDABLE) {
- type = TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD;
- flags &= ~MS_UNBINDABLE;
- }
- if (flags & MS_PRIVATE) {
+ } else if (flags & MS_SHARED) {
+ if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
+ return -EINVAL;
+ type = TOMOYO_MOUNT_MAKE_SHARED_KEYWORD;
+ flags &= ~MS_SHARED;
+ } else if (flags & MS_PRIVATE) {
+ if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE))
+ return -EINVAL;
type = TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD;
flags &= ~MS_PRIVATE;
- }
- if (flags & MS_SLAVE) {
+ } else if (flags & MS_SLAVE) {
+ if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE))
+ return -EINVAL;
type = TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD;
flags &= ~MS_SLAVE;
- }
- if (flags & MS_SHARED) {
- type = TOMOYO_MOUNT_MAKE_SHARED_KEYWORD;
- flags &= ~MS_SHARED;
+ } else if (flags & MS_UNBINDABLE) {
+ if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE))
+ return -EINVAL;
+ type = TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD;
+ flags &= ~MS_UNBINDABLE;
+ } else if (flags & MS_MOVE) {
+ type = TOMOYO_MOUNT_MOVE_KEYWORD;
+ flags &= ~MS_MOVE;
}
if (!type)
type = "<NULL>";
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index d1e05b0..a339187 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -95,7 +95,6 @@ char *tomoyo_realpath_from_path(struct path *path)
return NULL;
is_dir = dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode);
while (1) {
- struct path ns_root = { .mnt = NULL, .dentry = NULL };
char *pos;
buf_len <<= 1;
kfree(buf);
@@ -128,8 +127,12 @@ char *tomoyo_realpath_from_path(struct path *path)
/* If we don't have a vfsmount, we can't calculate. */
if (!path->mnt)
break;
- /* go to whatever namespace root we are under */
- pos = __d_path(path, &ns_root, buf, buf_len);
+ pos = d_absolute_path(path, buf, buf_len - 1);
+ /* If path is disconnected, use "[unknown]" instead. */
+ if (pos == ERR_PTR(-EINVAL)) {
+ name = tomoyo_encode("[unknown]");
+ break;
+ }
/* Prepend "/proc" prefix if using internal proc vfs mount. */
if (!IS_ERR(pos) && (path->mnt->mnt_flags & MNT_INTERNAL) &&
(path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) {