1
1
openmpi/oshmem/info/info.c
Igor Ivanov 5c061abf4e oshmem: Fix scan coverity issues
1324740 - Resource leak
1304562 - Unchecked return value
1340514 - Dereference before null check
1340515 - Use of untrusted scalar value
1340516 - Use of untrusted string value
2015-12-02 12:49:19 +02:00

337 строки
8.9 KiB
C

/*
* Copyright (c) 2015 Mellanox Technologies, Inc.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "oshmem_config.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "orte/runtime/orte_globals.h"
#include "orte/util/show_help.h"
#include "opal/util/opal_environ.h"
#include "opal/util/output.h"
#include "oshmem/version.h"
#include "oshmem/constants.h"
#include "oshmem/info/info.h"
#include "oshmem/shmem/shmem_api_logger.h"
/*
* Global variables
*/
oshmem_info_t oshmem_shmem_info_env = {
false,
false,
false,
256 * 1024 * 1024
};
#define OSHMEM_MAX_LIBRARY_VERSION_STRING 256
/*
* Local functions
*/
static int oshmem_info_value_to_bool(char *value, bool *interp);
static int oshmem_info_value_to_int(char *value, int *interp);
static int oshmem_info_get_heap_size(char *value, size_t *interp);
static int oshmem_info_get_library_version(char *version, int *len);
/*
* This function is called during oshmem_init.
*/
int oshmem_info_init(void)
{
int ret = OSHMEM_SUCCESS;
char *cptr;
/* fill the env info object */
if (NULL != (cptr = getenv(OSHMEM_ENV_VERSION))) {
ret = oshmem_info_value_to_bool(cptr, &oshmem_shmem_info_env.print_version);
if (OSHMEM_SUCCESS != ret) {
goto out;
}
}
if (oshmem_shmem_info_env.print_version && 0 == ORTE_PROC_MY_NAME->vpid) {
char version[OSHMEM_MAX_LIBRARY_VERSION_STRING];
int len;
ret = oshmem_info_get_library_version(version, &len);
if (OSHMEM_SUCCESS != ret || 0 == len) {
goto out;
}
orte_show_help("help-shmem-runtime.txt",
"oshmem_init:print-version",
true,
version);
}
if (NULL != (cptr = getenv(OSHMEM_ENV_INFO))) {
ret = oshmem_info_value_to_bool(cptr, &oshmem_shmem_info_env.print_info);
if (OSHMEM_SUCCESS != ret) {
goto out;
}
}
if (oshmem_shmem_info_env.print_info && 0 == ORTE_PROC_MY_NAME->vpid) {
orte_show_help("help-shmem-runtime.txt",
"oshmem_init:print-info",
true,
OSHMEM_ENV_VERSION,
OSHMEM_ENV_INFO,
OSHMEM_ENV_SYMMETRIC_SIZE,
OSHMEM_ENV_DEBUG);
}
if (NULL != (cptr = getenv(OSHMEM_ENV_DEBUG))) {
ret = oshmem_info_value_to_bool(cptr, &oshmem_shmem_info_env.debug);
if (OSHMEM_SUCCESS != ret) {
goto out;
}
}
if (NULL != (cptr = getenv(OSHMEM_ENV_SYMMETRIC_SIZE))) {
char *p1 = getenv(SHMEM_HEAP_SIZE);
if (p1 && strcmp(cptr, p1)) {
SHMEM_API_ERROR("Found conflict between env '%s' and '%s'.\n",
OSHMEM_ENV_SYMMETRIC_SIZE, SHMEM_HEAP_SIZE);
ret = OSHMEM_ERR_BAD_PARAM;
goto out;
}
ret = oshmem_info_get_heap_size(cptr, &oshmem_shmem_info_env.symmetric_heap_size);
if (OSHMEM_SUCCESS != ret) {
goto out;
}
} else if (NULL != (cptr = getenv(SHMEM_HEAP_SIZE))) {
ret = oshmem_info_get_heap_size(cptr, &oshmem_shmem_info_env.symmetric_heap_size);
if (OSHMEM_SUCCESS != ret) {
goto out;
}
}
/* All done */
return OSHMEM_SUCCESS;
out:
return ret;
}
/*
* Shut down oshmem_info handling
*/
int oshmem_info_finalize(void)
{
/* All done -- destroy the table */
return OSHMEM_SUCCESS;
}
/**
* Convert value string to boolean
*
* Convert value string \c value into a boolean. The
* strings "true", "false", and integer numbers can be converted
* into booleans. All others will return \c OSHMEM_ERR_BAD_PARAM
*
* @param value Value string for info key to interpret
* @param interp returned interpretation of the value key
*
* @retval OSHMEM_SUCCESS string was successfully interpreted
* @retval OSHMEM_ERR_BAD_PARAM string was not able to be interpreted
*/
static int oshmem_info_value_to_bool(char *value, bool *interp)
{
int tmp;
/* idiot case */
if (NULL == value || NULL == interp) return OSHMEM_ERR_BAD_PARAM;
/* is it true / false? */
if (0 == strcmp(value, "true")) {
*interp = true;
return OSHMEM_SUCCESS;
} else if (0 == strcmp(value, "false")) {
*interp = false;
return OSHMEM_SUCCESS;
/* is it a number? */
} else if (OSHMEM_SUCCESS == oshmem_info_value_to_int(value, &tmp)) {
if (tmp == 0) {
*interp = false;
} else {
*interp = true;
}
return OSHMEM_SUCCESS;
}
return OSHMEM_ERR_BAD_PARAM;
}
/**
* Convert value string to integer
*
* Convert value string \c value into a integer.
* All others will return \c OSHMEM_ERR_BAD_PARAM
*
* @param value Value string for info key to interpret
* @param interp returned interpretation of the value key
*
* @retval OSHMEM_SUCCESS string was successfully interpreted
* @retval OSHMEM_ERR_BAD_PARAM string was not able to be interpreted
*/
static int oshmem_info_value_to_int(char *value, int *interp)
{
long tmp;
char *endp;
if (NULL == value || '\0' == value[0]) return OSHMEM_ERR_BAD_PARAM;
errno = 0;
tmp = strtol(value, &endp, 10);
/* we found something not a number */
if (*endp != '\0') return OSHMEM_ERR_BAD_PARAM;
/* underflow */
if (tmp == 0 && errno == EINVAL) return OSHMEM_ERR_BAD_PARAM;
*interp = (int) tmp;
return OSHMEM_SUCCESS;
}
static int oshmem_info_get_heap_size(char *value, size_t *interp)
{
char *p;
long long factor = 1;
int idx;
long long size = 0;
p = value;
*interp = 0;
if (!p) {
return OSHMEM_ERR_BAD_PARAM;
}
/* Sanity check for buffer overflow attack (coverity issue: Use of untrusted string value) */
if (16 < strlen(p)) {
return OSHMEM_ERR_BAD_PARAM;
}
if (1 == sscanf(p, "%lld%n", &size, &idx)) {
if (p[idx] != '\0') {
if (p[idx + 1] == '\0') {
if (p[idx] == 'k' || p[idx] == 'K') {
factor = 1024;
} else if (p[idx] == 'm' || p[idx] == 'M') {
factor = 1024 * 1024;
} else if (p[idx] == 'g' || p[idx] == 'G') {
factor = 1024 * 1024 * 1024;
} else if (p[idx] == 't' || p[idx] == 'T') {
factor = 1024UL * 1024UL * 1024UL * 1024UL;
} else {
size = 0;
}
} else {
size = 0;
}
}
}
if (size <= 0) {
return OSHMEM_ERR_BAD_PARAM;
} else {
opal_setenv(OSHMEM_ENV_SYMMETRIC_SIZE, p, true, &environ);
opal_setenv(SHMEM_HEAP_SIZE, p, true, &environ);
/* Probably needless code */
#if 0
char *tmp = p;
if(!p) {
asprintf(&tmp, "%lld", size * factor);
}
if (tmp) {
opal_setenv(OSHMEM_ENV_SYMMETRIC_SIZE, p, true, &environ);
opal_setenv(SHMEM_HEAP_SIZE, p, true, &environ);
}
if (!p && tmp) {
free(tmp);
}
#endif
}
*interp = size * factor;
return OSHMEM_SUCCESS;
}
static int oshmem_info_get_library_version(char *version, int *resultlen)
{
int len_left;
char *ptr, tmp[OSHMEM_MAX_LIBRARY_VERSION_STRING];
ptr = tmp;
len_left = sizeof(tmp);
memset(tmp, 0, OSHMEM_MAX_LIBRARY_VERSION_STRING);
snprintf(tmp, OSHMEM_MAX_LIBRARY_VERSION_STRING, "Open SHMEM v%d.%d.%d",
OSHMEM_MAJOR_VERSION, OSHMEM_MINOR_VERSION, OSHMEM_RELEASE_VERSION);
ptr += strlen(tmp);
len_left -= strlen(tmp);
if (strlen(OSHMEM_GREEK_VERSION) > 0) {
snprintf(ptr, len_left, "%s", OSHMEM_GREEK_VERSION);
ptr = tmp + strlen(tmp);
len_left = OSHMEM_MAX_LIBRARY_VERSION_STRING - strlen(tmp);
}
/* Package name */
if (strlen(OPAL_PACKAGE_STRING) > 0) {
snprintf(ptr, len_left, ", package: %s", OPAL_PACKAGE_STRING);
ptr = tmp + strlen(tmp);
len_left = OSHMEM_MAX_LIBRARY_VERSION_STRING - strlen(tmp);
}
/* Ident string */
if (strlen(OSHMEM_IDENT_STRING) > 0) {
snprintf(ptr, len_left, ", ident: %s", OSHMEM_IDENT_STRING);
ptr = tmp + strlen(tmp);
len_left = OSHMEM_MAX_LIBRARY_VERSION_STRING - strlen(tmp);
}
/* Repository revision */
if (strlen(OSHMEM_REPO_REV) > 0) {
snprintf(ptr, len_left, ", repo rev: %s", OSHMEM_REPO_REV);
ptr = tmp + strlen(tmp);
len_left = OSHMEM_MAX_LIBRARY_VERSION_STRING - strlen(tmp);
}
/* Release date */
if (strlen(OSHMEM_RELEASE_DATE) > 0) {
snprintf(ptr, len_left, ", %s", OSHMEM_RELEASE_DATE);
ptr = tmp + strlen(tmp);
len_left = OSHMEM_MAX_LIBRARY_VERSION_STRING - strlen(tmp);
}
memcpy(version, tmp, strlen(tmp) + 1);
*resultlen = strlen(tmp) + 1;
return OSHMEM_SUCCESS;
}