All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
To: linux-security-module@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
	Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Subject: [PATCH 2/8] CaitSith: Add pathname calculation functions.
Date: Fri, 21 Oct 2016 21:49:04 +0900	[thread overview]
Message-ID: <1477054150-4772-3-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp> (raw)
In-Reply-To: <1477054150-4772-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp>

This is a simplified version of security/tomoyo/realpath.c , except
two changes listed below.

  A "\" character (0x5C) in TOMOYO is represented as "\\" while
  it in CaitSith is represented as "\134". This allows us to tell
  whether a "\" character at any position is a literal "\" character
  without scanning from the beginning of the string.

  A "/" character (0x2F) is appended in TOMOYO in order to represent
  a directory while it is not appended in CaitSith. In CaitSith,
  path.type variable which will be implemented after this version is
  accepted will allow us to tell whether a pathname represents a
  directory without appending a "/" character.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 security/caitsith/realpath.c | 227 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 227 insertions(+)
 create mode 100644 security/caitsith/realpath.c

diff --git a/security/caitsith/realpath.c b/security/caitsith/realpath.c
new file mode 100644
index 0000000..f62d843
--- /dev/null
+++ b/security/caitsith/realpath.c
@@ -0,0 +1,227 @@
+/*
+ * security/caitsith/realpath.c
+ *
+ * Copyright (C) 2005-2012  NTT DATA CORPORATION
+ */
+
+#include "caitsith.h"
+
+/**
+ * cs_realpath - Returns realpath(3) of the given pathname but ignores chroot'ed root.
+ *
+ * @path: Pointer to "struct path".
+ *
+ * Returns the realpath of the given @path on success, NULL otherwise.
+ *
+ * This function uses kzalloc(), so caller must kfree() if this function
+ * didn't return NULL.
+ */
+char *cs_realpath(const struct path *path)
+{
+	char *buf = NULL;
+	char *name = NULL;
+	unsigned int buf_len = PAGE_SIZE / 2;
+	struct dentry *dentry = path->dentry;
+	struct super_block *sb;
+
+	if (!dentry)
+		return NULL;
+	sb = dentry->d_sb;
+	while (1) {
+		char *pos;
+
+		buf_len <<= 1;
+		kfree(buf);
+		buf = kmalloc(buf_len, GFP_NOFS);
+		if (!buf)
+			break;
+		/* To make sure that pos is '\0' terminated. */
+		buf[buf_len - 1] = '\0';
+		/* For "pipe:[\$]". */
+		if (dentry->d_op && dentry->d_op->d_dname)
+			pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1);
+		else
+			pos = d_absolute_path(path, buf, buf_len);
+		if (IS_ERR(pos))
+			continue;
+		name = cs_encode(pos);
+		break;
+	}
+	kfree(buf);
+	if (!name)
+		cs_warn_oom(__func__);
+	return name;
+}
+
+/**
+ * cs_encode2 - Encode binary string to ascii string.
+ *
+ * @str:     String in binary format. Maybe NULL.
+ * @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.
+ */
+static char *cs_encode2(const char *str, int str_len)
+{
+	int i;
+	int len;
+	const char *p = str;
+	char *cp;
+	char *cp0;
+
+	if (!p)
+		return NULL;
+	len = str_len;
+	for (i = 0; i < str_len; i++) {
+		const unsigned char c = p[i];
+
+		if (!(c > ' ' && c < 127 && c != '\\'))
+			len += 3;
+	}
+	len++;
+	cp = kzalloc(len, GFP_NOFS);
+	if (!cp)
+		return NULL;
+	cp0 = cp;
+	p = str;
+	for (i = 0; i < str_len; i++) {
+		const unsigned char c = p[i];
+
+		if (c > ' ' && c < 127 && c != '\\') {
+			*cp++ = c;
+		} else {
+			*cp++ = '\\';
+			*cp++ = (c >> 6) + '0';
+			*cp++ = ((c >> 3) & 7) + '0';
+			*cp++ = (c & 7) + '0';
+		}
+	}
+	return cp0;
+}
+
+/**
+ * cs_encode - Encode binary string to ascii string.
+ *
+ * @str: String in binary format. Maybe NULL.
+ *
+ * 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 *cs_encode(const char *str)
+{
+	return str ? cs_encode2(str, strlen(str)) : NULL;
+}
+
+/**
+ * cs_const_part_length - Evaluate the initial length without a pattern in a token.
+ *
+ * @filename: The string to evaluate. Maybe NULL.
+ *
+ * Returns the initial length without a pattern in @filename.
+ */
+static int cs_const_part_length(const char *filename)
+{
+	char c;
+	int len = 0;
+
+	if (!filename)
+		return 0;
+	while (1) {
+		c = *filename++;
+		if (!c)
+			break;
+		if (c != '\\') {
+			len++;
+			continue;
+		}
+		c = *filename++;
+		switch (c) {
+		case '0':   /* "\ooo" */
+		case '1':
+		case '2':
+		case '3':
+			c = *filename++;
+			if (c < '0' || c > '7')
+				break;
+			c = *filename++;
+			if (c < '0' || c > '7')
+				break;
+			len += 4;
+			continue;
+		}
+		break;
+	}
+	return len;
+}
+
+/**
+ * cs_fill_path_info - Fill in "struct cs_path_info" members.
+ *
+ * @ptr: Pointer to "struct cs_path_info" to fill in.
+ *
+ * Returns nothing.
+ *
+ * The caller sets "struct cs_path_info"->name.
+ */
+void cs_fill_path_info(struct cs_path_info *ptr)
+{
+	const char *name = ptr->name;
+	const int len = strlen(name);
+
+	ptr->total_len = len;
+	ptr->const_len = cs_const_part_length(name);
+	ptr->hash = full_name_hash(NULL, name, len);
+}
+
+/**
+ * cs_get_exe - Get cs_realpath() of current process.
+ *
+ * Returns the cs_realpath() of current process on success, NULL otherwise.
+ *
+ * This function uses kzalloc(), so the caller must kfree()
+ * if this function didn't return NULL.
+ */
+char *cs_get_exe(void)
+{
+	struct mm_struct *mm = current->mm;
+	char *cp;
+	struct file *exe_file;
+
+	if (current->flags & PF_KTHREAD)
+		return kstrdup("<kernel>", GFP_NOFS);
+	if (!mm)
+		goto task_has_no_mm;
+	exe_file = get_mm_exe_file(mm);
+	if (!exe_file)
+		goto task_has_no_mm;
+	cp = cs_realpath(&exe_file->f_path);
+	fput(exe_file);
+	return cp;
+task_has_no_mm:
+	return kstrdup("<unknown>", GFP_NOFS);
+}
+
+/**
+ * cs_get_exename - Get cs_realpath() of current process.
+ *
+ * @buf: Pointer to "struct cs_path_info".
+ *
+ * Returns true on success, false otherwise.
+ *
+ * This function uses kzalloc(), so the caller must kfree()
+ * if this function returned true.
+ */
+bool cs_get_exename(struct cs_path_info *buf)
+{
+	buf->name = cs_get_exe();
+	if (buf->name) {
+		cs_fill_path_info(buf);
+		return true;
+	}
+	return false;
+}
-- 
1.8.3.1

  parent reply	other threads:[~2016-10-21 12:51 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-21 12:49 [PATCH 0/8] CaitSith LSM module Tetsuo Handa
2016-10-21 12:49 ` [PATCH 1/8] CaitSith: Add header file Tetsuo Handa
2016-10-21 12:49 ` Tetsuo Handa [this message]
2016-10-21 12:49 ` [PATCH 3/8] CaitSith: Add policy I/O functions Tetsuo Handa
2016-10-21 12:49 ` [PATCH 4/8] CaitSith: Add permission check functions Tetsuo Handa
2016-10-21 12:49 ` [PATCH 5/8] CaitSith: Add LSM adapter functions Tetsuo Handa
2016-10-21 12:49 ` [PATCH 6/8] CaitSith: Add policy loader functions Tetsuo Handa
2016-10-21 12:49 ` [PATCH 7/8] CaitSith: Add garbage collector functions Tetsuo Handa
2016-10-21 12:49 ` [PATCH 8/8] CaitSith: Add Kconfig and Makefile Tetsuo Handa
2016-10-24  4:44 ` [PATCH 0/8] CaitSith LSM module James Morris
2016-10-24 14:39   ` John Johansen
2016-10-24 18:18 ` John Johansen
2016-10-25 11:26   ` Tetsuo Handa
2016-11-23  6:31     ` Tetsuo Handa
2016-11-23 18:51       ` John Johansen
2017-05-21  4:59         ` Tetsuo Handa
2017-05-21  4:59           ` Tetsuo Handa
2017-05-21  5:31           ` John Johansen
2017-05-21  5:31             ` John Johansen
2017-05-21  5:59             ` Tetsuo Handa
2017-05-21  5:59               ` Tetsuo Handa
2017-10-21 10:59               ` Tetsuo Handa
2017-10-21 10:59                 ` Tetsuo Handa
2017-10-21 17:17                 ` Casey Schaufler
2017-10-21 17:17                   ` Casey Schaufler
2018-09-01 13:04                   ` Tetsuo Handa
2018-09-01 13:04                     ` Tetsuo Handa
2018-09-05 16:22                     ` John Johansen
2018-09-05 16:22                       ` John Johansen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1477054150-4772-3-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp \
    --to=penguin-kernel@i-love.sakura.ne.jp \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.