Subject: [PATCH] [BZ 148767] libica: libica crash with illegal instruction on z196/z114 From: Harald Freudenberger Description: libica: libica crash with illegal instruction on z196/z114 Symptom: 'illegal instruction' on libica initialization Problem: Upon initialization libica checks all the MSA levels of the system to find out the available functions. This check function reuses a buffer variable without proper reinitialization thus leading to detect an MSA 5 function PPNO which is in fact not available on z196/z114 systems. Upon initialization the libica internal pseudo random generator is initialized which is then trying to use this PPNO function and so the 'illegal instruction' occurs. Solution: Fix libica initialization function. Reproduction: On z196/z114 systems with every libica version >= 2.6. Upstream-ID: eeb40e5aea7dd36580629e6b17cd7f03fb62549c Problem-ID: 148767 Signed-off-by: Harald Freudenberger Index: libica-service/src/s390_crypto.c =================================================================== --- libica-service.orig/src/s390_crypto.c 2016-11-18 12:04:39.809574833 +0100 +++ libica-service/src/s390_crypto.c 2016-11-18 12:04:39.805574781 +0100 @@ -144,6 +144,8 @@ void set_switches(int msa) * kimd query and do not need to over the whole array. Therfore there * is also no distict setting of the switch needed in form * msa4_switch = 1. */ + + /* kmc query */ memset(mask, 0, sizeof(mask)); if (msa) { if (begin_sigill_section(&oldact, &oldset) == 0) { @@ -160,13 +162,14 @@ void set_switches(int msa) *s390_kmc_functions[n].enabled = on; } + /* kimd query */ + memset(mask, 0, sizeof(mask)); if (msa) { if (begin_sigill_section(&oldact, &oldset) == 0) { s390_kimd(S390_CRYPTO_QUERY, mask, (void *) 0, 0); end_sigill_section(&oldact, &oldset); } } - for (n = 0; n < (sizeof(s390_kimd_functions) / sizeof(s390_supported_function_t)); n++) { if (S390_CRYPTO_TEST_MASK(mask, s390_kimd_functions[n].hw_fc)) @@ -176,6 +179,8 @@ void set_switches(int msa) *s390_kimd_functions[n].enabled = on; } + /* ppno query */ + memset(mask, 0, sizeof(mask)); if (5 <= msa) { msa5_switch = 1; if (begin_sigill_section(&oldact, &oldset) == 0) { @@ -183,7 +188,6 @@ void set_switches(int msa) end_sigill_section(&oldact, &oldset); } } - for (n = 0; n < (sizeof(s390_ppno_functions) / sizeof(s390_supported_function_t)); n++) { if (S390_CRYPTO_TEST_MASK(mask, s390_ppno_functions[n].hw_fc)) @@ -254,7 +258,7 @@ libica_func_list_element_int icaList[] = {RSA_KEY_GEN_ME, ADAPTER, 0, ICA_FLAG_SW, 0}, // SW (openssl) {RSA_KEY_GEN_CRT, ADAPTER, 0, ICA_FLAG_SW, 0}, // SW (openssl) - {SHA512_DRNG, PPNO, SHA512_DRNG_GEN, ICA_FLAG_SHW | ICA_FLAG_SW, 0}, + {SHA512_DRNG, PPNO, SHA512_DRNG_GEN, ICA_FLAG_SW, 0}, /* available for the MSA4 instruction */ /* available for the RSA instruction */