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 <erbse.13@gmx.de>
Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
  • Loading branch information
2 people authored and ZoltanFridrich committed Aug 30, 2024
1 parent e6c6972 commit aedf4d9
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion trust/token.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,28 @@ loader_load_if_file (p11_token *token,
return 0;
}

static int
compar_strings (const void *one,
const void *two)
{
const char **p1 = (const char **)one;
const char **p2 = (const 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;
int ret;
int i;
DIR *dir;

/* First we load all the modules */
Expand All @@ -272,10 +284,22 @@ loader_load_directory (p11_token *token,
return 0;
}

paths = p11_array_new (NULL);
return_val_if_fail (paths != NULL, -1);

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

return_val_if_fail (p11_array_push (paths, path), -1);
}

closedir (dir);

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

for (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) {
Expand All @@ -291,7 +315,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 aedf4d9

Please sign in to comment.