integrity : utils Add 2 more inode atributes to hash
RFC PATCH 1/1 integrity : utils Add 2 more inode atributes to hash
From 0c48d5261ef653cc9ab73db7aa7bdf6bae4d9818 Mon Sep 17 00:00:00 2001
From: Lev Olshvang <[email protected]>
Date: Sun, 5 Apr 2020 22:29:22 +0300
Subject: [RFC PATCH] integrity : utils Add 2 more inode atributes to hash
Added inode attr fields and file size in to inode metadate hash. Inode attr is importent because it may influence how filesystem treats the file.
I think that some use cases relies on immutable attribute on files or directories and some use cases marks encrypted files with a special attribute
Therefore it is importent to check also integrity of inode->i_attr Code refactored a bit to avoid duplicate code paths
I refactored also couple of very similar data types to avoid pointer conversions.
--- src/evmctl.c | 244 ++++++++++++++++++++++++--------------------------- src/imaevm.h | 34 +++---- 2 files changed, 127 insertions(+), 151 deletions(-)
src/evmctl.c +115 -129
@@ -117,7 +117,13 @@ static char *ino_str;static char *uid_str;static char *gid_str;static char *mode_str; +static char *flags_str; +static char *size_str; + + +static char *generation_str; +static uint32_t generation =0 ;static char *caps_str;static char *ima_str;static char *selinux_str;
@@ -306,18 +312,24 @@ static int pack_uuid(const char *uuid_str, char *uuid)return 0 ; } -static int get_uuid (struct stat *st,char *uuid) +static int get_uuid (const char *const file,char *uuid) {uint32_t dev;unsigned minor, major;char path[PATH_MAX ], _uuid[37 ];FILE *fp;size_t len; +struct stat st;if (uuid_str)return pack_uuid (uuid_str, uuid); - dev = st->st_dev; +if (lstat (file, &st)) { +log_err ("Failed to stat: %s\n" , file); +return -1 ; + } + + dev = st.st_dev; major = (dev &0xfff00 ) >>8 ; minor = (dev &0xff ) | ((dev >>12 ) &0xfff00 );
@@ -338,33 +350,42 @@ err:log_err ("Failed to read UUID. Root access might require.\n" );return -1 ; } +static void store_inode_meta (uint32_t attr,file_common_t *hmac,const struct stat *const st) { + hmac->uid = st->st_uid; + hmac->gid = st->st_gid; + hmac->mode = st->st_mode; + hmac->attr = attr; + hmac->filesize = (uint32_t ) st->st_size; +} -static int calc_evm_hash (const char *file,unsigned char *hash) -{ -const EVP_MD *md; +static int fill_hmac (const char *const file,file_meta_t * hmac_misc) { +uint16_t hmac_size =sizeof (*hmac_misc); +uint32_t attr =0 ;struct stat st; -int err; -uint32_t generation =0 ; -EVP_MD_CTX *pctx; -unsigned int mdlen; -char **xattrname; -char xattr_value[1024 ]; -char list[1024 ]; -ssize_t list_size; -char uuid[16 ]; -struct h_misc_64 hmac_misc; -int hmac_size; -#if OPENSSL_VERSION_NUMBER <0x10100000 -EVP_MD_CTX ctx; - pctx = &ctx; -#else - pctx =EVP_MD_CTX_new (); -#endif + + generation =0 ;if (lstat (file, &st)) {log_err ("Failed to stat: %s\n" , file);return -1 ; } +if ( st.st_size >0xFFFFFFFF ) { +log_err ("File too big %s\n" , file); +return -E2BIG ; + } +int fd =open (file,0 ); +if (fd <0 ) { +log_err ("Failed to open: %s\n" , file); +return -1 ; + } +int rc =ioctl (fd,FS_IOC_GETFLAGS , &attr); +if (rc) { +log_err ("ioctl() FS_IOC_GETFLAGS failed, rc=%d\n" , rc); +close (fd); +return -1 ; + } +close (fd); +log_info ("attr: %x\n" , attr);if (generation_str) generation =strtoul (generation_str,NULL ,10 );
@@ -376,6 +397,10 @@ static int calc_evm_hash(const char *file, unsigned char *hash) st.st_gid =strtoul (gid_str,NULL ,10 );if (mode_str) st.st_mode =strtoul (mode_str,NULL ,10 ); +if (size_str) + st.st_size =strtoul (size_str,NULL ,10 ); +if (flags_str) + st.st_size =strtoul (flags_str,NULL ,10 );if (!evm_immutable) {if ((S_ISREG (st.st_mode) ||S_ISDIR (st.st_mode)) && !generation_str) {
@@ -396,6 +421,57 @@ static int calc_evm_hash(const char *file, unsigned char *hash) }log_info ("generation: %u\n" , generation); } + +memset (hmac_misc,0 , hmac_size); + +if (evm_immutable) { +// hmac_dig_sig, portable +file_common_t *hmac = &(hmac_misc->portable_fstat); + + hmac_size =sizeof (*hmac); +store_inode_meta (attr, hmac, &st); + + }else { +file_extra_t *hmac = &(hmac_misc->non_portable_fstat); + hmac_size =sizeof (*hmac); +if (!evm_portable) { + hmac->ino = st.st_ino; + hmac->generation = generation; + } +file_common_t *hmac_p = &(hmac_misc->portable_fstat); +store_inode_meta (attr, hmac_p, &st); + } +return hmac_size; +} + +static int calc_evm_hash (const char *file,unsigned char *hash) +{ +const EVP_MD *md; +int err; +uint16_t hmac_size; +EVP_MD_CTX *pctx; +unsigned int mdlen; +char **xattrname; +char xattr_value[1024 ]; +char list[1024 ]; +ssize_t list_size; +char uuid[16 ]; +file_meta_t hmac_misc; + + err =fill_hmac (file, &hmac_misc); +if (err <0 ) { +return err; + } + hmac_size = (uint16_t ) err; +log_debug ("hmac_misc (%d): " , hmac_size); +log_debug_dump (&hmac_misc, hmac_size); + +#if OPENSSL_VERSION_NUMBER <0x10100000 +EVP_MD_CTX ctx; + pctx = &ctx; +#else + pctx =EVP_MD_CTX_new (); +#endif list_size =llistxattr (file, list,sizeof (list));if (list_size <0 ) {
@@ -464,51 +540,8 @@ static int calc_evm_hash(const char *file, unsigned char *hash) } } -memset (&hmac_misc,0 ,sizeof (hmac_misc)); - -if (evm_immutable) { -struct h_misc_digsig *hmac = (struct h_misc_digsig *)&hmac_misc; - - hmac_size =sizeof (*hmac); - hmac->uid = st.st_uid; - hmac->gid = st.st_gid; - hmac->mode = st.st_mode; - }else if (msize ==0 ) { -struct h_misc *hmac = (struct h_misc *)&hmac_misc; - hmac_size =sizeof (*hmac); -if (!evm_portable) { - hmac->ino = st.st_ino; - hmac->generation = generation; - } - hmac->uid = st.st_uid; - hmac->gid = st.st_gid; - hmac->mode = st.st_mode; - }else if (msize ==64 ) { -struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc; - - hmac_size =sizeof (*hmac); -if (!evm_portable) { - hmac->ino = st.st_ino; - hmac->generation = generation; - } - hmac->uid = st.st_uid; - hmac->gid = st.st_gid; - hmac->mode = st.st_mode; - }else { -struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc; - - hmac_size =sizeof (*hmac); -if (!evm_portable) { - hmac->ino = st.st_ino; - hmac->generation = generation; - } - hmac->uid = st.st_uid; - hmac->gid = st.st_gid; - hmac->mode = st.st_mode; - } - -log_debug ("hmac_misc (%d): " , hmac_size); +log_debug ("hmac_misc (%u): " , hmac_size);log_debug_dump (&hmac_misc, hmac_size); err =EVP_DigestUpdate (pctx, &hmac_misc, hmac_size);
@@ -519,7 +552,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)if (!evm_immutable && !evm_portable && !(hmac_flags &HMAC_FLAG_NO_UUID )) { - err =get_uuid (&st, uuid); + err =get_uuid (file, uuid);if (err)return -1 ;
@@ -1064,10 +1097,9 @@ static int cmd_setxattr_ima(struct command *cmd)static int calc_evm_hmac (const char *file,const char *keyfile,unsigned char *hash) { -const EVP_MD *md; -struct stat st; +const EVP_MD *md; +int err =-1 ; -uint32_t generation =0 ;HMAC_CTX *pctx;unsigned int mdlen;char **xattrname;
@@ -1077,8 +1109,19 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *hunsigned char evmkey[MAX_KEY_SIZE ];char list[1024 ];ssize_t list_size; -struct h_misc_64 hmac_misc; +file_meta_t hmac_misc;int hmac_size; + + + hmac_size =fill_hmac (file, &hmac_misc); +if (hmac_size <0 ) { +return hmac_size; + } + +log_debug ("hmac_misc (%d): " , hmac_size); +log_debug_dump (&hmac_misc, hmac_size); + +#if OPENSSL_VERSION_NUMBER <0x10100000 HMAC_CTX ctx; pctx = &ctx;
@@ -1101,30 +1144,7 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *hmemcpy (evmkey, key, keylen);memset (evmkey + keylen,0 ,sizeof (evmkey) - keylen); -if (lstat (file, &st)) { -log_err ("Failed to stat: %s\n" , file); - goto out; - } - -if (S_ISREG (st.st_mode) ||S_ISDIR (st.st_mode)) { -/* we cannot at the momement to get generation of special files.. -* kernel API does not support it */ -int fd =open (file,0 ); - -if (fd <0 ) { -log_err ("Failed to open %s\n" , file); - goto out; - } -if (ioctl (fd,FS_IOC_GETVERSION , &generation)) { -log_err ("ioctl() failed\n" ); -close (fd); - goto out; - } -close (fd); - } - -log_info ("generation: %u\n" , generation); - + list_size =llistxattr (file, list,sizeof (list));if (list_size <=0 ) {log_err ("llistxattr() failed: %s\n" , file);
@@ -1164,40 +1184,6 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h } } -memset (&hmac_misc,0 ,sizeof (hmac_misc)); - -if (msize ==0 ) { -struct h_misc *hmac = (struct h_misc *)&hmac_misc; - - hmac_size =sizeof (*hmac); - hmac->ino = st.st_ino; - hmac->generation = generation; - hmac->uid = st.st_uid; - hmac->gid = st.st_gid; - hmac->mode = st.st_mode; - }else if (msize ==64 ) { -struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc; - - hmac_size =sizeof (*hmac); - hmac->ino = st.st_ino; - hmac->generation = generation; - hmac->uid = st.st_uid; - hmac->gid = st.st_gid; - hmac->mode = st.st_mode; - }else { -struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc; - - hmac_size =sizeof (*hmac); - hmac->ino = st.st_ino; - hmac->generation = generation; - hmac->uid = st.st_uid; - hmac->gid = st.st_gid; - hmac->mode = st.st_mode; - } - -log_debug ("hmac_misc (%d): " , hmac_size); -log_debug_dump (&hmac_misc, hmac_size); - err = !HMAC_Update (pctx, (const unsigned char *)&hmac_misc, hmac_size);if (err) {log_err ("HMAC_Update() failed\n" );
src/imaevm.h +12 -22
@@ -90,35 +90,25 @@ enum evm_ima_xattr_type { EVM_XATTR_PORTABLE_DIGSIG, }; -struct h_misc { -unsigned long ino; -uint32_t generation; +typedef struct _common {uid_t uid;gid_t gid;unsigned short mode; -}; +uint32_t attr; +uint32_t filesize; +}file_common_t ; -struct h_misc_32 { -uint32_t ino; +typedef struct _extra { +file_common_t inode_common;uint32_t generation; -uid_t uid; -gid_t gid; -unsigned short mode; -}; - -struct h_misc_64 {uint64_t ino; -uint32_t generation; -uid_t uid; -gid_t gid; -unsigned short mode; -}; +}file_extra_t ; + +typedef union _extended { +file_common_t portable_fstat; +file_extra_t non_portable_fstat; +}file_meta_t ; -struct h_misc_digsig { -uid_t uid; -gid_t gid; -unsigned short mode; -};enum pubkey_algo {PUBKEY_ALGO_RSA ,
--
2.17.1