Fix: utils: avoid strncpy overlap in utils_partial_realpath
[lttng-tools.git] / src / common / utils.c
index 17a313ee16f66efe8c574ddfddc8f94f156b9e11..f93a4f9d21da5078ccddf0e754e650ce886f9325 100644 (file)
  * but the /tmp/test1 does, the real path for /tmp/test1 is concatened with
  * /test2/test3 then returned. In normal time, realpath(3) fails if the end
  * point directory does not exist.
- * In case resolved_path is NULL, the string returned was allocated in the
- * function and thus need to be freed by the caller. The size argument allows
- * to specify the size of the resolved_path argument if given, or the size to
- * allocate.
+ *
+ * Return a newly-allocated string.
  */
-LTTNG_HIDDEN
-char *utils_partial_realpath(const char *path, char *resolved_path, size_t size)
+static
+char *utils_partial_realpath(const char *path)
 {
        char *cut_path = NULL, *try_path = NULL, *try_path_prev = NULL;
        const char *next, *prev, *end;
+       char *resolved_path = NULL;
 
        /* Safety net */
        if (path == NULL) {
@@ -156,13 +155,11 @@ char *utils_partial_realpath(const char *path, char *resolved_path, size_t size)
                cut_path = NULL;
        }
 
-       /* Allocate memory for the resolved path if necessary */
+       /* Allocate memory for the resolved path. */
+       resolved_path = zmalloc(LTTNG_PATH_MAX);
        if (resolved_path == NULL) {
-               resolved_path = zmalloc(size);
-               if (resolved_path == NULL) {
-                       PERROR("zmalloc resolved path");
-                       goto error;
-               }
+               PERROR("zmalloc resolved path");
+               goto error;
        }
 
        /*
@@ -186,7 +183,8 @@ char *utils_partial_realpath(const char *path, char *resolved_path, size_t size)
                }
 
                /* Concatenate the strings */
-               snprintf(resolved_path, size, "%s%s", try_path_prev, cut_path);
+               snprintf(resolved_path, LTTNG_PATH_MAX, "%s%s",
+                               try_path_prev, cut_path);
 
                /* Free the allocated memory */
                free(cut_path);
@@ -198,7 +196,7 @@ char *utils_partial_realpath(const char *path, char *resolved_path, size_t size)
         * return it as is
         */
        } else {
-               strncpy(resolved_path, path, size);
+               strncpy(resolved_path, path, LTTNG_PATH_MAX);
        }
 
        /* Then we return the 'partially' resolved path */
@@ -300,7 +298,7 @@ int expand_double_slashes_dot_and_dotdot(char *path)
                 * Copy the current token which is neither a '.' nor a '..'.
                 */
                path[expanded_path_len++] = '/';
-               memcpy(&path[expanded_path_len], curr_char, curr_token_len);
+               memmove(&path[expanded_path_len], curr_char, curr_token_len);
                expanded_path_len += curr_token_len;
        }
 
@@ -377,11 +375,13 @@ char *_utils_expand_path(const char *path, bool keep_symlink)
 
        if (keep_symlink) {
                /* Resolve partially our path */
-               absolute_path = utils_partial_realpath(absolute_path,
-                               absolute_path, LTTNG_PATH_MAX);
-               if (!absolute_path) {
+               char *new_absolute_path = utils_partial_realpath(absolute_path);
+               if (!new_absolute_path) {
                        goto error;
                }
+
+               free(absolute_path);
+               absolute_path = new_absolute_path;
        }
 
        ret = expand_double_slashes_dot_and_dotdot(absolute_path);
@@ -547,6 +547,7 @@ void utils_close_pipe(int *src)
                if (ret) {
                        PERROR("close pipe");
                }
+               src[i] = -1;
        }
 }
 
@@ -742,7 +743,8 @@ int utils_stream_file_path(const char *path_name, const char *file_name,
         char count_str[MAX_INT_DEC_LEN(count) + 1] = {};
        const char *path_separator;
 
-       if (path_name && path_name[strlen(path_name) - 1] == '/') {
+       if (path_name && (path_name[0] == '\0' ||
+                       path_name[strlen(path_name) - 1] == '/')) {
                path_separator = "";
        } else {
                path_separator = "/";
@@ -1276,8 +1278,14 @@ int utils_get_group_id(const char *name, bool warn, gid_t *gid)
                }
        }
        if (ret) {
-               PERROR("Failed to get group file entry for group name \"%s\"",
-                               name);
+               if (ret == ESRCH) {
+                       DBG("Could not find group file entry for group name '%s'",
+                                       name);
+               } else {
+                       PERROR("Failed to get group file entry for group name '%s'",
+                                       name);
+               }
+
                ret = -1;
                goto error;
        }
This page took 0.024847 seconds and 4 git commands to generate.