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 {
> 

Reply via email to