#16 DO NOT MERGE: Merge upstream changes for Hyperscale
Opened 2 months ago by dcavalca. Modified 2 months ago
rpms/ dcavalca/rpm c8s-sig-hyperscale  into  c8s-sig-hyperscale

file added
+1
@@ -0,0 +1,1 @@ 

+ 3f8c3ef08f93eaeef12008055a43f6872306f8a2 SOURCES/rpm-4.14.3.tar.bz2

@@ -0,0 +1,32 @@ 

+ From 5b21f2f2a12adfd9e1adffc2bf1ad7171ee5d03c Mon Sep 17 00:00:00 2001

+ From: "Vladimir D. Seleznev" <vseleznv@altlinux.org>

+ Date: Tue, 13 Mar 2018 00:04:45 +0300

+ Subject: [PATCH 01/33] Add RPMTAG_AUTOINSTALLED reservation

+ 

+ This tag is needed to track automatically installed packages with rpmdb.

+ Zero value means that a package was installed manually, other values

+ mean that the package was installed automatically as some else package

+ dependency.

+ 

+ This tag is reserved for ALT Linux Team and marked as unimplemented.

+ 

+ Signed-off-by: Vladimir D. Seleznev <vseleznv@altlinux.org>

+ ---

+  lib/rpmtag.h | 1 +

+  1 file changed, 1 insertion(+)

+ 

+ diff --git a/lib/rpmtag.h b/lib/rpmtag.h

+ index 57b10a706..664561156 100644

+ --- a/lib/rpmtag.h

+ +++ b/lib/rpmtag.h

+ @@ -368,6 +368,7 @@ typedef enum rpmTag_e {

+      RPMTAG_FILESIGNATURELENGTH  = 5091, /* i */

+      RPMTAG_PAYLOADDIGEST	= 5092, /* s[] */

+      RPMTAG_PAYLOADDIGESTALGO	= 5093, /* i */

+ +    RPMTAG_AUTOINSTALLED	= 5094, /* i reservation (unimplemented) */

+      RPMTAG_MODULARITYLABEL	= 5096, /* s */

+  

+      RPMTAG_FIRSTFREE_TAG	/*!< internal */

+ -- 

+ 2.27.0

+ 

@@ -0,0 +1,107 @@ 

+ From 186e0ab025b9ad92d900697f611633a6f6162f3b Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Wed, 9 Feb 2022 14:47:14 +0200

+ Subject: [PATCH] Add optional callback on directory changes during rpmfi

+  iteration

+ 

+ Internal only for now in case we need to fiddle with the API some more,

+ but no reason this couldn't be made public later.

+ ---

+  lib/rpmfi.c          | 24 ++++++++++++++++++++----

+  lib/rpmfi_internal.h | 17 +++++++++++++++++

+  2 files changed, 37 insertions(+), 4 deletions(-)

+ 

+ diff --git a/lib/rpmfi.c b/lib/rpmfi.c

+ index aec8220a3..6c631fdb5 100644

+ --- a/lib/rpmfi.c

+ +++ b/lib/rpmfi.c

+ @@ -53,6 +53,9 @@ struct rpmfi_s {

+      int intervalStart;		/*!< Start of iterating interval. */

+      int intervalEnd;		/*!< End of iterating interval. */

+  

+ +    rpmfiChdirCb onChdir;	/*!< Callback for directory changes */

+ +    void *onChdirData;		/*!< Caller private callback data */

+ +

+      rpmfiles files;		/*!< File info set */

+      rpmcpio_t archive;		/*!< Archive with payload */

+      unsigned char * found;	/*!< Bit field of files found in the archive */

+ @@ -298,11 +301,16 @@ rpm_count_t rpmfiDC(rpmfi fi)

+      return (fi != NULL ? rpmfilesDC(fi->files) : 0);

+  }

+  

+ -#ifdef	NOTYET

+ -int rpmfiDI(rpmfi fi)

+ +int rpmfiSetOnChdir(rpmfi fi, rpmfiChdirCb cb, void *data)

+  {

+ +    int rc = -1;

+ +    if (fi != NULL) {

+ +	fi->onChdir = cb;

+ +	fi->onChdirData = data;

+ +	rc = 0;

+ +    }

+ +    return rc;

+  }

+ -#endif

+  

+  int rpmfiFX(rpmfi fi)

+  {

+ @@ -314,9 +322,17 @@ int rpmfiSetFX(rpmfi fi, int fx)

+      int i = -1;

+  

+      if (fi != NULL && fx >= 0 && fx < rpmfilesFC(fi->files)) {

+ +	int dx = fi->j;

+  	i = fi->i;

+  	fi->i = fx;

+  	fi->j = rpmfilesDI(fi->files, fi->i);

+ +	i = fi->i;

+ +

+ +	if (fi->j != dx && fi->onChdir) {

+ +	    int chrc = fi->onChdir(fi, fi->onChdirData);

+ +	    if (chrc < 0)

+ +		i = chrc;

+ +	}

+      }

+      return i;

+  }

+ @@ -1682,9 +1698,9 @@ static rpmfi initIter(rpmfiles files, int itype, int link)

+      if (files && itype>=0 && itype<=RPMFILEITERMAX) {

+  	fi = xcalloc(1, sizeof(*fi)); 

+  	fi->i = -1;

+ +	fi->j = -1;

+  	fi->files = link ? rpmfilesLink(files) : files;

+  	fi->next = nextfuncs[itype];

+ -	fi->i = -1;

+  	if (itype == RPMFI_ITER_BACK) {

+  	    fi->i = rpmfilesFC(fi->files);

+  	} else if (itype >=RPMFI_ITER_READ_ARCHIVE

+ diff --git a/lib/rpmfi_internal.h b/lib/rpmfi_internal.h

+ index dccc6ccbe..37f1d45f5 100644

+ --- a/lib/rpmfi_internal.h

+ +++ b/lib/rpmfi_internal.h

+ @@ -13,6 +13,23 @@

+  extern "C" {

+  #endif

+  

+ +/** \ingroup rpmfi

+ + * Callback on file iterator directory changes

+ + * @param fi		file info

+ + * @param data		caller private callback data

+ + * @return		0 on success, < 0 on error (to stop iteration)

+ + */

+ +typedef int (*rpmfiChdirCb)(rpmfi fi, void *data);

+ +

+ +/** \ingroup rpmfi

+ + * Set a callback for directory changes during iteration.

+ + * @param fi		file info

+ + * @param cb		callback function

+ + * @param data		caller private callback data

+ + * @return		string pool handle (weak reference)

+ + */

+ +int rpmfiSetOnChdir(rpmfi fi, rpmfiChdirCb cb, void *data);

+ +

+  /** \ingroup rpmfi

+   * Return file info set string pool handle

+   * @param fi		file info

+ -- 

+ 2.41.0

+ 

@@ -0,0 +1,30 @@ 

+ From 6c66abd34cccbb5b3c063f8f613e0c2faffc415f Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Wed, 13 Dec 2023 11:57:50 +0200

+ Subject: [PATCH] Don't warn about missing user/group on skipped files

+ 

+ There's no reason to complain about missing user/group for entities

+ we don't create at all. It's cosmetical only, but "regressed" in the

+ 4.17 fsm robustness rewrite.

+ 

+ Reported in https://issues.redhat.com/browse/RHEL-18037

+ ---

+  lib/fsm.c | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/lib/fsm.c b/lib/fsm.c

+ index 2189bd84c..a54e43bae 100644

+ --- a/lib/fsm.c

+ +++ b/lib/fsm.c

+ @@ -903,7 +903,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,

+  	fp->fpath = fsmFsPath(fi, fp->suffix);

+  

+  	/* Remap file perms, owner, and group. */

+ -	rc = rpmfiStat(fi, 1, &fp->sb);

+ +	rc = rpmfiStat(fi, (fp->skip == 0), &fp->sb);

+  

+  	/* Hardlinks are tricky and handled elsewhere for install */

+  	fp->setmeta = (fp->skip == 0) &&

+ -- 

+ 2.43.0

+ 

@@ -0,0 +1,35 @@ 

+ From 0bc13d75b5883ccf4d6579f7a60fb1badd104649 Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Thu, 10 Feb 2022 10:23:22 +0200

+ Subject: [PATCH] Eliminate code duplication from rpmfiNext()

+ 

+ Now that we can, let rpmfiSetFX() take care of the details.

+ ---

+  lib/rpmfi.c | 11 ++---------

+  1 file changed, 2 insertions(+), 9 deletions(-)

+ 

+ diff --git a/lib/rpmfi.c b/lib/rpmfi.c

+ index 689ead2c5..aec8220a3 100644

+ --- a/lib/rpmfi.c

+ +++ b/lib/rpmfi.c

+ @@ -856,15 +856,8 @@ int rpmfiNext(rpmfi fi)

+  	    next = fi->next(fi);

+  	} while (next == RPMERR_ITER_SKIP);

+  

+ -	if (next >= 0 && next < rpmfilesFC(fi->files)) {

+ -	    fi->i = next;

+ -	    fi->j = rpmfilesDI(fi->files, fi->i);

+ -	} else {

+ -	    fi->i = -1;

+ -	    if (next >= 0) {

+ -		next = -1;

+ -	    }

+ -	}

+ +	if (next >= 0)

+ +	    next = rpmfiSetFX(fi, next);

+      }

+      return next;

+  }

+ -- 

+ 2.41.0

+ 

@@ -0,0 +1,66 @@ 

+ From c140768202e271b60910644c1e4bf848a50218d3 Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Mon, 27 Nov 2023 11:52:34 +0200

+ Subject: [PATCH] Emit full paths for file disposition diagnostics on

+  --fsmdebug

+ 

+ The full path is visible in the actual file operations later, but the

+ pre-flight disposition diagnostics is unreadable without the full path.

+ This regressed in the switch to relative paths for the *at() API family

+ for the symlink CVE fixes.

+ ---

+  lib/fsm.c | 12 ++++++------

+  1 file changed, 6 insertions(+), 6 deletions(-)

+ 

+ diff --git a/lib/fsm.c b/lib/fsm.c

+ index 091e90554..fcd764648 100644

+ --- a/lib/fsm.c

+ +++ b/lib/fsm.c

+ @@ -482,14 +482,14 @@ static void removeSBITS(int dirfd, const char *path)

+      }

