From 725eea28191030d28cd668d3e5b5cad3e164aa87 Mon Sep 17 00:00:00 2001 From: Artem Polyakov Date: Mon, 23 May 2016 12:25:24 +0300 Subject: [PATCH] Fix base64 implementation in pmix framework. In the commit 80f07b65f16e9538aca7fc5e124d2074e7e0b69e setting of '-' marker used as the string termination sign was moved from base64 code: from: https://github.com/open-mpi/ompi/commit/80f07b65f16e9538aca7fc5e124d2074e7e0b69e#diff-1b10896c267d2591dc2c08fd0542ab67L491 to: https://github.com/open-mpi/ompi/commit/80f07b65f16e9538aca7fc5e124d2074e7e0b69e#diff-1b10896c267d2591dc2c08fd0542ab67R189 However the decoding function wasn't fixed and still expects on extra byte at the end of the encoded string which leads to data truncation during extraction (was noticed on standalone code that was using base64 from OMPI). --- opal/mca/pmix/base/pmix_base_fns.c | 38 ++++++++++++++---------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/opal/mca/pmix/base/pmix_base_fns.c b/opal/mca/pmix/base/pmix_base_fns.c index 57e873385a..51ea06a3ec 100644 --- a/opal/mca/pmix/base/pmix_base_fns.c +++ b/opal/mca/pmix/base/pmix_base_fns.c @@ -5,6 +5,8 @@ * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. * Copyright (c) 2014-2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. + * Copyright (c) 2016 Mellanox Technologies, Inc. + * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -556,7 +558,7 @@ int opal_pmix_base_cache_keys_locally(const opal_process_name_t* id, const char* } /* search for each key in the decoded data */ - for (offset = 0 ; offset < len && '\0' != tmp_val[offset] ; ) { + for (offset = 0 ; offset < len ; ) { /* type */ tmp = tmp_val + offset + strlen (tmp_val + offset) + 1; /* size */ @@ -669,11 +671,11 @@ static inline unsigned char pmi_base64_encsym (unsigned char value) { assert (value < 64); if (value < 26) { - return 'A' + value; + return 'A' + value; } else if (value < 52) { - return 'a' + (value - 26); + return 'a' + (value - 26); } else if (value < 62) { - return '0' + (value - 52); + return '0' + (value - 52); } return (62 == value) ? '+' : '/'; @@ -681,19 +683,18 @@ static inline unsigned char pmi_base64_encsym (unsigned char value) { static inline unsigned char pmi_base64_decsym (unsigned char value) { if ('+' == value) { - return 62; + return 62; } else if ('/' == value) { - return 63; + return 63; } else if (' ' == value) { - return 64; + return 64; } else if (value <= '9') { - return (value - '0') + 52; + return (value - '0') + 52; } else if (value <= 'Z') { - return (value - 'A'); + return (value - 'A'); } else if (value <= 'z') { - return (value - 'a') + 26; + return (value - 'a') + 26; } - return 64; } @@ -715,12 +716,12 @@ static inline int pmi_base64_decode_block (const char in[4], unsigned char out[3 out[0] = in_dec[0] << 2 | in_dec[1] >> 4; if (64 == in_dec[2]) { - return 1; + return 1; } out[1] = in_dec[1] << 4 | in_dec[2] >> 2; if (64 == in_dec[3]) { - return 2; + return 2; } out[2] = ((in_dec[2] << 6) & 0xc0) | in_dec[3]; @@ -736,7 +737,7 @@ static char *pmi_encode(const void *val, size_t vallen) outdata = calloc (((2 + vallen) * 4) / 3 + 2, 1); if (NULL == outdata) { - return NULL; + return NULL; } for (i = 0, tmp = outdata ; i < vallen ; i += 3, tmp += 4) { @@ -750,7 +751,7 @@ static char *pmi_encode(const void *val, size_t vallen) static uint8_t *pmi_decode (const char *data, size_t *retlen) { - size_t input_len = (strlen (data) - 1) / 4; + size_t input_len = strlen (data) / 4; unsigned char *ret; int out_len; size_t i; @@ -758,16 +759,13 @@ static uint8_t *pmi_decode (const char *data, size_t *retlen) /* default */ *retlen = 0; - ret = calloc (1, 3 * input_len + 1); + ret = calloc (1, 3 * input_len); if (NULL == ret) { return ret; } - for (i = 0, out_len = 0 ; i < input_len ; i++, data += 4) { - out_len += pmi_base64_decode_block(data, ret + 3 * i); + out_len += pmi_base64_decode_block(data, ret + 3 * i); } - - ret[out_len] = '\0'; *retlen = out_len; return ret; }