Discussion:
[PATCH v1 2/4] integrity: provide file reading API
Dmitry Kasatkin
2014-07-15 12:54:21 UTC
Permalink
Signed-off-by: Dmitry Kasatkin <***@samsung.com>
---
security/integrity/Kconfig | 3 +++
security/integrity/digsig.c | 41 +++++++++++++++++++++++++++++++++++++++++
security/integrity/integrity.h | 2 +-
3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 463219b..1f000c4 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -50,6 +50,9 @@ config INTEGRITY_AUDIT
be enabled by specifying 'integrity_audit=1' on the kernel
command line.

+config INTEGRITY_FILE_READ
+ def_bool n
+
source security/integrity/ima/Kconfig
source security/integrity/evm/Kconfig

diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 8d4fbff..85d6662 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -18,6 +18,8 @@
#include <linux/cred.h>
#include <linux/key-type.h>
#include <linux/digsig.h>
+#include <linux/slab.h>
+#include <linux/file.h>

#include "integrity.h"

@@ -63,6 +65,45 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
return -EOPNOTSUPP;
}

+#ifdef CONFIG_INTEGRITY_FILE_READ
+int integrity_read_file(const char *path, char **data)
+{
+ struct file *file;
+ loff_t size;
+ char *buf;
+ int rc = -EINVAL;
+
+ file = filp_open(path, O_RDONLY, 0);
+ if (IS_ERR(file)) {
+ rc = PTR_ERR(file);
+ pr_err("Unable to open file: %s (%d)", path, rc);
+ return rc;
+ }
+
+ size = i_size_read(file_inode(file));
+ if (size <= 0)
+ goto out;
+
+ buf = kmalloc(size, GFP_KERNEL);
+ if (!buf) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /* should be ima_kernel_read */
+ rc = kernel_read(file, 0, buf, size);
+ if (rc < 0)
+ kfree(buf);
+ else if (rc != size)
+ rc = -EIO;
+ else
+ *data = buf;
+out:
+ fput(file);
+ return rc;
+}
+#endif
+
int integrity_init_keyring(const unsigned int id)
{
const struct cred *cred = current_cred();
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7656d47..f77de68 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -130,7 +130,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);

int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
const char *digest, int digestlen);
-
+int integrity_read_file(const char *path, char **data);
int integrity_init_keyring(const unsigned int id);
#else
--
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Kasatkin
2014-07-15 12:54:23 UTC
Permalink
This patch provides kernel parameter CONFIG_IMA_APPRAISE_SIGNED_INIT
to force initial user-space verification using signatures.
This is useful, when EVM key is not initalized yet and we want securely
initialize integrity or any other functionality. It implements
ima_preapre_keys() hook to load X509 certificate into the .ima trusted
kernel keyring from root filesystem. It forces embedded policy to
check signature. Signed initialization script can initialize EVM key,
update the IMA policy and change requirement of everything to be signed.

Signed-off-by: Dmitry Kasatkin <***@samsung.com>
---
security/integrity/ima/Kconfig | 15 +++++++++++++++
security/integrity/ima/ima_init.c | 17 +++++++++++++++++
security/integrity/ima/ima_policy.c | 5 +++++
3 files changed, 37 insertions(+)

diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 2477d1e..294ee2f 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -132,3 +132,18 @@ config IMA_TRUSTED_KEYRING
help
This option requires that all keys added to the .ima
keyring be signed by a key on the system trusted keyring.
+
+config IMA_APPRAISE_SIGNED_INIT
+ bool "Require signed user-space initialization"
+ depends on IMA_TRUSTED_KEYRING
+ select INTEGRITY_LOAD_X509
+ default n
+ help
+ This option requires user-space init to be signed.
+
+config IMA_X509_PATH
+ string "IMA X509 certificate path"
+ depends on IMA_APPRAISE_SIGNED_INIT
+ default "/init/ima/x509_ima.der"
+ help
+ This option defines IMA X509 certificate path.
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 8cf0f39..120b041 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -24,6 +24,12 @@
#include <crypto/hash_info.h>
#include "ima.h"