+  }

+  

+ -static void fsmDebug(const char *fpath, rpmFileAction action,

+ +static void fsmDebug(const char *dn, const char *fpath, rpmFileAction action,

+  		     const struct stat *st)

+  {

+ -    rpmlog(RPMLOG_DEBUG, "%-10s %06o%3d (%4d,%4d)%6d %s\n",

+ +    rpmlog(RPMLOG_DEBUG, "%-10s %06o%3d (%4d,%4d)%6d %s%s\n",

+  	   fileActionString(action), (int)st->st_mode,

+  	   (int)st->st_nlink, (int)st->st_uid,

+  	   (int)st->st_gid, (int)st->st_size,

+ -	    (fpath ? fpath : ""));

+ +	    (dn ? dn : ""), (fpath ? fpath : ""));

+  }

+  

+  static int fsmSymlink(const char *opath, int dirfd, const char *path)

+ @@ -910,7 +910,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,

+  		      (fp->sb.st_nlink == 1 || fp->action == FA_TOUCH);

+  

+  	setFileState(fs, fx);

+ -	fsmDebug(fp->fpath, fp->action, &fp->sb);

+ +	fsmDebug(rpmfiDN(fi), fp->fpath, fp->action, &fp->sb);

+  

+  	fp->stage = FILE_PRE;

+      }

+ @@ -975,7 +975,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,

+  		rpmlog(RPMLOG_DEBUG, "file %s vanished unexpectedly\n",

+  			fp->fpath);

+  		fp->action = FA_CREATE;

+ -		fsmDebug(fp->fpath, fp->action, &fp->sb);

+ +		fsmDebug(rpmfiDN(fi), fp->fpath, fp->action, &fp->sb);

+  	    }

+  

+  	    /* When touching we don't need any of this... */

+ @@ -1138,7 +1138,7 @@ int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfiles files,

+  

+  	rc = fsmStat(di.dirfd, fp->fpath, 1, &fp->sb);

+  

+ -	fsmDebug(fp->fpath, fp->action, &fp->sb);

+ +	fsmDebug(rpmfiDN(fi), fp->fpath, fp->action, &fp->sb);

+  

+  	/* Run fsm file pre hook for all plugins */

+  	rc = rpmpluginsCallFsmFilePre(plugins, fi, fp->fpath,

+ -- 

+ 2.43.0

+ 

@@ -0,0 +1,46 @@ 

+ From 89ce4e7ca592f5abafc3f25aeaa07d36a7b43a61 Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Tue, 14 Nov 2023 11:37:48 +0200

+ Subject: [PATCH] Fix wrong return code on O_DIRECTORY open of invalid symlink

+ 

+ The dir argument to fsmOpenpath() is supposed to be a rough O_DIRECTORY

+ equivalent, and if the path is actually a misowned symlink it should

+ return ENOTDIR instead of ELOOP. Makes the resulting error messages

+ at least a little more comprehensible.

+ ---

+  lib/fsm.c | 5 +++--

+  1 file changed, 3 insertions(+), 2 deletions(-)

+ 

+ diff --git a/lib/fsm.c b/lib/fsm.c

+ index 51f439ef3..091e90554 100644

+ --- a/lib/fsm.c

+ +++ b/lib/fsm.c

+ @@ -304,6 +304,7 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)

+      struct stat lsb, sb;

+      int sflags = flags | O_NOFOLLOW;

+      int fd = openat(dirfd, path, sflags);

+ +    int ffd = fd;

+  

+      /*

+       * Only ever follow symlinks by root or target owner. Since we can't

+ @@ -312,7 +313,7 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)

+       * it could've only been the link owner or root.

+       */

+      if (fd < 0 && errno == ELOOP && flags != sflags) {

+ -	int ffd = openat(dirfd, path, flags);

+ +	ffd = openat(dirfd, path, flags);

+  	if (ffd >= 0) {

+  	    if (fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) {

+  		if (fstat(ffd, &sb) == 0) {

+ @@ -327,7 +328,7 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)

+      }

+  

+      /* O_DIRECTORY equivalent */

+ -    if (dir && fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode)) {

+ +    if (dir && ((fd != ffd) || (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode)))) {

+  	errno = ENOTDIR;

+  	fsmClose(&fd);

+      }

+ -- 

+ 2.43.0

+ 

@@ -0,0 +1,153 @@ 

+ From ac7b0dbd5a18d2c57a942ca14ac856b8047425ff Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Tue, 15 Feb 2022 10:43:13 +0200

+ Subject: [PATCH] Pass file descriptor to file prepare plugin hook, use when

+  possible

+ 

+ Sadly the thing that allegedly makes things better mostly just makes

+ things more complicated as symlinks can't be opened, so we'll now have

+ to deal with both cases in plugins too. To make matters worse, most

+ APIs out there support either an fd or a path, but very few support

+ the *at() style dirfd + basename approach so plugins are stuck with

+ absolute paths for now.

+ 

+ This is of course a plugin API/ABI change too.

+ ---

+  lib/rpmplugin.h   |  2 +-

+  lib/rpmplugins.c  |  4 ++--

+  lib/rpmplugins.h  |  3 ++-

+  plugins/ima.c     |  9 +++++++--

+  plugins/selinux.c | 13 ++++++++-----

+  5 files changed, 20 insertions(+), 11 deletions(-)

+ 

+ diff --git a/lib/rpmplugin.h b/lib/rpmplugin.h

+ index fd81aec8d..fab4b3e83 100644

+ --- a/lib/rpmplugin.h

+ +++ b/lib/rpmplugin.h

+ @@ -57,7 +57,7 @@ typedef rpmRC (*plugin_fsm_file_post_func)(rpmPlugin plugin, rpmfi fi,

+  					   const char* path, mode_t file_mode,

+  					   rpmFsmOp op, int res);

+  typedef rpmRC (*plugin_fsm_file_prepare_func)(rpmPlugin plugin, rpmfi fi,

+ -					      const char* path,

+ +					      int fd, const char* path,

+  					      const char *dest,

+  					      mode_t file_mode, rpmFsmOp op);

+  

+ diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c

+ index 65e684e84..923084b78 100644

+ --- a/lib/rpmplugins.c

+ +++ b/lib/rpmplugins.c

+ @@ -384,7 +384,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char *path,

+  }

