Skip to content

Commit

Permalink
token: sort paths for reproducible extract
Browse files Browse the repository at this point in the history
There is no defined order in which readdir will return the entries
of a directory. In practice, order can depend on inode number or
similar. If we run p11-kit on different files systems with similar
directory structure but different inode order the output of extract
can change.

To get a stable and reproducible output, sort the paths returned by
readdir before extracting.

Co-authored-by: Tom Dohrmann <[email protected]>
Signed-off-by: Paul Meyer <[email protected]>
  • Loading branch information
katexochen and Freax13 committed Aug 28, 2024
1 parent 5332245 commit cd1202f
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions trust/token.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,23 @@ loader_load_if_file (p11_token *token,
return 0;
}

static int
compar_strings (const void *one,
const void *two)
{
char **p1 = (char **)one;
char **p2 = (char **)two;
return strcmp (*p1, *p2);
}


static int
loader_load_directory (p11_token *token,
const char *directory,
p11_dict *present)
{
p11_dictiter iter;
p11_array *paths;
struct dirent *dp;
char *path;
int total = 0;
Expand All @@ -272,11 +283,25 @@ loader_load_directory (p11_token *token,
return 0;
}

paths = p11_array_new (NULL);

while ((dp = readdir (dir)) != NULL) {
path = p11_path_build (directory, dp->d_name, NULL);
return_val_if_fail (path != NULL, -1);

ret = loader_load_if_file (token, path);
if (!p11_array_push (paths, path)) {
free (path);
return -1;
}
}

closedir(dir);

qsort(paths->elem, paths->num, sizeof(char *), compar_strings);

for (int i = 0; i < paths->num; i++) {
path = paths->elem[i];
ret = loader_load_if_file(token, path);
if (ret >= 0) {
if (ret <= INT_MAX - total) {
total += ret;
Expand All @@ -291,7 +316,7 @@ loader_load_directory (p11_token *token,
free (path);
}

closedir (dir);
p11_array_free (paths);

/* All other files that were present, not here now */
p11_dict_iterate (present, &iter);
Expand Down

0 comments on commit cd1202f

Please sign in to comment.