|
From: Bo Z. <bob...@gm...> - 2013-04-04 13:16:30
|
On Wed, Apr 3, 2013 at 8:45 PM, Mimi Zohar <zo...@li...> wrote:
>
> On Tue, 2013-04-02 at 03:19 +0800, Bo Zhi wrote:
> > hi, all
> >
> > I have some questions about the EVM extended attribute data structure.
> >
> > first, why is the EVM xattr data structure different between kernel
> > space and user space ?
> >
> > here is the definition of EVM xattr data structure in kernel (3.8.0):
> >
> > struct evm_ima_xattr_data {
> > u8 type;
> > u8 digest[SHA1_DIGEST_SIZE];
> > } __attribute__((packed));
> >
> > and the init and update operations in kernel (3.8.0) are all operated
> > with "struct evm_ima_xattr_data", e.g.
> >
> > [in evm_main.c]
> > int evm_inode_init_security(struct inode *inode,
> > const struct xattr *lsm_xattr,
> > struct xattr *evm_xattr)
> > {
> > struct evm_ima_xattr_data *xattr_data;
> > int rc;
> > ...
> > xattr_data->type = EVM_XATTR_HMAC;
> > rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
> > if (rc < 0)
> > goto out;
> >
> >
> > evm_xattr->value = xattr_data;
> > evm_xattr->value_len = sizeof(*xattr_data);
> > evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS);
> > return 0;
> > out:
> > kfree(xattr_data);
> > return rc;
> > }
> >
> >
> > [in evm_crypto.c]
> > int evm_update_evmxattr(struct dentry *dentry, const char
> > *xattr_name,
> > const char *xattr_value, size_t xattr_value_len)
> > {
> > struct inode *inode = dentry->d_inode;
> > struct evm_ima_xattr_data xattr_data;
> > int rc = 0;
> >
> >
> > rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
> > xattr_value_len, xattr_data.digest);
> > if (rc == 0) {
> > xattr_data.type = EVM_XATTR_HMAC;
> > rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
> > &xattr_data,
> > sizeof(xattr_data), 0);
> > } else if (rc == -ENODATA && inode->i_op->removexattr) {
> > rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
> > }
> > return rc;
> > }
> >
> >
> >
> >
> > while in the ima-evm-utils(evmctl), security.evm is signed with
> > "unsigned char sig[1024]"
> >
> >
> > static int sign_evm(const char *file, const char *key)
> > {
> > unsigned char hash[20];
> > unsigned char sig[1024] = "\x03";
> > ...
> > err = setxattr(file, "security.evm", sig, len + 1, 0);
> > if (err < 0) {
> > log_err("setxattr failed: %s\n", file);
> > return err;
> > }
> > return 0;
> > }
> >
> > I am confused here, can anybody help me ?
> >
> > second, I have already run the IMA module and ima-evm-utils on Gentoo
> > with these docs:
> >
> > [1]
> > http://www.gentoo.org/proj/en/hardened/integrity/docs/ima-guide.xml
> > [2]
> > http://www.gentoo.org/proj/en/hardened/integrity/docs/evm-guide.xml
> >
> >
> > and get security.ima and security.evm like this:
> >
> >
> > tcel keys # getfattr -m . -d ~/pgydyd
> > # file: root/pgydyd
> > security.evm=0sAwFKz
> > +1QAAA9Yz7H6RrISQEEAC8rEMhvs9q5HkwTU1EJOCdCTz0KLyhR1knpH/yT
> > W0EPa241Z+d4gSvX2cQadcKlpNAFw+f5LWHQrNVyXAERY3
> > +GGA3LPaEucGeXv6UseKuhblFD57S
> > WO901IM4woC2zRcq55dD0rkNYxEz/vKmmYuVjRnh9RX6bQWH68/yvCwSh
> > security.ima=0sAYP1pcNZ89yDF1GSQOMvH1H2i8BR
> >
> >
> > the format of the hash or sign result is totally different with [1]'s:
> >
> >
> > ~# getfattr -m . -d /boot/grub/grub.conf
> > # file: grub.conf
> > security.selinux="root:object_r:boot_t"
> > security.ima="76a0d787be14d84dfe3cf3930ac3da38bb389464"
> >
> >
> > I don't believe this is a programming mistake, maybe I did something
> > wrong, or it is related with the first question.
> >
> >
> > thanks in advance :)
>
> 'security.evm' contains either an HMAC or a digital signature, of which
> there are two formats - original, asymmetric. 'security.ima' contains
> either a hash or a digital signature. Based on the evmctl arguments,
> determines both the 'security.evm' and 'security.ima' xattr contents.
>
> evm_verify_hmac() verifies the HMAC or calls integrity_digsig_verify(),
> which in turn calls either digsig_verify() or asymmetric_verify(), to
> verify the digital signature.
>
> Try using the getfattr '--e hex' option to output the binary data in
> hex.
>
hi, Mimi,
thank you, but you didn't solve my doubts yet, i think that is because
i didn't express it clearly enough, sorry.
let me describe my doubts again.
1. the extended attributes associated with inodes are described as:
struct xattr{
char *name;
void *value;
size_t value_len;
};
2. the type of value in struct xattr is a void pointer, so it can be
associated with any types of pointers.
and in IMA, 'security.ima' and 'security.evm' are using the same data structure:
struct evm_ima_xattr_data {
u8 type;
u8 digest[SHA1_DIGEST_SIZE];
} __attribute__((packed));
so, the void pointer is replaced with pointer of struct evm_ima_xattr_data.
3. i know both 'security.evm' and 'security.ima' contains two formats
extended attributes,
so the type member is needed, and digest is just the real using data.
4. when we are to set 'security.ima' or 'security.evm',
we need set both evm_ima_xattr_data.type and evm_ima_xattr_data.value
because of the definition.
and the kernel code in "integrity" is just doing like this.(i know you
are very familiar with it :) )
5. in the user space, evmctl sets different formats with different parameters,
but the actual value passed to setxattr system call is a string (char *),
6. string vs. struct evm_ima_xattr_data, wouldn't this be a conflict ?
why don't we pass the ima or evm extended values from the user space
with a data structure like this?
struct evm_ima_xattr_usersapce {
int type;
char digest[SHA1_DIGEST_SIZE];
} __attribute__((packed));
just the same as kernel's.
thank you, hope i didn't say anything wrong, did i ?
best regards,
Bo Zhi
> thanks,
>
> Mimi
>
> >
> > btw, i am a student and now i am trying to develop another security
> > module which is related with IMA,
> > i have read the source code of "integrity" about 4 or 5 days.
> >
> >
> > Best Regards,
> >
> > Zhi Bo
>
>
|