Once rpki-client finished validating everything rpki moves valid files
into the validated cache. For RRDP invalid files currently in the valid
cache are moved back into the corresponding .rrdp directory. The problem
here is that in the .rrdp a same file exists we override the newer invalid
file with an older invalid file and put .rrdp into a state it can't
recover until that bad file is referenced in a delta update (at which
point rpki-client realizes that the RRDP state is corrupt and a snapshot
is refetched).
To fix this the older file should not be moved over a file in .rrdp if it
exists. The following diff does this check.
--
:wq Claudio
Index: repo.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/repo.c,v
retrieving revision 1.35
diff -u -p -r1.35 repo.c
--- repo.c 17 Jul 2022 10:32:45 -0000 1.35
+++ repo.c 30 Aug 2022 09:41:40 -0000
@@ -1396,12 +1396,24 @@ repo_cleanup(struct filepath_tree *tree,
}
rr = repo_is_rrdp(e->fts_parent->fts_pointer);
if (rr != NULL) {
+ struct stat st;
char *fn;
if (asprintf(&fn, "%s/%s", rr->basedir,
path) == -1)
err(1, NULL);
+ /*
+ * If the file exists in the rrdp dir
+ * that file is newer and needs to be kept
+ * so unlink this file instead of moving
+ * it over the file in the rrdp dir.
+ */
+ if (fstatat(cachefd, fn, &st, 0) == 0 &&
+ S_ISREG(st.st_mode)) {
+ free(fn);
+ goto unlink;
+ }
if (repo_mkpath(cachefd, fn) == 0) {
if (renameat(AT_FDCWD, e->fts_accpath,
cachefd, fn) == -1)
@@ -1413,6 +1425,7 @@ repo_cleanup(struct filepath_tree *tree,
}
free(fn);
} else {
+ unlink:
if (unlink(e->fts_accpath) == -1) {
warn("unlink %s", path);
} else {