From: Kentaro Takeda <takedakn@nttdata.co.jp>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org,
Kentaro Takeda <takedakn@nttdata.co.jp>,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Subject: [TOMOYO #6 retry 12/21] argv0 check functions.
Date: Wed, 09 Jan 2008 09:53:32 +0900 [thread overview]
Message-ID: <20080109005423.616915690@nttdata.co.jp> (raw)
In-Reply-To: 20080109005320.323184643@nttdata.co.jp
If the executed program name and argv[0] is different,
TOMOYO Linux checks permission.
Each permission can be automatically accumulated into
the policy of each domain using 'learning mode'.
Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
security/tomoyo/exec.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 215 insertions(+)
--- /dev/null
+++ linux-2.6-mm/security/tomoyo/exec.c
@@ -0,0 +1,215 @@
+/*
+ * security/tomoyo/exec.c
+ *
+ * Argv0 access control functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/************************* AUDIT FUNCTIONS *************************/
+
+static int tmy_audit_argv0_log(const struct path_info *filename,
+ const char *argv0,
+ const bool is_granted,
+ const u8 profile,
+ const unsigned int mode)
+{
+ char *buf;
+ int len;
+
+ if (is_granted) {
+ if (!tmy_audit_grant())
+ return 0;
+ } else {
+ if (!tmy_audit_reject())
+ return 0;
+ }
+
+ len = filename->total_len + strlen(argv0) + 8;
+ buf = tmy_init_audit_log(&len, profile, mode);
+
+ if (!buf)
+ return -ENOMEM;
+
+ tmy_sncatprintf(buf, len - 1, TMY_ALLOW_ARGV0 "%s %s",
+ filename->name, argv0);
+
+ return tmy_write_audit_log(buf, is_granted);
+}
+
+/************************* ARGV0 MISMATCH HANDLER *************************/
+
+static int tmy_add_argv0_entry(const char *filename,
+ const char *argv0,
+ struct domain_info *domain,
+ const struct condition_list *cond,
+ const bool is_delete)
+{
+ struct acl_info *ptr;
+ struct argv0_acl *acl;
+ const struct path_info *saved_filename;
+ const struct path_info *saved_argv0;
+ int error = -ENOMEM;
+
+ if (!tmy_correct_path(filename, 1, 0, -1, __FUNCTION__) ||
+ !tmy_correct_path(argv0, -1, 0, -1, __FUNCTION__) ||
+ strchr(argv0, '/'))
+ return -EINVAL;
+
+ saved_filename = tmy_save_name(filename);
+ saved_argv0 = tmy_save_name(argv0);
+ if (!saved_filename || !saved_argv0)
+ return -ENOMEM;
+
+ mutex_lock(&domain_acl_lock);
+
+ if (is_delete)
+ goto remove;
+
+ list_for_each_entry(ptr, &domain->acl_info_list, list) {
+ acl = container_of(ptr, struct argv0_acl, head);
+ if (ptr->type == TMY_TYPE_ARGV0_ACL && ptr->cond == cond &&
+ acl->filename == saved_filename &&
+ acl->argv0 == saved_argv0) {
+ ptr->is_deleted = 0;
+ /* Found. Nothing to do. */
+ error = 0;
+ goto ok;
+ }
+ }
+
+ /* Not found. Append it to the tail. */
+ acl = tmy_alloc_element(sizeof(*acl));
+ if (!acl)
+ goto ok;
+
+ acl->head.type = TMY_TYPE_ARGV0_ACL;
+ acl->head.cond = cond;
+ acl->filename = saved_filename;
+ acl->argv0 = saved_argv0;
+ error = tmy_add_acl(domain, &acl->head);
+ goto ok;
+remove: ;
+ error = -ENOENT;
+ list_for_each_entry(ptr, &domain->acl_info_list, list) {
+ acl = container_of(ptr, struct argv0_acl, head);
+ if (ptr->type != TMY_TYPE_ARGV0_ACL ||
+ ptr->cond != cond || ptr->is_deleted ||
+ acl->filename != saved_filename ||
+ acl->argv0 != saved_argv0)
+ continue;
+
+ error = tmy_del_acl(ptr);
+ break;
+ }
+ok: ;
+ mutex_unlock(&domain_acl_lock);
+
+ return error;
+}
+
+static int tmy_argv0_acl(const struct path_info *filename,
+ const char *argv0_)
+{
+ const struct domain_info *domain = TMY_SECURITY->domain;
+ int error = -EPERM;
+ struct acl_info *ptr;
+ struct path_info argv0;
+
+ if (!tmy_flags(TMY_MAC_FOR_ARGV0))
+ return 0;
+
+ argv0.name = argv0_;
+ tmy_fill_path_info(&argv0);
+
+ list_for_each_entry(ptr, &domain->acl_info_list, list) {
+ struct argv0_acl *acl;
+ acl = container_of(ptr, struct argv0_acl, head);
+
+ if (ptr->type == TMY_TYPE_ARGV0_ACL &&
+ ptr->is_deleted == 0 &&
+ tmy_check_condition(ptr->cond, NULL) == 0 &&
+ tmy_path_match(filename, acl->filename) &&
+ tmy_path_match(&argv0, acl->argv0)) {
+ error = 0;
+ break;
+ }
+ }
+
+ return error;
+}
+
+/**
+ * tmy_argv0_perm - check for argv[0] permission.
+ * @filename: pointer to filename.
+ * @argv0: pointer to basename of argv[0].
+ *
+ * Returns zero if permission granted.
+ * Returns nonzero if permission denied.
+ */
+int tmy_argv0_perm(const struct path_info *filename, const char *argv0)
+{
+ int error = 0;
+ const u8 profile = TMY_SECURITY->domain->profile;
+ const unsigned int mode = tmy_flags(TMY_MAC_FOR_ARGV0);
+ const bool is_enforce = (mode == 3);
+
+ if (!mode)
+ return 0;
+ if (!filename || !argv0 || !*argv0)
+ return 0;
+
+ error = tmy_argv0_acl(filename, argv0);
+
+ tmy_audit_argv0_log(filename, argv0, !error, profile, mode);
+
+ if (error) {
+ struct domain_info * const domain = TMY_SECURITY->domain;
+
+ if (tmy_flags(TMY_VERBOSE))
+ tmy_audit("TOMOYO-%s: Run %s as %s denied for %s\n",
+ tmy_getmsg(is_enforce), filename->name, argv0,
+ tmy_lastname(domain));
+
+ if (is_enforce)
+ error = tmy_supervisor("%s\n" TMY_ALLOW_ARGV0 "%s %s\n",
+ domain->domainname->name,
+ filename->name, argv0);
+
+ else if (mode == 1 && tmy_quota())
+ tmy_add_argv0_entry(filename->name, argv0, domain,
+ NULL, 0);
+
+ if (!is_enforce)
+ error = 0;
+ }
+
+ return error;
+}
+
+/**
+ * tmy_add_argv0_policy - add or delete argv[0] policy.
+ * @data: a line to parse.
+ * @domain: pointer to "struct domain_info".
+ * @cond: pointer to "struct condition_list". May be NULL.
+ * @is_delete: is this delete request?
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ */
+int tmy_add_argv0_policy(char *data,
+ struct domain_info *domain,
+ const struct condition_list *cond,
+ const bool is_delete)
+{
+ char *argv0 = strchr(data, ' ');
+
+ if (!argv0)
+ return -EINVAL;
+
+ *argv0++ = '\0';
+
+ return tmy_add_argv0_entry(data, argv0, domain, cond,
+ is_delete);
+}
--
next prev parent reply other threads:[~2008-01-09 0:58 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-09 0:53 [TOMOYO #6 retry 00/21] TOMOYO Linux - MAC based on process invocation history Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 01/21] TOMOYO Linux documentation Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 02/21] Add struct vfsmount to struct task_struct Kentaro Takeda
2008-01-15 21:16 ` Serge E. Hallyn
2008-01-16 0:22 ` Kentaro Takeda
2008-01-16 14:39 ` Serge E. Hallyn
2008-01-17 4:55 ` Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 03/21] Add wrapper functions for VFS helper functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 04/21] Replace VFS with wrapper functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 05/21] Add packet filtering based on processs security context Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 06/21] Data structures and prototype defitions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 07/21] Memory and pathname management functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 08/21] Utility functions and policy manipulation interface Kentaro Takeda
2008-01-09 4:25 ` James Morris
2008-01-09 4:29 ` James Morris
2008-01-12 2:06 ` [TOMOYO #6 retry 08/21] Utility functions and policy manipulationinterface Tetsuo Handa
2008-01-12 3:06 ` James Morris
2008-01-12 4:45 ` Greg KH
2008-01-12 7:34 ` [TOMOYO #6 retry 08/21] Utility functions and policymanipulationinterface Tetsuo Handa
2008-01-09 4:31 ` [TOMOYO #6 retry 08/21] Utility functions and policy manipulation interface Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 09/21] Domain transition functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 10/21] Auditing interface Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 11/21] File access control functions Kentaro Takeda
2008-01-09 0:53 ` Kentaro Takeda [this message]
2008-01-09 0:53 ` [TOMOYO #6 retry 13/21] environment variable name check functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 14/21] Network access control functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 15/21] Namespace manipulation " Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 16/21] Signal " Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 17/21] Capability access " Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 18/21] LSM adapter functions Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 19/21] Conditional permission support Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 20/21] Kconfig and Makefile Kentaro Takeda
2008-01-09 0:53 ` [TOMOYO #6 retry 21/21] Add signal hooks at sleepable location Kentaro Takeda
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=20080109005423.616915690@nttdata.co.jp \
--to=takedakn@nttdata.co.jp \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
/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.