@@ -838,17 +838,20 @@ int ima_post_load_data(char *buf, loff_t size,
838838 * @pcr: pcr to extend the measurement
839839 * @func_data: func specific data, may be NULL
840840 * @buf_hash: measure buffer data hash
841+ * @digest: buffer digest will be written to
842+ * @digest_len: buffer length
841843 *
842844 * Based on policy, either the buffer data or buffer data hash is measured
843845 *
844- * Return: 0 if the buffer has been successfully measured, a negative value
845- * otherwise.
846+ * Return: 0 if the buffer has been successfully measured, 1 if the digest
847+ * has been written to the passed location but not added to a measurement entry,
848+ * a negative value otherwise.
846849 */
847850int process_buffer_measurement (struct user_namespace * mnt_userns ,
848851 struct inode * inode , const void * buf , int size ,
849852 const char * eventname , enum ima_hooks func ,
850853 int pcr , const char * func_data ,
851- bool buf_hash )
854+ bool buf_hash , u8 * digest , size_t digest_len )
852855{
853856 int ret = 0 ;
854857 const char * audit_cause = "ENOMEM" ;
@@ -869,7 +872,10 @@ int process_buffer_measurement(struct user_namespace *mnt_userns,
869872 int action = 0 ;
870873 u32 secid ;
871874
872- if (!ima_policy_flag )
875+ if (digest && digest_len < digest_hash_len )
876+ return - EINVAL ;
877+
878+ if (!ima_policy_flag && !digest )
873879 return - ENOENT ;
874880
875881 template = ima_template_desc_buf ();
@@ -891,7 +897,7 @@ int process_buffer_measurement(struct user_namespace *mnt_userns,
891897 action = ima_get_action (mnt_userns , inode , current_cred (),
892898 secid , 0 , func , & pcr , & template ,
893899 func_data );
894- if (!(action & IMA_MEASURE ))
900+ if (!(action & IMA_MEASURE ) && ! digest )
895901 return - ENOENT ;
896902 }
897903
@@ -922,6 +928,12 @@ int process_buffer_measurement(struct user_namespace *mnt_userns,
922928 event_data .buf_len = digest_hash_len ;
923929 }
924930
931+ if (digest )
932+ memcpy (digest , iint .ima_hash -> digest , digest_hash_len );
933+
934+ if (!ima_policy_flag || (func && !(action & IMA_MEASURE )))
935+ return 1 ;
936+
925937 ret = ima_alloc_init_template (& event_data , & entry , template );
926938 if (ret < 0 ) {
927939 audit_cause = "alloc_entry" ;
@@ -964,7 +976,7 @@ void ima_kexec_cmdline(int kernel_fd, const void *buf, int size)
964976
965977 process_buffer_measurement (file_mnt_user_ns (f .file ), file_inode (f .file ),
966978 buf , size , "kexec-cmdline" , KEXEC_CMDLINE , 0 ,
967- NULL , false);
979+ NULL , false, NULL , 0 );
968980 fdput (f );
969981}
970982
@@ -975,26 +987,30 @@ void ima_kexec_cmdline(int kernel_fd, const void *buf, int size)
975987 * @buf: pointer to buffer data
976988 * @buf_len: length of buffer data (in bytes)
977989 * @hash: measure buffer data hash
990+ * @digest: buffer digest will be written to
991+ * @digest_len: buffer length
978992 *
979993 * Measure data critical to the integrity of the kernel into the IMA log
980994 * and extend the pcr. Examples of critical data could be various data
981995 * structures, policies, and states stored in kernel memory that can
982996 * impact the integrity of the system.
983997 *
984- * Return: 0 if the buffer has been successfully measured, a negative value
985- * otherwise.
998+ * Return: 0 if the buffer has been successfully measured, 1 if the digest
999+ * has been written to the passed location but not added to a measurement entry,
1000+ * a negative value otherwise.
9861001 */
9871002int ima_measure_critical_data (const char * event_label ,
9881003 const char * event_name ,
9891004 const void * buf , size_t buf_len ,
990- bool hash )
1005+ bool hash , u8 * digest , size_t digest_len )
9911006{
9921007 if (!event_name || !event_label || !buf || !buf_len )
9931008 return - ENOPARAM ;
9941009
9951010 return process_buffer_measurement (& init_user_ns , NULL , buf , buf_len ,
9961011 event_name , CRITICAL_DATA , 0 ,
997- event_label , hash );
1012+ event_label , hash , digest ,
1013+ digest_len );
9981014}
9991015
10001016static int __init init_ima (void )
0 commit comments