Skip to content

Commit 1f9f627

Browse files
hidmicahcorde
authored andcommitted
Cleanup rcl_get_secure_root() implementation. (#762)
* Do not assume allocation will succeed. * Do not leak allocated memory on failure. Signed-off-by: Michel Hidalgo <[email protected]>
1 parent e79b900 commit 1f9f627

File tree

1 file changed

+54
-47
lines changed

1 file changed

+54
-47
lines changed

rcl/src/rcl/security.c

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -128,52 +128,58 @@ char * exact_match_lookup(
128128
return secure_root;
129129
}
130130

131+
static const char *
132+
dupenv(const char * name, const rcl_allocator_t * allocator, char ** value)
133+
{
134+
const char * buffer = NULL;
135+
const char * error = rcutils_get_env(name, &buffer);
136+
if (NULL != error) {
137+
return error;
138+
}
139+
*value = NULL;
140+
if (0 != strcmp("", buffer)) {
141+
*value = rcutils_strdup(buffer, *allocator);
142+
if (NULL == *value) {
143+
return "string duplication failed";
144+
}
145+
}
146+
return NULL;
147+
}
148+
131149
char * rcl_get_secure_root(
132150
const char * name,
133151
const rcl_allocator_t * allocator)
134152
{
135-
bool ros_secure_enclave_override = true;
153+
RCL_CHECK_ARGUMENT_FOR_NULL(name, NULL);
154+
RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "allocator is invalid", return NULL);
136155

137-
// find out if either of the configuration environment variables are set
138-
const char * env_buf = NULL;
139-
if (NULL == name) {
140-
return NULL;
141-
}
142-
const char * get_env_error_str = NULL;
143-
// check if enclave override environment variable is empty
144-
get_env_error_str = rcutils_get_env(ROS_SECURITY_ENCLAVE_OVERRIDE, &env_buf);
145-
if (NULL != get_env_error_str) {
146-
RCUTILS_LOG_ERROR("rcutils_get_env failed: %s\n", get_env_error_str);
147-
return NULL;
148-
}
149-
if (!env_buf) {
150-
return NULL;
151-
}
152-
if (0 == strcmp("", env_buf)) {
153-
ros_secure_enclave_override = false;
154-
}
155-
char * ros_secure_enclave_override_env = rcutils_strdup(env_buf, *allocator);
156+
char * secure_root = NULL;
157+
char * ros_secure_keystore_env = NULL;
158+
char * ros_secure_enclave_override_env = NULL;
156159

157-
// check if keystore environment variable is empty
158-
get_env_error_str = rcutils_get_env(ROS_SECURITY_KEYSTORE_VAR_NAME, &env_buf);
159-
if (NULL != get_env_error_str) {
160-
RCUTILS_LOG_ERROR("rcutils_get_env failed: %s\n", get_env_error_str);
161-
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
162-
return NULL;
163-
}
164-
if (!env_buf) {
165-
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
160+
// check keystore environment variable
161+
const char * error =
162+
dupenv(ROS_SECURITY_KEYSTORE_VAR_NAME, allocator, &ros_secure_keystore_env);
163+
if (NULL != error) {
164+
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
165+
"failed to get %s: %s", ROS_SECURITY_KEYSTORE_VAR_NAME, error);
166166
return NULL;
167167
}
168-
if (0 == strcmp("", env_buf)) {
169-
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
168+
169+
if (NULL == ros_secure_keystore_env) {
170170
return NULL; // environment variable was empty
171171
}
172-
char * ros_secure_keystore_env = rcutils_strdup(env_buf, *allocator);
172+
173+
// check enclave override environment variable
174+
error = dupenv(ROS_SECURITY_ENCLAVE_OVERRIDE, allocator, &ros_secure_enclave_override_env);
175+
if (NULL != error) {
176+
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
177+
"failed to get %s: %s", ROS_SECURITY_ENCLAVE_OVERRIDE, error);
178+
goto leave_rcl_get_secure_root;
179+
}
173180

174181
// given usable environment variables, overwrite with next lookup
175-
char * secure_root = NULL;
176-
if (ros_secure_enclave_override) {
182+
if (NULL != ros_secure_enclave_override_env) {
177183
secure_root = exact_match_lookup(
178184
ros_secure_enclave_override_env,
179185
ros_secure_keystore_env,
@@ -185,21 +191,22 @@ char * rcl_get_secure_root(
185191
allocator);
186192
}
187193

188-
if (NULL == secure_root || !rcutils_is_directory(secure_root)) {
189-
// Check secure_root is not NULL before checking directory
190-
if (NULL == secure_root) {
191-
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
192-
"SECURITY ERROR: unable to find a folder matching the name '%s' in '%s'. ",
193-
name, ros_secure_keystore_env);
194-
} else {
195-
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
196-
"SECURITY ERROR: directory '%s' does not exist.", secure_root);
197-
}
198-
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
199-
allocator->deallocate(ros_secure_keystore_env, allocator->state);
194+
if (NULL == secure_root) {
195+
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
196+
"SECURITY ERROR: unable to find a folder matching the name '%s' in '%s'. ",
197+
name, ros_secure_keystore_env);
198+
goto leave_rcl_get_secure_root;
199+
}
200+
201+
if (!rcutils_is_directory(secure_root)) {
202+
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
203+
"SECURITY ERROR: directory '%s' does not exist.", secure_root);
200204
allocator->deallocate(secure_root, allocator->state);
201-
return NULL;
205+
secure_root = NULL;
202206
}
207+
208+
leave_rcl_get_secure_root:
209+
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
203210
allocator->deallocate(ros_secure_keystore_env, allocator->state);
204211
return secure_root;
205212
}

0 commit comments

Comments
 (0)