aboutsummaryrefslogtreecommitdiff
path: root/security/tomoyo/realpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r--security/tomoyo/realpath.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 6c601bd300f..a3386d11942 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -4,28 +4,23 @@
* Copyright (C) 2005-2011 NTT DATA CORPORATION
*/
-#include <linux/types.h>
-#include <linux/mount.h>
-#include <linux/mnt_namespace.h>
-#include <linux/fs_struct.h>
-#include <linux/magic.h>
-#include <linux/slab.h>
-#include <net/sock.h>
#include "common.h"
-#include "../../fs/internal.h"
+#include <linux/magic.h>
/**
- * tomoyo_encode: Convert binary string to ascii string.
+ * tomoyo_encode2 - Encode binary string to ascii string.
*
- * @str: String in binary format.
+ * @str: String in binary format.
+ * @str_len: Size of @str in byte.
*
* Returns pointer to @str in ascii format on success, NULL otherwise.
*
* This function uses kzalloc(), so caller must kfree() if this function
* didn't return NULL.
*/
-char *tomoyo_encode(const char *str)
+char *tomoyo_encode2(const char *str, int str_len)
{
+ int i;
int len = 0;
const char *p = str;
char *cp;
@@ -33,8 +28,9 @@ char *tomoyo_encode(const char *str)
if (!p)
return NULL;
- while (*p) {
- const unsigned char c = *p++;
+ for (i = 0; i < str_len; i++) {
+ const unsigned char c = p[i];
+
if (c == '\\')
len += 2;
else if (c > ' ' && c < 127)
@@ -49,8 +45,8 @@ char *tomoyo_encode(const char *str)
return NULL;
cp0 = cp;
p = str;
- while (*p) {
- const unsigned char c = *p++;
+ for (i = 0; i < str_len; i++) {
+ const unsigned char c = p[i];
if (c == '\\') {
*cp++ = '\\';
@@ -68,6 +64,21 @@ char *tomoyo_encode(const char *str)
}
/**
+ * tomoyo_encode - Encode binary string to ascii string.
+ *
+ * @str: String in binary format.
+ *
+ * Returns pointer to @str in ascii format on success, NULL otherwise.
+ *
+ * This function uses kzalloc(), so caller must kfree() if this function
+ * didn't return NULL.
+ */
+char *tomoyo_encode(const char *str)
+{
+ return str ? tomoyo_encode2(str, strlen(str)) : NULL;
+}
+
+/**
* tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
*
* @path: Pointer to "struct path".
@@ -83,9 +94,8 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer,
{
char *pos = ERR_PTR(-ENOMEM);
if (buflen >= 256) {
- struct path ns_root = { };
/* go to whatever namespace root we are under */
- pos = __d_path(path, &ns_root, buffer, buflen - 1);
+ pos = d_absolute_path(path, buffer, buflen - 1);
if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
struct inode *inode = path->dentry->d_inode;
if (inode && S_ISDIR(inode->i_mode)) {
@@ -163,7 +173,7 @@ static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer,
* Use filesystem name if filesystem does not support rename()
* operation.
*/
- if (inode->i_op && !inode->i_op->rename)
+ if (!inode->i_op->rename)
goto prepend_filesystem_name;
}
/* Prepend device name. */
@@ -272,12 +282,20 @@ char *tomoyo_realpath_from_path(struct path *path)
* Get local name for filesystems without rename() operation
* or dentry without vfsmount.
*/
- if (!path->mnt || (inode->i_op && !inode->i_op->rename))
+ if (!path->mnt || !inode->i_op->rename)
pos = tomoyo_get_local_path(path->dentry, buf,
buf_len - 1);
/* Get absolute name for the rest. */
- else
+ else {
pos = tomoyo_get_absolute_path(path, buf, buf_len - 1);
+ /*
+ * Fall back to local name if absolute name is not
+ * available.
+ */
+ if (pos == ERR_PTR(-EINVAL))
+ pos = tomoyo_get_local_path(path->dentry, buf,
+ buf_len - 1);
+ }
encode:
if (IS_ERR(pos))
continue;