On Tue, Aug 30, 2022 at 12:06:35PM +0200, Claudio Jeker wrote:
> 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.
Good catch.
ok tb
>
> --
> :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 {
>