+#ifdef CONFIG_IMA_X509_PATH
+#define IMA_X509_PATH CONFIG_IMA_X509_PATH
+#else
+#define IMA_X509_PATH "/init/ima/x509_ima.der"
+#endif
+
/* name for boot aggregate entry */
static const char *boot_aggregate_name = "boot_aggregate";
int ima_used_chip;
@@ -85,6 +91,17 @@ err_out:
audit_cause, result, 0);
}

+void __init ima_prepare_keys(void)
+{
+ if (ima_initialized) {
+ /* disable IMA to load the key */
+ /* hackish for now */
+ ima_initialized = 0;
+ integrity_load_x509(INTEGRITY_KEYRING_IMA, IMA_X509_PATH);
+ ima_initialized = 1;
+ }
+}
+
int __init ima_init(void)
{
u8 pcr_i[TPM_DIGEST_SIZE];
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index b9716d9..96e885f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -97,7 +97,12 @@ static struct ima_rule_entry default_appraise_rules[] = {
{.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
{.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
+#ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT
{.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER},
+#else
+ /* force signature */
+ {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER | IMA_DIGSIG_REQUIRED},
+#endif
};

static LIST_HEAD(ima_default_rules);
--
1.9.1
Dmitry Kasatkin
2014-07-15 12:54:22 UTC
Permalink
Provide API to load x509 certificates from the kernel into the
integrity kernel keyrings.

Signed-off-by: Dmitry Kasatkin <***@samsung.com>
---
security/integrity/Kconfig | 4 ++++
security/integrity/digsig.c | 37 +++++++++++++++++++++++++++++++++++++
security/integrity/integrity.h | 9 +++++++++
3 files changed, 50 insertions(+)

diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 1f000c4..63766fb 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -53,6 +53,10 @@ config INTEGRITY_AUDIT
config INTEGRITY_FILE_READ
def_bool n

+config INTEGRITY_LOAD_X509
+ select INTEGRITY_FILE_READ
+ def_bool n
+
source security/integrity/ima/Kconfig
source security/integrity/evm/Kconfig

diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 85d6662..63f66cc 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -104,6 +104,43 @@ out:
}
#endif

+#ifdef CONFIG_INTEGRITY_LOAD_X509
+int integrity_load_x509(const unsigned int id, char *path)
+{
+ key_ref_t key;
+ char *data;
+ int rc;
+
+ if (!keyring[id])
+ return -EINVAL;
+
+ rc = integrity_read_file(path, &data);
+ if (rc < 0)
+ return rc;
+
+ key = key_create_or_update(make_key_ref(keyring[id], 1),
+ "asymmetric",
+ NULL,
+ data,
+ rc,
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW | KEY_USR_READ),
+ KEY_ALLOC_NOT_IN_QUOTA |
+ KEY_ALLOC_TRUSTED);
+ if (IS_ERR(key)) {
+ rc = PTR_ERR(key);
+ pr_err("Problem loading X.509 certificate (%d): %s\n",
+ rc, path);
+ } else {
+ pr_notice("Loaded X.509 cert '%s': %s\n",
+ key_ref_to_ptr(key)->description, path);
+ key_ref_put(key);
+ }
+ kfree(data);
+ return 0;
+}
+#endif
+
int integrity_init_keyring(const unsigned int id)
{
const struct cred *cred = current_cred();
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index f77de68..a4de3e3 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -158,6 +158,15 @@ static inline int asymmetric_verify(struct key *keyring, const char *sig,
}
#endif

+#ifdef CONFIG_INTEGRITY_LOAD_X509
+int integrity_load_x509(const unsigned int id, char *path);
+#else
+static inline int integrity_load_x509(const unsigned int id, char *path)
+{
+ return 0;
+}
+#endif
+
#ifdef CONFIG_INTEGRITY_AUDIT
/* declarations */
void integrity_audit_msg(int audit_msgno, struct inode *inode,
--
1.9.1
Dmitry Kasatkin
2014-07-15 12:54:20 UTC
Permalink
Keys can only be loaded when rootfs is mounted. Initcalls
are not suitable for that. Provide a special hook.

Signed-off-by: Dmitry Kasatkin <***@samsung.com>
---
include/linux/ima.h | 9 +++++++++
init/main.c | 6 +++++-
2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/include/linux/ima.h b/include/linux/ima.h
index 23a87a4..b617c1a 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -73,4 +73,13 @@ static inline int ima_inode_removexattr(struct dentry *dentry,
return 0;
}
#endif /* CONFIG_IMA_APPRAISE */
+
+#ifdef CONFIG_IMA_APPRAISE_SIGNED_INIT
+extern void __init ima_prepare_keys(void);
+#else
+static inline void ima_prepare_keys(void)
+{
+}
+#endif
+
#endif /* _LINUX_IMA_H */
diff --git a/init/main.c b/init/main.c
index e8ae1fe..b24cfaa 100644
--- a/init/main.c
+++ b/init/main.c
@@ -78,6 +78,7 @@
#include <linux/context_tracking.h>
#include <linux/random.h>
#include <linux/list.h>
+#include <linux/ima.h>

#include <asm/io.h>
#include <asm/bugs.h>
@@ -1028,6 +1029,9 @@ static noinline void __init kernel_init_freeable(void)
* initmem segments and start the user-mode stuff..
*/

- /* rootfs is available now, try loading default modules */
+ /* rootfs is available now */
+ /* try loading public keys */
+ ima_prepare_keys();
+ /* try loading default modules */
load_default_modules();
}
--
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Andrew Morton
2014-07-15 21:33:15 UTC
Permalink
Currently secure IMA/EVM initialization has to be done from the initramfs,
embedded in the signed kernel image. Many systems do not want to use
initramfs or usage of embedded initramfs makes it difficult to have
multi-target kernels.
This is a very simple patchset which makes it possible to perform secure
initialization by requiring initial user-space to be signed.
- introducing IMA public keys loading hook
- loading IMA trusted public key into .ima trusted keyring
- making default IMA appraisal policy to require everything to be signed
When builtin initramfs is not in use, keys cannot be read from initcalls,
because root filesystem is not yet mounted. In order to read keys before
executing init process, ima_prepare_keys() hook is introduced. Reading
public keys from the kernel is justified because signature verification
key is needed in order to verify anything else which is read from the
file system. Public keys are X509 certificates and itself signed by the
trusted key from the .system keyring. Kernel BIG KEYS support is an example
of reading keys directly by the kernel.
CONFIG_IMA_APPRAISE_SIGNED_INIT kernel option is provided to make the IMA
default appraisal policy to required signature validation. Signed init
process need to initialize EVM key and load appropriate IMA policy which
would not require everything to be signed.
Unless real '/sbin/init' is signed, a simple and practical way is to place
all signed programs, libraries, scripts and configuration files under
dedicated directory, for example '/ima', and run signed init process by
providing a kernel command line parameter 'init=/ima/init'
The kernel may already have loaded kernel modules before it gets around
to mounting rootfs and running /sbin/init. How does that fit into the
overall signing scheme? And how did /sbin/modprobe get its signature
checked?


The proposed interface and implementation look reasonable to me.
Opening and reading a file from the root fs is a bit unusual, but we
already do something similar with "/sbin/init" and the reasoning here
is similar.

The only alternative I can immediately think of is to bundle the public
keys into a kernel module and load them into the kernel that way but

- if/when we implement module signing, we have a chicken-and-egg problem

- doing it via a kernel module seems a bit fake - a bit of trickery
to reduce code duplication. Better to do it explicitly.


One thing I'm wondering: integrity_read_file() is a very simple
open-file-and-slurp-it-into-memory. Have you checked whether other
code sites are doing the same thing? Perhaps integrity_read_file()
should be in ./lib/ and other callsites can be converted to share it?

That comment in integrity_read_file() is completely useless :(


--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Kasatkin
2014-07-16 20:26:46 UTC
Permalink
Hello,


On Wed, Jul 16, 2014 at 12:33 AM, Andrew Morton
Post by Andrew Morton
Currently secure IMA/EVM initialization has to be done from the initramfs,
embedded in the signed kernel image. Many systems do not want to use
initramfs or usage of embedded initramfs makes it difficult to have
multi-target kernels.
This is a very simple patchset which makes it possible to perform secure
initialization by requiring initial user-space to be signed.
- introducing IMA public keys loading hook
- loading IMA trusted public key into .ima trusted keyring
- making default IMA appraisal policy to require everything to be signed
When builtin initramfs is not in use, keys cannot be read from initcalls,
because root filesystem is not yet mounted. In order to read keys before
executing init process, ima_prepare_keys() hook is introduced. Reading
public keys from the kernel is justified because signature verification
key is needed in order to verify anything else which is read from the
file system. Public keys are X509 certificates and itself signed by the
trusted key from the .system keyring. Kernel BIG KEYS support is an example
of reading keys directly by the kernel.
CONFIG_IMA_APPRAISE_SIGNED_INIT kernel option is provided to make the IMA
default appraisal policy to required signature validation. Signed init
process need to initialize EVM key and load appropriate IMA policy which
would not require everything to be signed.
Unless real '/sbin/init' is signed, a simple and practical way is to place
all signed programs, libraries, scripts and configuration files under
dedicated directory, for example '/ima', and run signed init process by
providing a kernel command line parameter 'init=/ima/init'
The kernel may already have loaded kernel modules before it gets around
to mounting rootfs and running /sbin/init. How does that fit into the
overall signing scheme? And how did /sbin/modprobe get its signature
checked?
If kernel embedded initramfs is in use then it is signed together with kernel,
and this functionality is not needed and no need to enable it with
kernel configuration.

As it is IMA extensions and it is entirely based on IMA functionality
it requires
extended attribute support.

If externally loaded initramfs is used, then that one uses cpio based
archive that
does not support extended attributes and thus external initramfs cannot be used
for secure initialization.

This functionality is targeted to be used without initramfs on normal
filesystems
supporting xattrs. In such case, modprobe cannot be loaded before
rootfs is mounted.
Any filesystems and block device drivers obviously need to be embedded
into the kernel.
In the place where ima_prepare_keys() hooks is called, we have

ima_prepare_keys();
load_default_modules();

So we load keys after mounting rootfs and before calling load_default_modules().
So if anything useful kernel loads with load_default_modules, will be
loaded after
IMA key is available and thus modprobe will be verified.
Post by Andrew Morton
The proposed interface and implementation look reasonable to me.
Opening and reading a file from the root fs is a bit unusual, but we
already do something similar with "/sbin/init" and the reasoning here
is similar.
The only alternative I can immediately think of is to bundle the public
keys into a kernel module and load them into the kernel that way but
- if/when we implement module signing, we have a chicken-and-egg problem
- doing it via a kernel module seems a bit fake - a bit of trickery
to reduce code duplication. Better to do it explicitly.
This was the idea. Kernel has embedded certificate signing key on the
.system keyring. Filesystem image/package can come with own signing key
and that one is loaded and verified by existing KEY infrastructure.
Entire signed init code can come as rpm or deb package with its own key.
That is benefit of loading key.
Post by Andrew Morton
One thing I'm wondering: integrity_read_file() is a very simple
open-file-and-slurp-it-into-memory. Have you checked whether other
code sites are doing the same thing? Perhaps integrity_read_file()
should be in ./lib/ and other callsites can be converted to share it?
Yes, indeed, I saw. For code cleanness for posting I thought to have
it all belonging to integrity subsystem. I can make it as additional patch
for the next post to show how to "refactor" common code and if needed to
squash it.
Post by Andrew Morton
That comment in integrity_read_file() is completely useless :(
Ough, you mean /* should be ima_kernel_read */ ??

The thing is that ima_kernel_read which is used to read file for hashing
does not honor security checks.. Indeed, kernel must read it regardless
any obstacles. The same is here with keys...
I worked on this patch in parallel I introduced ima_kernel_read.

So if ima_kernel_read would be used, then we cannot share integrity_read_file
as they other code uses kernel_read and honors security checks.

We had discussion with Mimi on list to move and rename ima_kernel_read
as "kernel_read_nosec" or something like that. It was once suggested
by Eric Biederman.
So then we could have such "helper" function.

Let us think about it.

Thank you for commenting.

-Dmitry
Mimi Zohar
2014-07-23 19:08:49 UTC
Permalink
Post by Dmitry Kasatkin
Hello,
On Wed, Jul 16, 2014 at 12:33 AM, Andrew Morton
Post by Andrew Morton
Currently secure IMA/EVM initialization has to be done from the initramfs,
embedded in the signed kernel image. Many systems do not want to use
initramfs or usage of embedded initramfs makes it difficult to have
multi-target kernels.
This is a very simple patchset which makes it possible to perform secure
initialization by requiring initial user-space to be signed.
- introducing IMA public keys loading hook
- loading IMA trusted public key into .ima trusted keyring
- making default IMA appraisal policy to require everything to be signed
When builtin initramfs is not in use, keys cannot be read from initcalls,
because root filesystem is not yet mounted. In order to read keys before
executing init process, ima_prepare_keys() hook is introduced. Reading
public keys from the kernel is justified because signature verification
key is needed in order to verify anything else which is read from the
file system. Public keys are X509 certificates and itself signed by the
trusted key from the .system keyring. Kernel BIG KEYS support is an example
of reading keys directly by the kernel.
CONFIG_IMA_APPRAISE_SIGNED_INIT kernel option is provided to make the IMA
default appraisal policy to required signature validation. Signed init
process need to initialize EVM key and load appropriate IMA policy which
would not require everything to be signed.
Unless real '/sbin/init' is signed, a simple and practical way is to place
all signed programs, libraries, scripts and configuration files under
dedicated directory, for example '/ima', and run signed init process by
providing a kernel command line parameter 'init=/ima/init'
The kernel may already have loaded kernel modules before it gets around
to mounting rootfs and running /sbin/init. How does that fit into the
overall signing scheme? And how did /sbin/modprobe get its signature
checked?
If kernel embedded initramfs is in use then it is signed together with kernel,
and this functionality is not needed and no need to enable it with
kernel configuration.
As it is IMA extensions and it is entirely based on IMA functionality
it requires extended attribute support.
If externally loaded initramfs is used, then that one uses cpio based
archive that does not support extended attributes and thus external
initramfs cannot be used for secure initialization.
Right, but GNU tar version 1.27.1 supports Posix.1 (ustar) format, which
has xattr support. GNU CPIO supports the Posix.1 tar format. The
question is whether CPIO supports the included xattrs.
Post by Dmitry Kasatkin
This functionality is targeted to be used without initramfs on normal
filesystems supporting xattrs. In such case, modprobe cannot be loaded before
rootfs is mounted. Any filesystems and block device drivers obviously
need to be embedded into the kernel. In the place where
ima_prepare_keys() hooks is called, we have
ima_prepare_keys();
load_default_modules();
So we load keys after mounting rootfs and before calling load_default_modules().
So if anything useful kernel loads with load_default_modules, will be
loaded after IMA key is available and thus modprobe will be verified.
Post by Andrew Morton
The proposed interface and implementation look reasonable to me.
Opening and reading a file from the root fs is a bit unusual, but we
already do something similar with "/sbin/init" and the reasoning here
is similar.
The only alternative I can immediately think of is to bundle the public
keys into a kernel module and load them into the kernel that way but
- if/when we implement module signing, we have a chicken-and-egg problem
- doing it via a kernel module seems a bit fake - a bit of trickery
to reduce code duplication. Better to do it explicitly.
This was the idea. Kernel has embedded certificate signing key on the
.system keyring. Filesystem image/package can come with own signing key
and that one is loaded and verified by existing KEY infrastructure.
Entire signed init code can come as rpm or deb package with its own key.
That is benefit of loading key.
Ok, this type of solution addresses the concerns of devices, but we also
need a viable solution for systems with an initramfs.

Mimi

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Kasatkin
2014-07-29 21:37:04 UTC
Permalink
Post by Mimi Zohar
Post by Dmitry Kasatkin
Hello,
On Wed, Jul 16, 2014 at 12:33 AM, Andrew Morton
Post by Andrew Morton
Currently secure IMA/EVM initialization has to be done from the initramfs,
embedded in the signed kernel image. Many systems do not want to use
initramfs or usage of embedded initramfs makes it difficult to have
multi-target kernels.
This is a very simple patchset which makes it possible to perform secure
initialization by requiring initial user-space to be signed.
- introducing IMA public keys loading hook
- loading IMA trusted public key into .ima trusted keyring
- making default IMA appraisal policy to require everything to be signed
When builtin initramfs is not in use, keys cannot be read from initcalls,
because root filesystem is not yet mounted. In order to read keys before
executing init process, ima_prepare_keys() hook is introduced. Reading
public keys from the kernel is justified because signature verification
key is needed in order to verify anything else which is read from the
file system. Public keys are X509 certificates and itself signed by the
trusted key from the .system keyring. Kernel BIG KEYS support is an example
of reading keys directly by the kernel.
CONFIG_IMA_APPRAISE_SIGNED_INIT kernel option is provided to make the IMA
default appraisal policy to required signature validation. Signed init
process need to initialize EVM key and load appropriate IMA policy which
would not require everything to be signed.
Unless real '/sbin/init' is signed, a simple and practical way is to place
all signed programs, libraries, scripts and configuration files under
dedicated directory, for example '/ima', and run signed init process by
providing a kernel command line parameter 'init=/ima/init'
The kernel may already have loaded kernel modules before it gets around
to mounting rootfs and running /sbin/init. How does that fit into the
overall signing scheme? And how did /sbin/modprobe get its signature
checked?
If kernel embedded initramfs is in use then it is signed together with kernel,
and this functionality is not needed and no need to enable it with
kernel configuration.
As it is IMA extensions and it is entirely based on IMA functionality
it requires extended attribute support.
If externally loaded initramfs is used, then that one uses cpio based
archive that does not support extended attributes and thus external
initramfs cannot be used for secure initialization.
Right, but GNU tar version 1.27.1 supports Posix.1 (ustar) format, which
has xattr support. GNU CPIO supports the Posix.1 tar format. The
question is whether CPIO supports the included xattrs.
Post by Dmitry Kasatkin
This functionality is targeted to be used without initramfs on normal
filesystems supporting xattrs. In such case, modprobe cannot be loaded before
rootfs is mounted. Any filesystems and block device drivers obviously
need to be embedded into the kernel. In the place where
ima_prepare_keys() hooks is called, we have
ima_prepare_keys();
load_default_modules();
So we load keys after mounting rootfs and before calling load_default_modules().
So if anything useful kernel loads with load_default_modules, will be
loaded after IMA key is available and thus modprobe will be verified.
Post by Andrew Morton
The proposed interface and implementation look reasonable to me.
Opening and reading a file from the root fs is a bit unusual, but we
already do something similar with "/sbin/init" and the reasoning here
is similar.
The only alternative I can immediately think of is to bundle the public
keys into a kernel module and load them into the kernel that way but
- if/when we implement module signing, we have a chicken-and-egg problem
- doing it via a kernel module seems a bit fake - a bit of trickery
to reduce code duplication. Better to do it explicitly.
This was the idea. Kernel has embedded certificate signing key on the
.system keyring. Filesystem image/package can come with own signing key
and that one is loaded and verified by existing KEY infrastructure.
Entire signed init code can come as rpm or deb package with its own key.
That is benefit of loading key.
Ok, this type of solution addresses the concerns of devices, but we also
need a viable solution for systems with an initramfs.
Mimi
Sorry for the late reply. I am on holidays at the moment.

Offered solution is simple one to work without initramfs.

When using initramfs, one approach is that it can be be embedded into
the kernel.

When initramfs is separate, offered solution would work as well, but
it would require initramfs container, which is 'cpio' would support
extended attributes. cpio does not support them. 'cpio' maintainer
Sergey Poznyakoff replied in my email to him that it would require
standardization work. He suggested that it is better to use 'tar'
archive which supports xattrs. Using tar for initramfs would require
initramfs tool changes across all distros and kernel. As I said above
offered solution would work as well for initramfs without any changes
if initramfs container would support xattrs... So further extensions
are not related to this patchset.

Thanks,
Dmitry
Dmitry Kasatkin
2014-10-10 14:15:32 UTC
Permalink
Hello Andrew,

I have just posted updated patchset.
Please check patch description where I discuss your questions and
related changes.

Thanks,
Dmitry
Post by Dmitry Kasatkin
Post by Mimi Zohar
Post by Dmitry Kasatkin
Hello,
On Wed, Jul 16, 2014 at 12:33 AM, Andrew Morton
Post by Andrew Morton
Currently secure IMA/EVM initialization has to be done from the initramfs,
embedded in the signed kernel image. Many systems do not want to use
initramfs or usage of embedded initramfs makes it difficult to have
multi-target kernels.
This is a very simple patchset which makes it possible to perform secure
initialization by requiring initial user-space to be signed.
- introducing IMA public keys loading hook
- loading IMA trusted public key into .ima trusted keyring
- making default IMA appraisal policy to require everything to be signed
When builtin initramfs is not in use, keys cannot be read from initcalls,
because root filesystem is not yet mounted. In order to read keys before
executing init process, ima_prepare_keys() hook is introduced. Reading
public keys from the kernel is justified because signature verification
key is needed in order to verify anything else which is read from the
file system. Public keys are X509 certificates and itself signed by the
trusted key from the .system keyring. Kernel BIG KEYS support is an example
of reading keys directly by the kernel.
CONFIG_IMA_APPRAISE_SIGNED_INIT kernel option is provided to make the IMA
default appraisal policy to required signature validation. Signed init
process need to initialize EVM key and load appropriate IMA policy which
would not require everything to be signed.
Unless real '/sbin/init' is signed, a simple and practical way is to place
all signed programs, libraries, scripts and configuration files under
dedicated directory, for example '/ima', and run signed init process by
providing a kernel command line parameter 'init=/ima/init'
The kernel may already have loaded kernel modules before it gets around
to mounting rootfs and running /sbin/init. How does that fit into the
overall signing scheme? And how did /sbin/modprobe get its signature
checked?
If kernel embedded initramfs is in use then it is signed together with kernel,
and this functionality is not needed and no need to enable it with
kernel configuration.
As it is IMA extensions and it is entirely based on IMA functionality
it requires extended attribute support.
If externally loaded initramfs is used, then that one uses cpio based
archive that does not support extended attributes and thus external
initramfs cannot be used for secure initialization.
Right, but GNU tar version 1.27.1 supports Posix.1 (ustar) format, which
has xattr support. GNU CPIO supports the Posix.1 tar format. The
question is whether CPIO supports the included xattrs.
Post by Dmitry Kasatkin
This functionality is targeted to be used without initramfs on normal
filesystems supporting xattrs. In such case, modprobe cannot be loaded before
rootfs is mounted. Any filesystems and block device drivers obviously
need to be embedded into the kernel. In the place where
ima_prepare_keys() hooks is called, we have
ima_prepare_keys();
load_default_modules();
So we load keys after mounting rootfs and before calling load_default_modules().
So if anything useful kernel loads with load_default_modules, will be
loaded after IMA key is available and thus modprobe will be verified.
Post by Andrew Morton
The proposed interface and implementation look reasonable to me.
Opening and reading a file from the root fs is a bit unusual, but we
already do something similar with "/sbin/init" and the reasoning here
is similar.
The only alternative I can immediately think of is to bundle the public
keys into a kernel module and load them into the kernel that way but
- if/when we implement module signing, we have a chicken-and-egg problem
- doing it via a kernel module seems a bit fake - a bit of trickery
to reduce code duplication. Better to do it explicitly.
This was the idea. Kernel has embedded certificate signing key on the
.system keyring. Filesystem image/package can come with own signing key
and that one is loaded and verified by existing KEY infrastructure.
Entire signed init code can come as rpm or deb package with its own key.
That is benefit of loading key.
Ok, this type of solution addresses the concerns of devices, but we also
need a viable solution for systems with an initramfs.
Mimi
Sorry for the late reply. I am on holidays at the moment.
Offered solution is simple one to work without initramfs.
When using initramfs, one approach is that it can be be embedded into
the kernel.
When initramfs is separate, offered solution would work as well, but
it would require initramfs container, which is 'cpio' would support
extended attributes. cpio does not support them. 'cpio' maintainer
Sergey Poznyakoff replied in my email to him that it would require
standardization work. He suggested that it is better to use 'tar'
archive which supports xattrs. Using tar for initramfs would require
initramfs tool changes across all distros and kernel. As I said above
offered solution would work as well for initramfs without any changes
if initramfs container would support xattrs... So further extensions
are not related to this patchset.
Thanks,
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...