+  

+  rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,

+ -				   const char *path, const char *dest,

+ +				   int fd, const char *path, const char *dest,

+  				   mode_t file_mode, rpmFsmOp op)

+  {

+      plugin_fsm_file_prepare_func hookFunc;

+ @@ -394,7 +394,7 @@ rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,

+      for (i = 0; i < plugins->count; i++) {

+  	rpmPlugin plugin = plugins->plugins[i];

+  	RPMPLUGINS_SET_HOOK_FUNC(fsm_file_prepare);

+ -	if (hookFunc && hookFunc(plugin, fi, path, dest, file_mode, op) == RPMRC_FAIL) {

+ +	if (hookFunc && hookFunc(plugin, fi, fd, path, dest, file_mode, op) == RPMRC_FAIL) {

+  	    rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_prepare failed\n", plugin->name);

+  	    rc = RPMRC_FAIL;

+  	}

+ diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h

+ index 39762c376..ddf5d7048 100644

+ --- a/lib/rpmplugins.h

+ +++ b/lib/rpmplugins.h

+ @@ -156,6 +156,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char* path,

+   * permissions etc, but before committing file to destination path.

+   * @param plugins	plugins structure

+   * @param fi		file info iterator (or NULL)

+ + * @param fd		file descriptor (or -1 if not available)

+   * @param path		file object current path

+   * @param dest		file object destination path

+   * @param mode		file object mode

+ @@ -164,7 +165,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char* path,

+   */

+  RPM_GNUC_INTERNAL

+  rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,

+ -                                   const char *path, const char *dest,

+ +                                   int fd, const char *path, const char *dest,

+                                     mode_t mode, rpmFsmOp op);

+  

+  #ifdef __cplusplus

+ diff --git a/plugins/fapolicyd.c b/plugins/fapolicyd.c

+ index 7ac44f0d0..1ff50c30f 100644

+ --- a/plugins/fapolicyd.c

+ +++ b/plugins/fapolicyd.c

+ @@ -145,7 +145,8 @@ static rpmRC fapolicyd_scriptlet_pre(rpmPlugin plugin, const char *s_name,

+  }

+  

+  static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,

+ -                                        const char *path, const char *dest,

+ +                                        int fd, const char *path,

+ +					const char *dest,

+                                          mode_t file_mode, rpmFsmOp op)

+  {

+      /* not ready  */

+ --- a/plugins/ima.c	2020-04-28 14:50:11.835399269 +0200

+ +++ b/plugins/ima.c	2023-12-13 11:19:58.835948660 +0100

+ @@ -39,7 +39,7 @@

+  	return (memcmp(fsig, &zero_hdr, sizeof(zero_hdr)) == 0);

+  }

+  

+ -static rpmRC ima_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,

+ +static rpmRC ima_fsm_file_prepare(rpmPlugin plugin, rpmfi fi, int fd,

+                                    const char *path,

+                                    const char *dest,

+                                    mode_t file_mode, rpmFsmOp op)

+ @@ -63,8 +63,14 @@

+  

+  	fsig = rpmfiFSignature(fi, &len);

+  	if (fsig && (check_zero_hdr(fsig, len) == 0)) {

+ -	    if (lsetxattr(path, XATTR_NAME_IMA, fsig, len, 0) < 0) {

+ -	        rpmlog(RPMLOG_ERR,

+ +	    int xx;

+ +	    if (fd >= 0)

+ +		xx = fsetxattr(fd, XATTR_NAME_IMA, fsig, len, 0);

+ +	    else

+ +		xx = lsetxattr(path, XATTR_NAME_IMA, fsig, len, 0);

+ +	    if (xx < 0) {

+ +		int is_err = errno != EOPNOTSUPP;

+ + 	        rpmlog(is_err?RPMLOG_ERR:RPMLOG_DEBUG,

+  			"ima: could not apply signature on '%s': %s\n",

+  			path, strerror(errno));

+  	        rc = RPMRC_FAIL;

+ --- a/plugins/selinux.c	2023-12-13 11:21:54.935009141 +0100

+ +++ b/plugins/selinux.c	2023-12-13 11:22:23.172510285 +0100

+ @@ -149,7 +149,7 @@

+      return rc;

+  }

+  

+ -static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,

+ +static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi, int fd,

+  					const char *path, const char *dest,

+  				        mode_t file_mode, rpmFsmOp op)

+  {

+ @@ -159,14 +159,17 @@

+      if (sehandle && !XFA_SKIPPING(action)) {

+  	security_context_t scon = NULL;

+  	if (selabel_lookup_raw(sehandle, &scon, dest, file_mode) == 0) {

+ -	    int conrc = lsetfilecon(path, scon);

+ +	    int conrc;

+ +	    if (fd >= 0)

+ +		conrc = fsetfilecon(fd, scon);

+ +	    else

+ +		conrc = lsetfilecon(path, scon);

+  

+  	    if (conrc == 0 || (conrc < 0 && errno == EOPNOTSUPP))

+  		rc = RPMRC_OK;

+  

+ -	    rpmlog((rc != RPMRC_OK) ? RPMLOG_ERR : RPMLOG_DEBUG,

+ -		   "lsetfilecon: (%s, %s) %s\n",

+ -		   path, scon, (conrc < 0 ? strerror(errno) : ""));

+ +	    rpmlog((rc != RPMRC_OK) ? RPMLOG_ERR : RPMLOG_DEBUG, "lsetfilecon: (%d %s, %s) %s\n",

+ +		       fd, path, scon, (conrc < 0 ? strerror(errno) : ""));

+  

+  	    freecon(scon);

+  	} else {

@@ -0,0 +1,32 @@ 

+ From f1503ab6e898430b80017c0f8347860f3a74d5bb Mon Sep 17 00:00:00 2001

+ From: Florian Festi <ffesti@redhat.com>

+ Date: Mon, 11 Dec 2023 15:50:15 +0100

+ Subject: [PATCH] Print full path if file removal fails

+ 

+ For normal debug output the basename of the files are sufficient as when

+ debugging is enabled the directories are also printed. But here the

+ warning is given without a debug flag so we need the full context right

+ there.

+ ---

+  lib/fsm.c | 4 ++--

+  1 file changed, 2 insertions(+), 2 deletions(-)

+ 

+ diff --git a/lib/fsm.c b/lib/fsm.c

+ index fcd764648..2189bd84c 100644

+ --- a/lib/fsm.c

+ +++ b/lib/fsm.c

+ @@ -1174,9 +1174,9 @@ int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfiles files,

+  

+  	    if (rc) {

+  		int lvl = strict_erasures ? RPMLOG_ERR : RPMLOG_WARNING;

+ -		rpmlog(lvl, _("%s %s: remove failed: %s\n"),

+ +		rpmlog(lvl, _("%s %s%s: remove failed: %s\n"),

+  			S_ISDIR(fp->sb.st_mode) ? _("directory") : _("file"),

+ -			fp->fpath, strerror(errno));

+ +			rpmfiDN(fi), fp->fpath, strerror(errno));

+              }

+          }

+  

+ -- 

+ 2.43.0

+ 

The added file is too large to be shown here, see it at: 0001-RPM-with-Copy-on-Write.patch
@@ -0,0 +1,90 @@ 

+ From 6dd62720fe84f7e2ad902c915b952fc0b29e3dcd Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Tue, 15 Feb 2022 11:34:37 +0200

+ Subject: [PATCH] Swap over to dirfd+basename based operation within the fsm

+ 

+ Within fsm this is just a matter of adjusting error messages to include

+ the directory... if it only wasn't for the plugins requiring absolute

+ paths for outside users. For the plugins, we need to assemble absolute

+ paths as needed, both in ensureDir() and plugin file slots.

+ ---

+  lib/rpmplugins.c | 20 +++++++++++++++++---

+  2 files changed, 36 insertions(+), 14 deletions(-)

+ 

+ diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c

+ index 703368c0d..f06fd7895 100644

+ --- a/lib/rpmplugins.c

+ +++ b/lib/rpmplugins.c

+ @@ -350,21 +350,31 @@ rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int ty

+      return rc;

+  }

+  

+ +static char *abspath(rpmfi fi, const char *path)

+ +{

+ +    if (*path == '/')

+ +	return xstrdup(path);

+ +    else

+ +	return rstrscat(NULL, rpmfiDN(fi), path, NULL);

+ +}

+ +

+  rpmRC rpmpluginsCallFsmFilePre(rpmPlugins plugins, rpmfi fi, const char *path,

+  			       mode_t file_mode, rpmFsmOp op)

+  {

+      plugin_fsm_file_pre_func hookFunc;

+      int i;

+      rpmRC rc = RPMRC_OK;

+ +    char *apath = abspath(fi, path);

+  

+      for (i = 0; i < plugins->count; i++) {

+  	rpmPlugin plugin = plugins->plugins[i];

+  	RPMPLUGINS_SET_HOOK_FUNC(fsm_file_pre);

+ -	if (hookFunc && hookFunc(plugin, fi, path, file_mode, op) == RPMRC_FAIL) {

+ +	if (hookFunc && hookFunc(plugin, fi, apath, file_mode, op) == RPMRC_FAIL) {

+  	    rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_pre failed\n", plugin->name);

+  	    rc = RPMRC_FAIL;

+  	}

+      }

+ +    free(apath);

+  

+      return rc;

+  }

+ @@ -375,14 +385,16 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char *path,

+      plugin_fsm_file_post_func hookFunc;

+      int i;

+      rpmRC rc = RPMRC_OK;

+ +    char *apath = abspath(fi, path);

+  

+      for (i = 0; i < plugins->count; i++) {

+  	rpmPlugin plugin = plugins->plugins[i];

+  	RPMPLUGINS_SET_HOOK_FUNC(fsm_file_post);

+ -	if (hookFunc && hookFunc(plugin, fi, path, file_mode, op, res) == RPMRC_FAIL) {

+ +	if (hookFunc && hookFunc(plugin, fi, apath, file_mode, op, res) == RPMRC_FAIL) {

+  	    rpmlog(RPMLOG_WARNING, "Plugin %s: hook fsm_file_post failed\n", plugin->name);

+  	}

+      }

+ +    free(apath);

+  

+      return rc;

+  }

+ @@ -394,15 +406,17 @@ rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,

+      plugin_fsm_file_prepare_func hookFunc;

+      int i;

+      rpmRC rc = RPMRC_OK;

+ +    char *apath = abspath(fi, path);

+  

+      for (i = 0; i < plugins->count; i++) {

+  	rpmPlugin plugin = plugins->plugins[i];

+  	RPMPLUGINS_SET_HOOK_FUNC(fsm_file_prepare);

+ -	if (hookFunc && hookFunc(plugin, fi, fd, path, dest, file_mode, op) == RPMRC_FAIL) {

+ +	if (hookFunc && hookFunc(plugin, fi, fd, apath, dest, file_mode, op) == RPMRC_FAIL) {

+  	    rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_prepare failed\n", plugin->name);

+  	    rc = RPMRC_FAIL;

+  	}

+      }

+ +    free(apath);

+  

+      return rc;

+  }

+ -- 

+ 2.41.0

+ 

The added file is too large to be shown here, see it at: 0001-Use-file-state-machine-from-rpm-4.19.patch
@@ -0,0 +1,34 @@ 

+ From a74ea72cb47dcdc1006ffbdd23643964bd40f580 Mon Sep 17 00:00:00 2001

+ From: "Vladimir D. Seleznev" <vseleznv@altlinux.org>

+ Date: Tue, 13 Mar 2018 00:04:46 +0300

+ Subject: [PATCH 02/33] Add RPMTAG_IDENTITY reservation

+ 

+ This tag represents binary package build characteristic: if two binary

+ packages have equal RPMTAG_IDENTITY values, it means that these packages

+ have no significant differences.

+ 

+ One of the applications of RPMTAG_IDENTITY is reproducible build

+ verification.

+ 

+ This tag is reserved for ALT Linux Team and marked as unimplemented.

+ 

+ Signed-off-by: Vladimir D. Seleznev <vseleznv@altlinux.org>

+ ---

+  lib/rpmtag.h | 1 +

+  1 file changed, 1 insertion(+)

+ 

+ diff --git a/lib/rpmtag.h b/lib/rpmtag.h

+ index 664561156..002492d20 100644

+ --- a/lib/rpmtag.h

+ +++ b/lib/rpmtag.h

+ @@ -369,6 +369,7 @@ typedef enum rpmTag_e {

+      RPMTAG_PAYLOADDIGEST	= 5092, /* s[] */

+      RPMTAG_PAYLOADDIGESTALGO	= 5093, /* i */

+      RPMTAG_AUTOINSTALLED	= 5094, /* i reservation (unimplemented) */

+ +    RPMTAG_IDENTITY		= 5095, /* s reservation (unimplemented) */

+      RPMTAG_MODULARITYLABEL	= 5096, /* s */

+  

+      RPMTAG_FIRSTFREE_TAG	/*!< internal */

+ -- 

+ 2.27.0

+ 

@@ -0,0 +1,53 @@ 

+ From 845b5c3882b1eecb31d712b61a4e91fe0eb70712 Mon Sep 17 00:00:00 2001

+ From: Matthew Almond <malmond@fb.com>

+ Date: Sun, 31 Jan 2021 12:30:33 -0800

+ Subject: [PATCH 02/30] Remove use of bool type for consistency

+ 

+ ---

+  lib/fsm.c | 9 ++++-----

+  1 file changed, 4 insertions(+), 5 deletions(-)

+ 

+ diff --git a/lib/fsm.c b/lib/fsm.c

+ index 90193c749..feda3750c 100644

+ --- a/lib/fsm.c

+ +++ b/lib/fsm.c

+ @@ -8,7 +8,6 @@

+ 

+  #include <utime.h>

+  #include <errno.h>

+ -#include <stdbool.h>

+  #if WITH_CAP

+  #include <sys/capability.h>

+  #endif

+ @@ -896,10 +895,10 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,

+  

+      Header h = rpmteHeader(te);

+      const char *payloadfmt = headerGetString(h, RPMTAG_PAYLOADFORMAT);

+ -    bool cpio = true;

+ +    int cpio = 1;

+  

+      if (payloadfmt && rstreq(payloadfmt, "clon")) {

+ -	cpio = false;

+ +	cpio = 0;

+      }

+  

+      /* transaction id used for temporary path suffix while installing */

+ @@ -927,13 +926,13 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,

+  	/* Run fsm file pre hook for all plugins */

+  	rc = rpmpluginsCallFsmFilePre(plugins, fi, fp->fpath,

+  				      fp->sb.st_mode, fp->action);

+ -	fp->plugin_contents = false;

+ +	fp->plugin_contents = 0;

+  	switch (rc) {

+  	case RPMRC_OK:

+  	    setFileState(fs, fx);

+  	    break;

+  	case RPMRC_PLUGIN_CONTENTS:

+ -	    fp->plugin_contents = true;

+ +	    fp->plugin_contents = 1;

+  	    // reduce reads on cpio to this value. Could be zero if

+  	    // this is from a hard link.

+  	    rc = RPMRC_OK;

+ -- 

+ 2.35.1

+ 

The added file is too large to be shown here, see it at: 0003-Match-formatting-style-of-existing-code.patch
@@ -0,0 +1,58 @@ 

+ From 492823ca53f5666b82e94fcfdd422bdcd67005cb Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Tue, 10 Oct 2017 11:07:38 +0300

+ Subject: [PATCH 03/33] Use lower-level headerPut() for file signing

+ 

+ Not supposed to affect behavior at all, but we'll need this in the

+ next step.

+ ---

+  sign/rpmsignfiles.c | 19 ++++++++++++++++---

+  1 file changed, 16 insertions(+), 3 deletions(-)

+ 

+ diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c

+ index 61b73bd40..1fc127cb1 100644

+ --- a/sign/rpmsignfiles.c

+ +++ b/sign/rpmsignfiles.c

+ @@ -82,7 +82,7 @@ char *keypass)

+  

+  rpmRC rpmSignFiles(Header h, const char *key, char *keypass)

+  {

+ -    struct rpmtd_s digests;

+ +    struct rpmtd_s digests, td;

+      int algo;

+      int diglen;

+      uint32_t siglen;

+ @@ -110,7 +110,19 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass)

+      headerDel(h, RPMTAG_FILESIGNATURELENGTH);

+      headerDel(h, RPMTAG_FILESIGNATURES);

+      siglen = signatureLength(algoname, diglen, key, keypass);

+ -    headerPutUint32(h, RPMTAG_FILESIGNATURELENGTH, &siglen, 1);

+ +

+ +    rpmtdReset(&td);

+ +    td.tag = RPMTAG_FILESIGNATURELENGTH;

+ +    td.type = RPM_INT32_TYPE;

+ +    td.data = &siglen;

+ +    td.count = 1;

+ +    headerPut(h, &td, HEADERPUT_DEFAULT);

+ +

+ +    rpmtdReset(&td);

+ +    td.tag = RPMTAG_FILESIGNATURES;

+ +    td.type = RPM_STRING_ARRAY_TYPE;

+ +    td.data = NULL; /* set in the loop below */

+ +    td.count = 1;

+  

+      headerGet(h, RPMTAG_FILEDIGESTS, &digests, HEADERGET_MINMEM);

+      while ((digest = rpmtdNextString(&digests))) {

+ @@ -120,7 +132,8 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass)

+  	    rc = RPMRC_FAIL;

+  	    goto exit;

+  	}

+ -	if (!headerPutString(h, RPMTAG_FILESIGNATURES, signature)) {

+ +	td.data = &signature;

+ +	if (!headerPut(h, &td, HEADERPUT_APPEND)) {

+  	    free(signature);

+  	    rpmlog(RPMLOG_ERR, _("headerPutString failed\n"));

+  	    rc = RPMRC_FAIL;

+ -- 

+ 2.27.0

+ 

@@ -0,0 +1,27 @@ 

+ From 15127592f8cc3221129f61b79319d88c7727bec3 Mon Sep 17 00:00:00 2001

+ From: Matthew Almond <malmond@fb.com>

+ Date: Sun, 31 Jan 2021 15:24:25 -0800

+ Subject: [PATCH 04/30] Fix printf formatting in reflink.c

+ 

+ There were some mismatches on field "sizes". This should eliminate the

+ error messages.

+ ---

+  plugins/reflink.c | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/plugins/reflink.c b/plugins/reflink.c

+ index 9eaa87094..513887604 100644

+ --- a/plugins/reflink.c

+ +++ b/plugins/reflink.c

+ @@ -316,7 +316,7 @@ static rpmRC reflink_fsm_file_pre(rpmPlugin plugin, rpmfi fi, const char* path,

+  		return RPMRC_FAIL;

+  	    }

+  	    rpmlog(RPMLOG_DEBUG,

+ -	           _("reflink: Reflinking %lu bytes at %lu to %s orig size=%lu, file=%ld\n"),

+ +	           _("reflink: Reflinking %llu bytes at %llu to %s orig size=%ld, file=%lld\n"),

+  		   fcr.src_length, fcr.src_offset, path, size, fcr.src_fd);

+  	    rc = ioctl(dst, FICLONERANGE, &fcr);

+  	    if (rc) {

+ -- 

+ 2.35.1

+ 

@@ -0,0 +1,329 @@ 

+ From f354c5a4265ddad758ad41abfb2f5fe174a54c69 Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Tue, 10 Oct 2017 11:44:10 +0300

+ Subject: [PATCH 04/33] Place file signatures into the signature header where

+  they belong

+ 

+ The original file signing puts the file signatures into the main header

+ immutable region, invalidating all previous signatures and digests so

+ the package no longer appears to be what it was when it came out of the

+ assembly line. Which is bad. Doing that also requires recalculating

+ everything again which is just added complexity, and since it adds

+ stuff to different place from the rest of the signing, it requires yet

+ complexity to deal with that. Moving the file signatures into the

+ signature header solves all that and allows removing a big pile of

+ now unnecessary code.

+ 

+ Because this means retrofitting tags bass-ackwards into the signature

+ header, the tag definitions are backwards to everything else. Other

+ options would certainly be possible, but this makes things look more

+ normal on the signature header side. "Users" only ever see the

+ unchanged file signature tags as they have always been.

+ 

+ This also means the signature header can be MUCH bigger than ever before,

+ so bump up the limit (to 64MB, arbitrary something for now), and

+ permit string array types to be migrated from the signature header

+ on package read.

+ 

+ Caveats:

+ This loses the check for identical existing signatures to keep the

+ complexity down, it's hardly a critical thing and can be added back later.

+ While file signing could now be done separately to other signing, that

+ is not handled here.

+ ---

+  lib/rpmtag.h        |   4 ++

+  sign/rpmgensig.c    | 161 +++-----------------------------------------

+  sign/rpmsignfiles.c |  14 ++--

+  sign/rpmsignfiles.h |   5 +-

+  4 files changed, 22 insertions(+), 162 deletions(-)

+ 

+ diff --git a/lib/rpmtag.h b/lib/rpmtag.h

+ index 002492d20..46719ec75 100644

+ --- a/lib/rpmtag.h

+ +++ b/lib/rpmtag.h

+ @@ -65,6 +65,8 @@ typedef enum rpmTag_e {

+      RPMTAG_LONGARCHIVESIZE	= RPMTAG_SIG_BASE+15,	/* l */

+      /* RPMTAG_SIG_BASE+16 reserved */

+      RPMTAG_SHA256HEADER		= RPMTAG_SIG_BASE+17,	/* s */

+ +    /* RPMTAG_SIG_BASE+18 reserved for RPMSIGTAG_FILESIGNATURELENGTH */

+ +    /* RPMTAG_SIG_BASE+19 reserved for RPMSIGTAG_FILESIGNATURES */

+  

+      RPMTAG_NAME  		= 1000,	/* s */

+  #define	RPMTAG_N	RPMTAG_NAME	/* s */

+ @@ -425,6 +427,8 @@ typedef enum rpmSigTag_e {

+      RPMSIGTAG_LONGSIZE	= RPMTAG_LONGSIGSIZE,	/*!< internal Header+Payload size (64bit) in bytes. */

+      RPMSIGTAG_LONGARCHIVESIZE = RPMTAG_LONGARCHIVESIZE, /*!< internal uncompressed payload size (64bit) in bytes. */

+      RPMSIGTAG_SHA256	= RPMTAG_SHA256HEADER,

+ +    RPMSIGTAG_FILESIGNATURELENGTH	= RPMTAG_SIG_BASE + 18,

+ +    RPMSIGTAG_FILESIGNATURES		= RPMTAG_SIG_BASE + 19,

+  } rpmSigTag;

+  

+  

+ diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c

+ index 8f77ad9c1..5fddb56ea 100644

+ --- a/sign/rpmgensig.c

+ +++ b/sign/rpmgensig.c

+ @@ -417,74 +417,12 @@ static void unloadImmutableRegion(Header *hdrp, rpmTagVal tag)

+      }

+  }

+  

+ -#ifdef WITH_IMAEVM

+ -static rpmRC replaceSigDigests(FD_t fd, const char *rpm, Header *sigp,

+ -			       off_t sigStart, off_t sigTargetSize,

+ -			       char *SHA256, char *SHA1, uint8_t *MD5)

+ -{

+ -    off_t archiveSize;

+ -    rpmRC rc = RPMRC_OK;

+ -

+ -    if (Fseek(fd, sigStart, SEEK_SET) < 0) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),

+ -		rpm, Fstrerror(fd));

+ -	goto exit;

+ -    }

+ -

+ -    /* Get payload size from signature tag */

+ -    archiveSize = headerGetNumber(*sigp, RPMSIGTAG_PAYLOADSIZE);

+ -    if (!archiveSize) {

+ -	archiveSize = headerGetNumber(*sigp, RPMSIGTAG_LONGARCHIVESIZE);

+ -    }

+ -

+ -    /* Set reserved space to 0 */

+ -    rpmPushMacro(NULL, "__gpg_reserved_space", NULL, 0, RMIL_GLOBAL);

+ -

+ -    /* Replace old digests in sigh */

+ -    rc = rpmGenerateSignature(SHA256, SHA1, MD5, sigTargetSize, archiveSize, fd);

+ -    if (rc != RPMRC_OK) {

+ -	rpmlog(RPMLOG_ERR, _("generateSignature failed\n"));

+ -	goto exit;

+ -    }

+ -

+ -    if (Fseek(fd, sigStart, SEEK_SET) < 0) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),

+ -		rpm, Fstrerror(fd));

+ -	goto exit;

+ -    }

+ -

+ -    headerFree(*sigp);

+ -    rc = rpmReadSignature(fd, sigp, NULL);

+ -    if (rc != RPMRC_OK) {

+ -	rpmlog(RPMLOG_ERR, _("rpmReadSignature failed\n"));

+ -	goto exit;

+ -    }

+ -

+ -exit:

+ -    return rc;

+ -}

+ -#endif

+ -

+ -static rpmRC includeFileSignatures(FD_t fd, const char *rpm,

+ -				   Header *sigp, Header *hdrp,

+ -				   off_t sigStart, off_t headerStart)

+ +static rpmRC includeFileSignatures(Header *sigp, Header *hdrp)

+  {

+  #ifdef WITH_IMAEVM

+ -    FD_t ofd = NULL;

+ -    char *trpm = NULL;

+ +    rpmRC rc;

+      char *key;

+      char *keypass;

+ -    char *SHA1 = NULL;

+ -    char *SHA256 = NULL;

+ -    uint8_t *MD5 = NULL;

+ -    off_t sigTargetSize;

+ -    rpmRC rc = RPMRC_OK;

+ -    struct rpmtd_s osigtd;

+ -    char *o_sha1 = NULL;

+ -

+ -    unloadImmutableRegion(hdrp, RPMTAG_HEADERIMMUTABLE);

+  

+      key = rpmExpand("%{?_file_signing_key}", NULL);

+  

+ @@ -494,94 +432,10 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm,

+  	keypass = NULL;

+      }

+  

+ -    rc = rpmSignFiles(*hdrp, key, keypass);

+ -    if (rc != RPMRC_OK) {

+ -	goto exit;

+ -    }

+ -

+ -    *hdrp = headerReload(*hdrp, RPMTAG_HEADERIMMUTABLE);

+ -    if (*hdrp == NULL) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("headerReload failed\n"));

+ -	goto exit;

+ -    }

+ -

+ -    ofd = rpmMkTempFile(NULL, &trpm);

+ -    if (ofd == NULL || Ferror(ofd)) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));

+ -	goto exit;

+ -    }

+ -

+ -    /* Copy archive to temp file */

+ -    if (copyFile(&fd, rpm, &ofd, trpm)) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("copyFile failed\n"));

+ -	goto exit;

+ -    }

+ -

+ -    if (Fseek(fd, headerStart, SEEK_SET) < 0) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),

+ -		rpm, Fstrerror(fd));

+ -	goto exit;

+ -    }

+ +    rc = rpmSignFiles(*sigp, *hdrp, key, keypass);

+  

+ -    /* Start MD5 calculation */

+ -    fdInitDigestID(fd, PGPHASHALGO_MD5, RPMSIGTAG_MD5, 0);

+ -

+ -    /* Write header to rpm and recalculate digests */

+ -    fdInitDigestID(fd, PGPHASHALGO_SHA1, RPMSIGTAG_SHA1, 0);

+ -    fdInitDigestID(fd, PGPHASHALGO_SHA256, RPMSIGTAG_SHA256, 0);

+ -    rc = headerWrite(fd, *hdrp, HEADER_MAGIC_YES);

+ -    if (rc != RPMRC_OK) {

+ -	rpmlog(RPMLOG_ERR, _("headerWrite failed\n"));

+ -	goto exit;

+ -    }

+ -    fdFiniDigest(fd, RPMSIGTAG_SHA1, (void **)&SHA1, NULL, 1);

+ -    /* Only add SHA256 if it was there to begin with */

+ -    if (headerIsEntry(*sigp, RPMSIGTAG_SHA256))

+ -	fdFiniDigest(fd, RPMSIGTAG_SHA256, (void **)&SHA256, NULL, 1);

+ -

+ -    /* Copy archive from temp file */

+ -    if (Fseek(ofd, 0, SEEK_SET) < 0) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),

+ -		rpm, Fstrerror(fd));

+ -	goto exit;

+ -    }

+ -    if (copyFile(&ofd, trpm, &fd, rpm)) {

+ -	rc = RPMRC_FAIL;

+ -	rpmlog(RPMLOG_ERR, _("copyFile failed\n"));

+ -	goto exit;

+ -    }

+ -    unlink(trpm);

+ -

+ -    sigTargetSize = Ftell(fd) - headerStart;

+ -    fdFiniDigest(fd, RPMSIGTAG_MD5, (void **)&MD5, NULL, 0);

+ -

+ -    if (headerGet(*sigp, RPMSIGTAG_SHA1, &osigtd, HEADERGET_DEFAULT)) {

+ -	o_sha1 = xstrdup(osigtd.data);

+ -	rpmtdFreeData(&osigtd);

+ -    }

+ -

+ -    if (strcmp(SHA1, o_sha1) == 0)

+ -	rpmlog(RPMLOG_WARNING,

+ -	       _("%s already contains identical file signatures\n"),

+ -	       rpm);

+ -    else

+ -	replaceSigDigests(fd, rpm, sigp, sigStart, sigTargetSize, SHA256, SHA1, MD5);

+ -

+ -exit:

+ -    free(trpm);

+ -    free(MD5);

+ -    free(SHA1);

+ -    free(SHA256);

+ -    free(o_sha1);

+      free(keypass);

+      free(key);

+ -    if (ofd)

+ -	(void) closeFile(&ofd);

+      return rc;

+  #else

+      rpmlog(RPMLOG_ERR, _("file signing support not built in\n"));

+ @@ -674,13 +528,14 @@ static int rpmSign(const char *rpm, int deleting, int signfiles)

+  	goto exit;

+      }

+  

+ -    if (signfiles) {

+ -	includeFileSignatures(fd, rpm, &sigh, &h, sigStart, headerStart);

+ -    }

+ -

+      unloadImmutableRegion(&sigh, RPMTAG_HEADERSIGNATURES);

+      origSigSize = headerSizeof(sigh, HEADER_MAGIC_YES);

+  

+ +    if (signfiles) {

+ +	if (includeFileSignatures(&sigh, &h))

+ +	    goto exit;

+ +    }

+ +

+      if (deleting) {	/* Nuke all the signature tags. */

+  	deleteSigs(sigh);

+      } else {

+ diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c

+ index 1fc127cb1..2dcc50400 100644

+ --- a/sign/rpmsignfiles.c

+ +++ b/sign/rpmsignfiles.c

+ @@ -80,7 +80,7 @@ char *keypass)

+      return siglen + 1;

+  }

+  

+ -rpmRC rpmSignFiles(Header h, const char *key, char *keypass)

+ +rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)

+  {

+      struct rpmtd_s digests, td;

+      int algo;

+ @@ -107,19 +107,19 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass)

+  	return RPMRC_FAIL;

+      }

+  

+ -    headerDel(h, RPMTAG_FILESIGNATURELENGTH);

+ -    headerDel(h, RPMTAG_FILESIGNATURES);

+ +    headerDel(sigh, RPMTAG_FILESIGNATURELENGTH);

+ +    headerDel(sigh, RPMTAG_FILESIGNATURES);

+      siglen = signatureLength(algoname, diglen, key, keypass);

+  

+      rpmtdReset(&td);

+ -    td.tag = RPMTAG_FILESIGNATURELENGTH;

+ +    td.tag = RPMSIGTAG_FILESIGNATURELENGTH;

+      td.type = RPM_INT32_TYPE;

+      td.data = &siglen;

+      td.count = 1;

+ -    headerPut(h, &td, HEADERPUT_DEFAULT);

+ +    headerPut(sigh, &td, HEADERPUT_DEFAULT);

+  

+      rpmtdReset(&td);

+ -    td.tag = RPMTAG_FILESIGNATURES;

+ +    td.tag = RPMSIGTAG_FILESIGNATURES;

+      td.type = RPM_STRING_ARRAY_TYPE;

+      td.data = NULL; /* set in the loop below */

+      td.count = 1;

+ @@ -133,7 +133,7 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass)

+  	    goto exit;

+  	}

+  	td.data = &signature;

+ -	if (!headerPut(h, &td, HEADERPUT_APPEND)) {

+ +	if (!headerPut(sigh, &td, HEADERPUT_APPEND)) {

+  	    free(signature);

+  	    rpmlog(RPMLOG_ERR, _("headerPutString failed\n"));

+  	    rc = RPMRC_FAIL;

+ diff --git a/sign/rpmsignfiles.h b/sign/rpmsignfiles.h

+ index 4163fafde..2ff623cdf 100644

+ --- a/sign/rpmsignfiles.h

+ +++ b/sign/rpmsignfiles.h

+ @@ -9,14 +9,15 @@ extern "C" {

+  #endif

+  

+  /**

+ - * Sign file digests in header and store the signatures in header

+ + * Sign file digests in header into signature header

+ + * @param sigh		package signature header

+   * @param h		package header

+   * @param key		signing key

+   * @param keypass	signing key password

+   * @return		RPMRC_OK on success

+   */

+  RPM_GNUC_INTERNAL

+ -rpmRC rpmSignFiles(Header h, const char *key, char *keypass);

+ +rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass);

+  

+  #ifdef _cplusplus

+  }

+ -- 

+ 2.27.0

+ 

@@ -0,0 +1,30 @@ 

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Tue, 10 Oct 2017 14:40:05 +0300

+ Subject: [PATCH 05/33] Unbreak file signing from previous commit

+ From cabecd35ff6842c029103732ca5e5ea7dcdce256 Mon Sep 17 00:00:00 2001

+ 

+ Commit f558e886050c4e98f6cdde391df679a411b3f62c essentially broke

+ file signing because signatures never get migrated into the package

+ header. This is what happens when you play around with too many

+ variants of the same thing and forget to test what ultimately got

+ committed, which was subtly different from anything else so far... :(

+ ---

+  lib/package.c | 2 ++

+  1 file changed, 2 insertions(+)

+ 

+ diff --git a/lib/package.c b/lib/package.c

+ index 211fd3902..b7d996a12 100644

+ --- a/lib/package.c

+ +++ b/lib/package.c

+ @@ -43,6 +43,8 @@ struct taglate_s {

+      { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0, 0 },

+      /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0, 0 }, */ /* long obsolete, dont use */

+      { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1, 1 },

+ +    { RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0, 1 },

+ +    { RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1, 1 },

+      { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 },

+      { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1, 0 },

+      { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0, 0 },

+ -- 

+ 2.27.0

+ 

@@ -0,0 +1,73 @@ 

+ From fd4060dcfbe4127fb0d19f1878d0d8b9f34c7b9a Mon Sep 17 00:00:00 2001

+ From: chantra <chantr4@gmail.com>

+ Date: Fri, 28 Jan 2022 08:33:16 -0800

+ Subject: [PATCH 05/30] [tests][rpm2extents] Add basic tests for rpm2extents

+ 

+ ---

+  tests/Makefile.am    |  1 +

+  tests/rpm2extents.at | 31 +++++++++++++++++++++++++++++++

+  tests/rpmtests.at    |  1 +

+  3 files changed, 33 insertions(+)

+  create mode 100644 tests/rpm2extents.at

+ 

+ diff --git a/tests/Makefile.am b/tests/Makefile.am

+ index f78e17c3e..fc8a24a5e 100644

+ --- a/tests/Makefile.am

+ +++ b/tests/Makefile.am

+ @@ -36,6 +36,7 @@ TESTSUITE_AT += rpmio.at

+  TESTSUITE_AT += rpmio.at

+  TESTSUITE_AT += rpmorder.at

+  TESTSUITE_AT += rpmvfylevel.at

+ +TESTSUITE_AT += rpm2extents.at

+  EXTRA_DIST += $(TESTSUITE_AT)

+  

+  ## testsuite data

+ diff --git a/tests/rpm2extents.at b/tests/rpm2extents.at

+ new file mode 100644

+ index 000000000..f943b9af4

+ --- /dev/null

+ +++ b/tests/rpm2extents.at

+ @@ -0,0 +1,31 @@

+ +#    rpm2extents.at: Some very basic checks

+ +#

+ +#    Copyright (C) 2022  Manu Bretelle <chantr4@gmail.com>

+ +#

+ +#    This program is free software; you can redistribute it and/or modify

+ +#    it under the terms of the GNU General Public License as published by

+ +#    the Free Software Foundation; either version 2 of the License, or

+ +#    (at your option) any later version.

+ +#

+ +#    This program is distributed in the hope that it will be useful,

+ +#    but WITHOUT ANY WARRANTY; without even the implied warranty of

+ +#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ +#    GNU General Public License for more details.

+ +#

+ +#    You should have received a copy of the GNU General Public License

+ +#    along with this program; if not, write to the Free Software

+ +#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

+ +

+ +AT_BANNER([rpm2extents tests])

+ +

+ +# ------------------------------

+ +

+ +# check that transcoder write magic at the end

+ +AT_SETUP([rpm2extents magic])

+ +AT_KEYWORDS([rpm2extents])

+ +AT_CHECK([runroot_other cat /data/RPMS/hello-2.0-1.x86_64.rpm | runroot_other rpm2extents SHA256 | tail -c8],

+ +[0],

+ +[KWTSH100],

+ +[ignore])

+ +AT_CLEANUP

+ +

+ diff --git a/tests/rpmtests.at b/tests/rpmtests.at

+ index a1adab8e0..205fed6a3 100644

+ --- a/tests/rpmtests.at

+ +++ b/tests/rpmtests.at

+ @@ -21,3 +21,4 @@ m4_include([rpmreplace.at])

+  m4_include([rpmmacro.at])

+  m4_include([rpmpython.at])

+  m4_include([rpmdepmatch.at])

+ +m4_include([rpm2extents.at])

+ -- 

+ 2.35.1

+ 

@@ -0,0 +1,71 @@ 

+ From bcdd8505e792fd67c1480d43d987b92a61710e53 Mon Sep 17 00:00:00 2001

+ From: Panu Matilainen <pmatilai@redhat.com>

+ Date: Tue, 10 Oct 2017 14:43:58 +0300

+ Subject: [PATCH 06/33] Assume failure in rpmSignFiles()

+ 

+ Doesn't make it any shorter yet, but makes more sense in the next steps.

+ Just refactoring.

+ ---

+  sign/rpmsignfiles.c | 16 ++++++++--------

+  1 file changed, 8 insertions(+), 8 deletions(-)

+ 

+ diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c

+ index 2dcc50400..c1d227a07 100644

+ --- a/sign/rpmsignfiles.c

+ +++ b/sign/rpmsignfiles.c

+ @@ -88,23 +88,24 @@ rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)

+      uint32_t siglen;

+      const char *algoname;

+      const char *digest;

+ -    char *signature;

+ -    rpmRC rc = RPMRC_OK;

+ +    char *signature = NULL;

+ +    rpmRC rc = RPMRC_FAIL;

+  

+ +    rpmtdReset(&digests);

+      algo = headerGetNumber(h, RPMTAG_FILEDIGESTALGO);

+      if (!algo) {

+          /* use default algorithm */

+          algo = PGPHASHALGO_MD5;

+      } else if (algo < 0 || algo >= ARRAY_SIZE(hash_algo_name)) {

+  	rpmlog(RPMLOG_ERR, _("File digest algorithm id is invalid"));

+ -	return RPMRC_FAIL;

+ +	goto exit;

+      }

+  

+      diglen = rpmDigestLength(algo);

+      algoname = hash_algo_name[algo];

+      if (!algoname) {

+  	rpmlog(RPMLOG_ERR, _("hash_algo_name failed\n"));

+ -	return RPMRC_FAIL;

+ +	goto exit;

+      }

+  

+      headerDel(sigh, RPMTAG_FILESIGNATURELENGTH);

+ @@ -129,20 +130,19 @@ rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)

+  	signature = signFile(algoname, digest, diglen, key, keypass);

+  	if (!signature) {

+  	    rpmlog(RPMLOG_ERR, _("signFile failed\n"));

+ -	    rc = RPMRC_FAIL;

+  	    goto exit;

+  	}

+  	td.data = &signature;

+  	if (!headerPut(sigh, &td, HEADERPUT_APPEND)) {

+ -	    free(signature);

+  	    rpmlog(RPMLOG_ERR, _("headerPutString failed\n"));

+ -	    rc = RPMRC_FAIL;

+  	    goto exit;

+  	}

+ -	free(signature);

+ +	signature = _free(signature);

+      }

+ +    rc = RPMRC_OK;

+  

+  exit:

+ +    free(signature);

+      rpmtdFreeData(&digests);

+      return rc;

+  }

+ -- 

+ 2.27.0

+ 

@@ -0,0 +1,431 @@ 

+ From ea1177fcef609519f0c2377ebee236001d2a8fae Mon Sep 17 00:00:00 2001

+ From: chantra <chantr4@gmail.com>

+ Date: Fri, 28 Jan 2022 08:31:39 -0800

+ Subject: [PATCH 06/30] [rpm2extents] verify package signature during

+  transcoding

+ 

+ ---

+  lib/rpmchecksig.c |  30 ++++++

+  lib/rpmcli.h      |   9 ++

+  rpm2extents.c     | 233 +++++++++++++++++++++++++++++++++++++++++-----

+  3 files changed, 248 insertions(+), 24 deletions(-)

+ 

+ diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c

+ index 40a3ab83f..1a6b95323 100644

+ --- a/lib/rpmchecksig.c

+ +++ b/lib/rpmchecksig.c

+ @@ -304,3 +304,33 @@ int rpmcliVerifySignatures(rpmts ts, ARGV_const_t argv)

+      rpmKeyringFree(keyring);

+      return res;

+  }

+ +

+ +int rpmcliVerifySignaturesFD(rpmts ts, FD_t fdi)

+ +{

+ +    int res = 0;

+ +    rpmKeyring keyring = rpmtsGetKeyring(ts, 1);

+ +    rpmVSFlags vsflags = rpmtsVfyFlags(ts);

+ +    int vfylevel = rpmtsVfyLevel(ts);

+ +

+ +    vsflags |= rpmcliVSFlags;

+ +    if (rpmcliVfyLevelMask) {

+ +	vfylevel &= ~rpmcliVfyLevelMask;

+ +	rpmtsSetVfyLevel(ts, vfylevel);

+ +    }

+ +

+ +    FD_t fd = fdDup(Fileno(fdi));

+ +    if (fd == NULL || Ferror(fd)) {

+ +	rpmlog(RPMLOG_ERR, _("fdDup failed: %s\n"), Fstrerror(fd));

+ +	res++;

+ +    } else if (rpmpkgVerifySigs(keyring, vfylevel, vsflags, fd, "stdin")) {

+ +	res++;

+ +    }

+ +

+ +    lseek(Fileno(fd), SEEK_SET, 0);

+ +    Fclose(fd);

+ +    rpmsqPoll();

+ +

+ +    rpmKeyringFree(keyring);

+ +    return res;

+ +}

+ +

+ diff --git a/lib/rpmcli.h b/lib/rpmcli.h

+ index 906fe9951..52443e459 100644

+ --- a/lib/rpmcli.h

+ +++ b/lib/rpmcli.h

+ @@ -411,6 +411,15 @@ int rpmcliImportPubkeys(rpmts ts, ARGV_const_t argv);

+   */

+  int rpmcliVerifySignatures(rpmts ts, ARGV_const_t argv);

+  

+ +

+ +/** \ingroup rpmcli

+ + * Verify package signatures

+ + * @param ts		transaction set

+ + * @param fd		a file descriptor to verify

+ + * @return		0 on success

+ + */

+ +int rpmcliVerifySignaturesFD(rpmts ts, FD_t fd);

+ +

+  #ifdef __cplusplus

+  }

+  #endif

+ diff --git a/rpm2extents.c b/rpm2extents.c

+ index c111be0a2..d8e582676 100644

+ --- a/rpm2extents.c

+ +++ b/rpm2extents.c

+ @@ -2,7 +2,9 @@

+  

+  #include "system.h"

+  

+ +#include <rpm/rpmcli.h>

+  #include <rpm/rpmlib.h>		/* rpmReadPackageFile .. */

+ +#include <rpm/rpmlog.h>

+  #include <rpm/rpmfi.h>

+  #include <rpm/rpmtag.h>

+  #include <rpm/rpmio.h>

+ @@ -10,6 +12,7 @@

+  

+  #include <rpm/rpmts.h>

+  #include "lib/rpmlead.h"

+ +#include "lib/rpmts.h"

+  #include "lib/signature.h"

+  #include "lib/header_internal.h"

+  #include "rpmio/rpmio_internal.h"

+ @@ -51,6 +54,16 @@ rpm_loff_t pad_to(rpm_loff_t pos, rpm_loff_t unit)

+      return (unit - (pos % unit)) % unit;

+  }

+  

+ +static struct poptOption optionsTable[] = {

+ +    { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,

+ +    N_("Common options for all rpm modes and executables:"), NULL },

+ +

+ +    POPT_AUTOALIAS

+ +    POPT_AUTOHELP

+ +    POPT_TABLEEND

+ +};

+ +

+ +

+  static int digestor(

+      FD_t fdi,

+      FD_t fdo,

+ @@ -120,7 +133,19 @@ exit:

+      return rc;

+  }

+  

+ -static rpmRC process_package(FD_t fdi, FD_t validationi)

+ +static rpmRC validator(FD_t fdi){

+ +    rpmts ts = rpmtsCreate();

+ +    rpmtsSetRootDir(ts, rpmcliRootDir);

+ +    /* rpmlog prints NOTICE to stdout */

+ +    // rpmlogSetFile(stderr);

+ +    if(rpmcliVerifySignaturesFD(ts, fdi)){

+ +	fprintf(stderr, _("Error validating package\n"));

+ +	return RPMRC_FAIL;

+ +    }

+ +    return RPMRC_OK;

+ +}

+ +

+ +static rpmRC process_package(FD_t fdi, FD_t digestori, FD_t validationi)

+  {

+      uint32_t diglen;

+      /* GNU C extension: can use diglen from outer context */

+ @@ -148,7 +173,7 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)

+      rpm_mode_t mode;

+      char *rpmio_flags = NULL, *zeros;

+      const unsigned char *digest;

+ -    rpm_loff_t pos, size, pad, validation_pos;

+ +    rpm_loff_t pos, size, pad, digest_pos, validation_pos;

+      uint32_t offset_ix = 0;

+      size_t len;

+      int next = 0;

+ @@ -278,17 +303,26 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)

+  	    goto exit;

+  	}