From: Tony Jones <tonyj@suse.de>
To: linux-kernel@vger.kernel.org
Cc: chrisw@sous-sol.org, Tony Jones <tonyj@suse.de>,
linux-security-module@vger.kernel.org
Subject: [RFC][PATCH 5/11] security: AppArmor - Filesystem
Date: Wed, 19 Apr 2006 10:49:46 -0700 [thread overview]
Message-ID: <20060419174946.29149.40949.sendpatchset@ermintrude.int.wirex.com> (raw)
In-Reply-To: <20060419174905.29149.67649.sendpatchset@ermintrude.int.wirex.com>
This patch implements the AppArmor file structure underneath securityfs.
Securityfs is normally mounted as /sys/kernel/security
The following files are created under /sys/kernel/security/apparmor
control
audit - Controls the global setting for auditing all
accesses.
complain - Controls the global setting for learning mode
(usually this is set per profile rather than
globally)
debug - Controls whether debugging is enabled.
This needs to be made more fine grained
logsyscall - Controls whether when logging to the audit
subsystem full syscall auditing is enabled.
The values by default for all of the above are 0.
matching - Returns the features of the installed matching submodule
profiles - Returns the profiles currently loaded and for each whether
it is in complain (learning) or enforce mode.
.load
.remove
.replace - Used by userspace tools to load, remove and replace new
profiles.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/apparmorfs.c | 432 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 432 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/apparmorfs.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2005 Novell/SUSE
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * AppArmor filesystem (part of securityfs)
+ */
+
+#include <linux/security.h>
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+
+#include "apparmor.h"
+#include "inline.h"
+#include "match/match.h"
+
+#define SECFS_AA "apparmor"
+static struct dentry *aafs_dentry = NULL;
+
+/* profile */
+extern struct seq_operations apparmorfs_profiles_op;
+static int aa_prof_open(struct inode *inode, struct file *file);
+static int aa_prof_release(struct inode *inode, struct file *file);
+
+static struct file_operations apparmorfs_profiles_fops = {
+ .open = aa_prof_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = aa_prof_release,
+};
+
+/* matching */
+static ssize_t aa_matching_read(struct file *file, char __user *buf,
+ size_t size, loff_t *ppos);
+
+static struct file_operations apparmorfs_matching_fops = {
+ .read = aa_matching_read,
+};
+
+
+/* interface */
+static ssize_t aa_profile_load(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos);
+static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos);
+static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos);
+
+static struct file_operations apparmorfs_profile_load = {
+ .write = aa_profile_load
+};
+
+static struct file_operations apparmorfs_profile_replace = {
+ .write = aa_profile_replace
+};
+
+static struct file_operations apparmorfs_profile_remove = {
+ .write = aa_profile_remove
+};
+
+
+/* control */
+static u64 aa_control_get(void *data);
+static void aa_control_set(void *data, u64 val);
+
+DEFINE_SIMPLE_ATTRIBUTE(apparmorfs_control_fops, aa_control_get,
+ aa_control_set, "%lld\n");
+
+
+
+/* table of static entries */
+
+static struct root_entry {
+ const char *name;
+ int mode;
+ int access;
+ struct file_operations *fops;
+ void *data;
+
+ /* internal fields */
+ struct dentry *dentry;
+ int parent_index;
+} root_entries[] = {
+ /* our root, normally /sys/kernel/security/apparmor */
+ {SECFS_AA, S_IFDIR, 0550}, /* DO NOT EDIT/MOVE */
+
+ /* interface for obtaining list of profiles currently loaded */
+ {"profiles", S_IFREG, 0440, &apparmorfs_profiles_fops,
+ NULL},
+
+ /* interface for obtaining matching features supported */
+ {"matching", S_IFREG, 0440, &apparmorfs_matching_fops,
+ NULL},
+
+ /* interface for loading/removing/replacing profiles */
+ {".load", S_IFREG, 0640, &apparmorfs_profile_load,
+ NULL},
+ {".replace", S_IFREG, 0640, &apparmorfs_profile_replace,
+ NULL},
+ {".remove", S_IFREG, 0640, &apparmorfs_profile_remove,
+ NULL},
+
+ /* interface for setting binary config values */
+ {"control", S_IFDIR, 0550},
+ {"complain", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_complain},
+ {"audit", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_audit},
+ {"debug", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_debug},
+ {"logsyscall", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_logsyscall},
+ {NULL, S_IFDIR, 0},
+
+ /* root end */
+ {NULL, S_IFDIR, 0}
+};
+
+#define AAFS_DENTRY root_entries[0].dentry
+
+static const unsigned int num_entries =
+ sizeof(root_entries) / sizeof(struct root_entry);
+
+
+
+static int aa_prof_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &apparmorfs_profiles_op);
+}
+
+
+static int aa_prof_release(struct inode *inode, struct file *file)
+{
+ return seq_release(inode, file);
+}
+
+static ssize_t aa_matching_read(struct file *file, char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ const char *matching = aamatch_features();
+
+ return simple_read_from_buffer(buf, size, ppos, matching,
+ strlen(matching));
+}
+
+static char *aa_simple_write_to_buffer(const char __user *userbuf,
+ size_t alloc_size, size_t copy_size,
+ loff_t *pos, const char *msg)
+{
+ struct aaprofile *active;
+ char *data;
+
+ if (*pos != 0) {
+ /* only writes from pos 0, that is complete writes */
+ data = ERR_PTR(-ESPIPE);
+ goto out;
+ }
+
+ /* Don't allow confined processes to load/replace/remove profiles.
+ * No sane person would add rules allowing this to a profile
+ * but we enforce the restriction anyways.
+ */
+ rcu_read_lock();
+ active = get_activeptr_rcu();
+ if (active) {
+ AA_WARN("REJECTING access to profile %s (%s(%d) "
+ "profile %s active %s)\n",
+ msg, current->comm, current->pid,
+ BASE_PROFILE(active)->name, active->name);
+
+ data = ERR_PTR(-EPERM);
+ goto out;
+ }
+ rcu_read_unlock();
+
+ data = vmalloc(alloc_size);
+ if (data == NULL) {
+ data = ERR_PTR(-ENOMEM);
+ goto out;
+ }
+
+ if (copy_from_user(data, userbuf, copy_size)) {
+ vfree(data);
+ data = ERR_PTR(-EFAULT);
+ goto out;
+ }
+
+out:
+ return data;
+}
+
+static ssize_t aa_profile_load(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+{
+ char *data;
+ ssize_t error;
+
+ data = aa_simple_write_to_buffer(buf, size, size, pos, "load");
+
+ if (!IS_ERR(data)) {
+ error = aa_file_prof_add(data, size);
+ vfree(data);
+ } else {
+ error = PTR_ERR(data);
+ }
+
+ return error;
+}
+
+static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+{
+ char *data;
+ ssize_t error;
+
+ data = aa_simple_write_to_buffer(buf, size, size, pos, "replacement");
+
+ if (!IS_ERR(data)) {
+ error = aa_file_prof_repl(data, size);
+ vfree(data);
+ } else {
+ error = PTR_ERR(data);
+ }
+
+ return error;
+}
+
+static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+{
+ char *data;
+ ssize_t error;
+
+ /* aa_file_prof_remove needs a null terminated string so 1 extra
+ * byte is allocated and null the copied data is then null terminated
+ */
+ data = aa_simple_write_to_buffer(buf, size+1, size, pos, "removal");
+
+ if (!IS_ERR(data)) {
+ data[size] = 0;
+ error = aa_file_prof_remove(data, size);
+ vfree(data);
+ } else {
+ error = PTR_ERR(data);
+ }
+
+ return error;
+}
+
+static u64 aa_control_get(void *data)
+{
+ return *(int *)data;
+}
+
+static void aa_control_set(void *data, u64 val)
+{
+ if (val > 1)
+ val = 1;
+
+ *(int*)data = (int)val;
+}
+
+static void clear_apparmorfs(void)
+{
+ unsigned int i;
+
+ for (i=0; i < num_entries;i++) {
+ unsigned int index;
+
+ if (root_entries[i].mode == S_IFDIR) {
+ if (root_entries[i].name)
+ /* defer dir free till all sub-entries freed */
+ continue;
+ else
+ /* cleanup parent */
+ index = root_entries[i].parent_index;
+ } else {
+ index = i;
+ }
+
+ if (root_entries[index].dentry) {
+ securityfs_remove(root_entries[index].dentry);
+
+ AA_DEBUG("%s: deleted apparmorfs entry name=%s "
+ "dentry=%p\n",
+ __FUNCTION__,
+ root_entries[index].name,
+ root_entries[index].dentry);
+
+ root_entries[index].dentry = NULL;
+ root_entries[index].parent_index = 0;
+ }
+ }
+}
+
+static int populate_apparmorfs(struct dentry *root)
+{
+ unsigned int i, parent_index, depth;
+
+ for (i = 0; i < num_entries; i++) {
+ root_entries[i].dentry = NULL;
+ root_entries[i].parent_index = 0;
+ }
+
+ /* 1. Verify entry 0 is valid [sanity check] */
+ if (num_entries == 0 ||
+ !root_entries[0].name ||
+ strcmp(root_entries[0].name, SECFS_AA) != 0 ||
+ root_entries[0].mode != S_IFDIR) {
+ AA_ERROR("%s: root entry 0 is not SECFS_AA/dir\n",
+ __FUNCTION__);
+ goto error;
+ }
+
+ /* 2. Build back pointers */
+ parent_index = 0;
+ depth = 1;
+
+ for (i = 1; i < num_entries; i++) {
+ root_entries[i].parent_index = parent_index;
+
+ if (root_entries[i].name &&
+ root_entries[i].mode == S_IFDIR) {
+ depth++;
+ parent_index = i;
+ } else if (!root_entries[i].name) {
+ if (root_entries[i].mode != S_IFDIR || depth == 0) {
+ AA_ERROR("%s: root_entry %d invalid (%u %d)",
+ __FUNCTION__, i,
+ root_entries[i].mode,
+ root_entries[i].parent_index);
+ goto error;
+ }
+
+ depth--;
+ parent_index = root_entries[parent_index].parent_index;
+ }
+ }
+
+ if (depth != 0) {
+ AA_ERROR("%s: root_entry table not correctly terminated\n",
+ __FUNCTION__);
+ goto error;
+ }
+
+ /* 3. Create root (parent=NULL) */
+ root_entries[0].dentry = securityfs_create_file(
+ root_entries[0].name,
+ root_entries[0].mode |
+ root_entries[0].access,
+ NULL, NULL, NULL);
+
+ if (IS_ERR(root_entries[0].dentry))
+ goto error;
+ else
+ AA_DEBUG("%s: created securityfs/apparmor [dentry=%p]\n",
+ __FUNCTION__, root_entries[0].dentry);
+
+
+ /* 4. create remaining nodes */
+ for (i = 1; i < num_entries; i++) {
+ struct dentry *parent;
+ void *data = NULL;
+ struct file_operations *fops = NULL;
+
+ /* end of directory ? */
+ if (!root_entries[i].name)
+ continue;
+
+ parent = root_entries[root_entries[i].parent_index].dentry;
+
+ if (root_entries[i].mode != S_IFDIR) {
+ data = root_entries[i].data;
+ fops = root_entries[i].fops;
+ }
+
+ root_entries[i].dentry = securityfs_create_file(
+ root_entries[i].name,
+ root_entries[i].mode |
+ root_entries[i].access,
+ parent,
+ data,
+ fops);
+
+ if (IS_ERR(root_entries[i].dentry))
+ goto cleanup_error;
+
+ AA_DEBUG("%s: added apparmorfs entry "
+ "name=%s mode=%x dentry=%p [parent %p]\n",
+ __FUNCTION__, root_entries[i].name,
+ root_entries[i].mode|root_entries[i].access,
+ root_entries[i].dentry, parent);
+ }
+
+ return 0;
+
+cleanup_error:
+ clear_apparmorfs();
+
+error:
+ return -EINVAL;
+}
+
+int create_apparmorfs(void)
+{
+ int error = 0;
+
+ if (AAFS_DENTRY) {
+ error = -EEXIST;
+ AA_ERROR("%s: Subdomain securityfs already exists\n",
+ __FUNCTION__);
+ } else {
+ error = populate_apparmorfs(aafs_dentry);
+ if (error != 0) {
+ AA_ERROR("%s: Error populating Subdomain securityfs\n",
+ __FUNCTION__);
+ }
+ }
+
+ return error;
+}
+
+void destroy_apparmorfs(void)
+{
+ if (AAFS_DENTRY)
+ clear_apparmorfs();
+}
next prev parent reply other threads:[~2006-04-19 17:54 UTC|newest]
Thread overview: 173+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
2006-04-19 17:57 ` Arjan van de Ven
2006-04-19 18:10 ` Tony Jones
2006-04-19 18:35 ` Valdis.Kletnieks
2006-04-19 19:55 ` Adrian Bunk
2006-04-19 20:52 ` Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 2/11] security: AppArmor - Core headers Tony Jones
2006-04-19 18:01 ` Arjan van de Ven
2006-04-20 17:43 ` Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 3/11] security: AppArmor - LSM interface Tony Jones
2006-04-19 18:05 ` Arjan van de Ven
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
2006-04-19 18:10 ` Arjan van de Ven
2006-04-19 18:57 ` Crispin Cowan
2006-04-19 23:05 ` Rik van Riel
2006-04-19 23:18 ` Seth Arnold
2006-04-19 23:21 ` Rik van Riel
2006-04-19 23:50 ` Crispin Cowan
2006-04-20 12:33 ` Stephen Smalley
2006-04-20 16:27 ` Lars Marowsky-Bree
2006-04-20 17:39 ` Tony Jones
2006-04-19 19:32 ` Jan Engelhardt
2006-04-19 19:50 ` Stephen Smalley
2006-04-20 9:40 ` Al Viro
2006-04-20 11:40 ` Serge E. Hallyn
2006-04-20 21:39 ` Tony Jones
2006-04-19 17:49 ` Tony Jones [this message]
2006-04-21 21:13 ` [RFC][PATCH 5/11] security: AppArmor - Filesystem Amy Griffis
2006-04-19 17:49 ` [RFC][PATCH 6/11] security: AppArmor - Userspace interface Tony Jones
2006-04-20 21:39 ` Pavel Machek
2006-04-21 18:01 ` Tony Jones
2006-04-21 18:41 ` Pavel Machek
2006-04-19 17:50 ` [RFC][PATCH 7/11] security: AppArmor - Misc (capabilities, data structures) Tony Jones
2006-04-19 18:16 ` Stephen Hemminger
2006-04-19 17:50 ` [RFC][PATCH 8/11] security: AppArmor - Pathname matching submodule Tony Jones
2006-04-19 17:50 ` [RFC][PATCH 9/11] security: AppArmor - Audit changes Tony Jones
2006-04-21 21:21 ` Amy Griffis
2006-04-22 0:13 ` Steve Grubb
2006-04-22 0:19 ` Tony Jones
2006-04-19 17:50 ` [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path Tony Jones
2006-04-19 22:12 ` Christoph Hellwig
2006-04-20 5:36 ` Tony Jones
2006-04-20 8:26 ` Arjan van de Ven
2006-04-20 16:43 ` Tony Jones
2006-04-20 17:04 ` Christoph Hellwig
2006-04-20 17:50 ` Tony Jones
2006-04-21 12:16 ` Stephen Smalley
2006-04-24 13:05 ` Alan Cox
2006-04-19 17:50 ` [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore Tony Jones
2006-04-19 22:10 ` Christoph Hellwig
2006-04-20 12:39 ` Stephen Smalley
2006-04-20 12:46 ` Serge E. Hallyn
2006-04-20 12:05 ` Stephen Smalley
2006-04-20 13:21 ` Serge E. Hallyn
2006-04-20 12:48 ` Stephen Smalley
2006-04-20 12:58 ` Stephen Smalley
2006-04-20 22:11 ` Linda A. Walsh
2006-04-20 23:05 ` Christoph Hellwig
2006-04-21 1:29 ` Linda A. Walsh
2006-04-21 2:09 ` Chris Wright
2006-04-21 5:10 ` Linda Walsh
2006-04-23 12:11 ` Arjan van de Ven
2006-04-21 14:02 ` Stephen Smalley
2006-04-20 19:45 ` Tony Jones
2006-04-20 20:16 ` Serge E. Hallyn
2006-04-20 20:22 ` James Morris
2006-04-20 21:50 ` Linda Walsh
2006-04-20 21:56 ` Al Viro
2006-04-20 23:54 ` James Morris
2006-04-21 13:59 ` Stephen Smalley
2006-04-19 18:14 ` [RFC][PATCH 0/11] security: AppArmor - Overview Arjan van de Ven
2006-04-19 22:32 ` Andi Kleen
2006-04-19 23:00 ` grundig
2006-04-19 23:38 ` Andi Kleen
2006-04-20 1:32 ` Crispin Cowan
2006-04-20 13:00 ` grundig
2006-04-20 13:09 ` Serge E. Hallyn
2006-04-20 13:15 ` Al Viro
2006-04-21 0:11 ` Tony Jones
2006-04-24 13:01 ` Alan Cox
2006-04-20 8:42 ` Arjan van de Ven
2006-04-20 19:26 ` Crispin Cowan
2006-04-20 19:27 ` Chris Wright
2006-04-21 12:18 ` Stephen Smalley
2006-04-21 17:30 ` Chris Wright
2006-04-21 18:07 ` Stephen Smalley
2006-04-21 20:06 ` Valdis.Kletnieks
2006-04-21 20:35 ` Stephen Smalley
2006-04-21 20:44 ` Stephen Smalley
2006-04-21 21:38 ` Dave Neuer
2006-04-22 10:01 ` Thomas Bleher
2006-04-24 4:18 ` Neil Brown
2006-04-24 7:03 ` Theodore Ts'o
2006-04-24 13:04 ` Pavel Machek
2006-04-24 13:43 ` Joshua Brindle
2006-04-24 21:07 ` Stephen Smalley
2006-04-24 23:52 ` Theodore Ts'o
2006-04-25 6:22 ` Arjan van de Ven
2006-04-25 16:45 ` Stephen Smalley
2006-04-25 16:52 ` Arjan van de Ven
2006-04-25 17:43 ` Seth Arnold
2006-04-25 18:34 ` Valdis.Kletnieks
2006-04-25 18:48 ` Stephen Smalley
2006-04-25 18:56 ` Valdis.Kletnieks
2006-04-25 4:25 ` Casey Schaufler
2006-04-25 7:50 ` James Morris
2006-04-25 12:46 ` Theodore Ts'o
2006-04-25 15:06 ` Stephen Smalley
2006-04-25 16:00 ` Casey Schaufler
2006-04-25 16:21 ` Randy.Dunlap
2006-04-26 3:42 ` Casey Schaufler
2006-04-26 12:15 ` Stephen Smalley
2006-04-27 0:21 ` Casey Schaufler
2006-04-27 14:47 ` Karl MacMillan
2006-04-25 17:29 ` Stephen Smalley
2006-04-26 3:56 ` Casey Schaufler
2006-04-26 11:32 ` Stephen Smalley
2006-04-25 16:47 ` Stephen Smalley
2006-04-24 7:14 ` Arjan van de Ven
2006-04-24 8:11 ` Lars Marowsky-Bree
2006-04-25 19:27 ` Seth Arnold
2006-04-24 13:11 ` Joshua Brindle
2006-04-24 13:26 ` Andi Kleen
2006-04-24 13:39 ` Joshua Brindle
2006-04-24 15:16 ` Joshua Brindle
2006-04-24 15:50 ` Tony Jones
2006-04-24 17:03 ` Joshua Brindle
2006-04-25 17:12 ` Valdis.Kletnieks
2006-04-25 17:34 ` Tony Jones
2006-04-24 13:52 ` Alan Cox
2006-04-24 14:09 ` Andi Kleen
2006-04-24 20:45 ` Stephen Smalley
2006-04-25 8:10 ` Neil Brown
2006-04-25 8:28 ` Al Viro
2006-04-25 12:42 ` James Carter
2006-04-25 12:43 ` Andi Kleen
2006-04-25 14:50 ` James Carter
2006-04-25 15:01 ` Stephen Smalley
2006-04-25 18:11 ` Tony Jones
2006-04-25 21:25 ` Stephen Smalley
2006-04-25 17:07 ` Stephen Smalley
2006-04-26 22:15 ` Some Concrete AppArmor Questions - was " Neil Brown
2006-04-26 23:06 ` Ken Brush
2006-04-27 4:15 ` Andi Kleen
2006-04-27 6:52 ` Arjan van de Ven
2006-04-27 7:40 ` Chris Wright
2006-04-27 10:17 ` Chris Wright
2006-04-27 14:42 ` Karl MacMillan
2006-04-27 23:44 ` Chris Wright
2006-04-28 13:02 ` Stephen Smalley
2006-04-28 15:49 ` Casey Schaufler
2006-04-28 16:04 ` Stephen Hemminger
2006-04-28 21:49 ` James Morris
2006-04-28 16:56 ` Karl MacMillan
2006-04-27 16:03 ` Stephen Smalley
2006-04-27 22:38 ` Chris Wright
2006-04-28 13:00 ` Stephen Smalley
2006-04-27 17:43 ` Stephen Smalley
2006-04-27 17:58 ` Ken Brush
2006-04-28 11:28 ` Stephen Smalley
2006-04-28 11:47 ` Andi Kleen
2006-04-28 12:28 ` Stephen Smalley
2006-04-27 11:02 ` Christoph Hellwig
2006-04-27 11:05 ` Andi Kleen
2006-04-20 11:29 ` Serge E. Hallyn
2006-04-20 13:24 ` Christoph Hellwig
2006-04-20 22:32 ` Linda A. Walsh
2006-04-20 12:17 ` Stephen Smalley
2006-04-20 15:38 ` Joshua Brindle
2006-04-20 19:57 ` Crispin Cowan
2006-04-21 13:34 ` Stephen Smalley
2006-04-22 12:27 ` Pavel Machek
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=20060419174946.29149.40949.sendpatchset@ermintrude.int.wirex.com \
--to=tonyj@suse.de \
--cc=chrisw@sous-sol.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome