Okay, Will correct and send V2. Thanks, Vivek
On Fri, Apr 26, 2024 at 1:29 AM Steve Sakoman <st...@sakoman.com> wrote: > This patch caused multiple build failures both locally and on the > autobuilder. > > Here is a link to the autobuilder run: > > https://autobuilder.yoctoproject.org/typhoon/#/builders/83/builds/6845 > > Sample error log: > > https://errors.yoctoproject.org/Errors/Details/763370/ > > Steve > > On Tue, Apr 23, 2024 at 9:30 AM Vivek Kumbhar via > lists.openembedded.org <vkumbhar=mvista....@lists.openembedded.org> > wrote: > > > > Upstream-Status: Backport > https://github.com/rpm-software-management/rpm/commit/96ec957e281220f8e137a2d5eb23b83a6377d556 > > > https://github.com/rpm-software-management/rpm/commit/fb13f7fd9eff012cb7b9dbf94ac5381c69404055 > > > > Signed-off-by: Vivek Kumbhar <vkumb...@mvista.com> > > --- > > .../rpm/files/CVE-2021-35939.patch | 378 ++++++++++++++++++ > > meta/recipes-devtools/rpm/rpm_4.17.1.bb | 1 + > > 2 files changed, 379 insertions(+) > > create mode 100644 meta/recipes-devtools/rpm/files/CVE-2021-35939.patch > > > > diff --git a/meta/recipes-devtools/rpm/files/CVE-2021-35939.patch > b/meta/recipes-devtools/rpm/files/CVE-2021-35939.patch > > new file mode 100644 > > index 0000000000..b60cc0e5ce > > --- /dev/null > > +++ b/meta/recipes-devtools/rpm/files/CVE-2021-35939.patch > > @@ -0,0 +1,378 @@ > > +From 96ec957e281220f8e137a2d5eb23b83a6377d556 Mon Sep 17 00:00:00 2001 > > +From: Panu Matilainen <pmati...@redhat.com> > > +Date: Thu, 10 Feb 2022 14:32:43 +0200 > > +Subject: [PATCH] Validate intermediate symlinks during installation, > > + CVE-2021-35939 > > + > > +Whenever directory changes during unpacking, walk the entire tree from > > +starting from / and validate any symlinks crossed, fail the install > > +on invalid links. > > + > > +This is the first of step of many towards securing our file operations > > +against local tamperers and besides plugging that one CVE, paves the way > > +for the next step by adding the necessary directory fd tracking. > > +This also bumps the rpm OS requirements to a whole new level by > requiring > > +the *at() family of calls from POSIX-1.2008. > > + > > +This necessarily does a whole lot of huffing and puffing we previously > > +did not do. It should be possible to cache secure (ie root-owned) > > +directory structures to avoid validating everything a million times > > +but for now, just keeping things simple. > > + > > +Upstream-Status: Backport [ > https://github.com/rpm-software-management/rpm/commit/96ec957e281220f8e137a2d5eb23b83a6377d556 > ] > > +CVE: CVE-2021-35939 > > +Signed-off-by: Vivek Kumbhar <vkumb...@mvista.com> > > +--- > > + INSTALL | 2 + > > + configure.ac | 3 +- > > + lib/fsm.c | 144 +++++++++++++++++++++++++++++++++++++++++-- > > + lib/rpmfi.c | 27 +++++++- > > + lib/rpmfi_internal.h | 17 +++++ > > + 5 files changed, 183 insertions(+), 10 deletions(-) > > + > > +diff --git a/INSTALL b/INSTALL > > +index 358e5ae0d..9a9c7b0d0 100644 > > +--- a/INSTALL > > ++++ b/INSTALL > > +@@ -103,6 +103,8 @@ option to configure). For GCC, OpenMP 4.5 is fully > supported since GCC 6.1, > > + which is available from > > + http://www.gnu.org/ > > + > > ++Rpm requires a POSIX.1-2008 level operating system. > > ++ > > + To compile RPM: > > + -------------- > > + > > +diff --git a/configure.ac b/configure.ac > > +index 78c555f90..4ddacdfe2 100644 > > +--- a/configure.ac > > ++++ b/configure.ac > > +@@ -570,7 +570,8 @@ AC_CHECK_FUNCS([secure_getenv __secure_getenv]) > > + > > + AC_CHECK_FUNCS( > > + [mkstemp getcwd basename dirname realpath setenv unsetenv regcomp > lchown \ > > +- utimes getline localtime_r statvfs getaddrinfo ], > > ++ utimes getline localtime_r statvfs getaddrinfo \ > > ++ openat mkdirat fstatat ], > > + [], [AC_MSG_ERROR([function required by rpm])]) > > + > > + AC_LIBOBJ(fnmatch) > > +diff --git a/lib/fsm.c b/lib/fsm.c > > +index 935a0a5c6..0b29284e8 100644 > > +--- a/lib/fsm.c > > ++++ b/lib/fsm.c > > +@@ -8,6 +8,7 @@ > > + #include <inttypes.h> > > + #include <utime.h> > > + #include <errno.h> > > ++#include <fcntl.h> > > + #if WITH_CAP > > + #include <sys/capability.h> > > + #endif > > +@@ -20,6 +21,7 @@ > > + #include "rpmio/rpmio_internal.h" /* fdInit/FiniDigest */ > > + #include "lib/fsm.h" > > + #include "lib/rpmte_internal.h" /* XXX rpmfs */ > > ++#include "lib/rpmfi_internal.h" /* rpmfiSetOnChdir */ > > + #include "lib/rpmplugins.h" /* rpm plugins hooks */ > > + #include "lib/rpmug.h" > > + > > +@@ -406,17 +408,118 @@ static int fsmRmdir(const char *path) > > + return rc; > > + } > > + > > +-static int fsmMkdir(const char *path, mode_t mode) > > ++static int fsmMkdir(int dirfd, const char *path, mode_t mode) > > + { > > +- int rc = mkdir(path, (mode & 07777)); > > ++ int rc = mkdirat(dirfd, path, (mode & 07777)); > > + if (_fsm_debug) > > +- rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%04o) %s\n", __func__, > > +- path, (unsigned)(mode & 07777), > > ++ rpmlog(RPMLOG_DEBUG, " %8s (%d %s, 0%04o) %s\n", __func__, > > ++ dirfd, path, (unsigned)(mode & 07777), > > + (rc < 0 ? strerror(errno) : "")); > > + if (rc < 0) rc = RPMERR_MKDIR_FAILED; > > + return rc; > > + } > > + > > ++static int fsmOpenat(int dirfd, const char *path, int flags) > > ++{ > > ++ struct stat lsb, sb; > > ++ int sflags = flags | O_NOFOLLOW; > > ++ int fd = openat(dirfd, path, sflags); > > ++ > > ++ /* > > ++ * Only ever follow symlinks by root or target owner. Since we > can't > > ++ * open the symlink itself, the order matters: we stat the link > *after* > > ++ * opening the target, and if the link ownership changed between > the calls > > ++ * it could've only been the link owner or root. > > ++ */ > > ++ if (fd < 0 && errno == ELOOP && flags != sflags) { > > ++ int ffd = openat(dirfd, path, flags); > > ++ if (ffd >= 0 && fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) > == 0) { > > ++ if (fstat(ffd, &sb) == 0) { > > ++ if (lsb.st_uid == 0 || lsb.st_uid == sb.st_uid) { > > ++ fd = ffd; > > ++ } else { > > ++ close(ffd); > > ++ } > > ++ } > > ++ } > > ++ } > > ++ return fd; > > ++} > > ++ > > ++static int fsmDoMkDir(rpmPlugins plugins, int dirfd, const char *dn, > > ++ int owned, mode_t mode) > > ++{ > > ++ int rc; > > ++ rpmFsmOp op = (FA_CREATE); > > ++ if (!owned) > > ++ op |= FAF_UNOWNED; > > ++ > > ++ /* Run fsm file pre hook for all plugins */ > > ++ rc = rpmpluginsCallFsmFilePre(plugins, NULL, dn, mode, op); > > ++ > > ++ if (!rc) > > ++ rc = fsmMkdir(dirfd, dn, mode); > > ++ > > ++ if (!rc) { > > ++ rc = rpmpluginsCallFsmFilePrepare(plugins, NULL, dn, dn, mode, > op); > > ++ } > > ++ > > ++ /* Run fsm file post hook for all plugins */ > > ++ rpmpluginsCallFsmFilePost(plugins, NULL, dn, mode, op, rc); > > ++ > > ++ if (!rc) { > > ++ rpmlog(RPMLOG_DEBUG, > > ++ "%s directory created with perms %04o\n", > > ++ dn, (unsigned)(mode & 07777)); > > ++ } > > ++ > > ++ return rc; > > ++} > > ++ > > ++static int ensureDir(rpmPlugins plugins, const char *p, int owned, int > create) > > ++{ > > ++ char *path = xstrdup(p); > > ++ char *dp = path; > > ++ char *sp = NULL, *bn; > > ++ int oflags = O_RDONLY; > > ++ > > ++ int dirfd = fsmOpenat(-1, "/", oflags); > > ++ int fd = dirfd; /* special case of "/" */ > > ++ > > ++ while ((bn = strtok_r(dp, "/", &sp)) != NULL) { > > ++ struct stat sb; > > ++ fd = fsmOpenat(dirfd, bn, oflags); > > ++ > > ++ if (fd < 0 && errno == ENOENT && create) { > > ++ mode_t mode = S_IFDIR | (_dirPerms & 07777); > > ++ if (fsmDoMkDir(plugins, dirfd, bn, owned, mode) == 0) { > > ++ fd = fsmOpenat(dirfd, bn, oflags|O_NOFOLLOW); > > ++ } > > ++ } > > ++ > > ++ if (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode)) { > > ++ close(fd); > > ++ errno = ENOTDIR; > > ++ fd = -1; > > ++ } > > ++ > > ++ close(dirfd); > > ++ if (fd >= 0) { > > ++ dirfd = fd; > > ++ } else { > > ++ dirfd = -1; > > ++ rpmlog(RPMLOG_ERR, _("failed to open dir %s of %s: %s\n"), > > ++ bn, p, strerror(errno)); > > ++ break; > > ++ } > > ++ > > ++ dp = NULL; > > ++ } > > ++ > > ++ free(path); > > ++ return dirfd; > > ++} > > ++ > > + static int fsmMkfifo(const char *path, mode_t mode) > > + { > > + int rc = mkfifo(path, (mode & 07777)); > > +@@ -507,7 +610,7 @@ static int fsmMkdirs(rpmfiles files, rpmfs fs, > rpmPlugins plugins) > > + rc = rpmpluginsCallFsmFilePre(plugins, NULL, dn, mode, > op); > > + > > + if (!rc) > > +- rc = fsmMkdir(dn, mode); > > ++ rc = fsmMkdir(-1, dn, mode); > > + > > + if (!rc) { > > + rc = rpmpluginsCallFsmFilePrepare(plugins, NULL, dn, > dn, > > +@@ -874,6 +977,21 @@ static void setFileState(rpmfs fs, int i) > > + } > > + } > > + > > ++struct diriter_s { > > ++ int dirfd; > > ++}; > > ++ > > ++static int onChdir(rpmfi fi, void *data) > > ++{ > > ++ struct diriter_s *di = data; > > ++ > > ++ if (di->dirfd >= 0) { > > ++ close(di->dirfd); > > ++ di->dirfd = -1; > > ++ } > > ++ return 0; > > ++} > > ++ > > + int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, > > + rpmpsm psm, char ** failedFile) > > + { > > +@@ -890,6 +1008,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, > rpmfiles files, > > + char *tid = NULL; > > + struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata)); > > + struct filedata_s *firstlink = NULL; > > ++ struct diriter_s di = { -1 }; > > + > > + /* transaction id used for temporary path suffix while installing > */ > > + rasprintf(&tid, ";%08x", (unsigned)rpmtsGetTid(ts)); > > +@@ -929,6 +1048,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, > rpmfiles files, > > + rc = RPMERR_BAD_MAGIC; > > + goto exit; > > + } > > ++ rpmfiSetOnChdir(fi, onChdir, &di); > > + > > + /* Detect and create directories not explicitly in package. */ > > + if (!rc) > > +@@ -943,6 +1063,16 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, > rpmfiles files, > > + if (!fp->suffix) { > > + rc = fsmBackup(fi, fp->action); > > + } > > ++ > > ++ if (di.dirfd == -1) { > > ++ di.dirfd = ensureDir(plugins, rpmfiDN(fi), 0, > > ++ (fp->action == FA_CREATE)); > > ++ if (di.dirfd == -1) { > > ++ rc = RPMERR_OPEN_FAILED; > > ++ break; > > ++ } > > ++ } > > ++ > > + /* Assume file does't exist when tmp suffix is in use */ > > + if (!fp->suffix) { > > + if (fp->action == FA_TOUCH) { > > +@@ -977,7 +1107,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, > rpmfiles files, > > + mode_t mode = fp->sb.st_mode; > > + mode &= ~07777; > > + mode |= 00700; > > +- rc = fsmMkdir(fp->fpath, mode); > > ++ rc = fsmMkdir(di.dirfd, fp->fpath, mode); > > + } > > + } else if (S_ISLNK(fp->sb.st_mode)) { > > + if (rc == RPMERR_ENOENT) { > > +@@ -1019,6 +1149,8 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, > rpmfiles files, > > + fp->stage = FILE_UNPACK; > > + } > > + fi = rpmfiFree(fi); > > ++ close(di.dirfd); > > ++ di.dirfd = -1; > > + > > + if (!rc && fx < 0 && fx != RPMERR_ITER_END) > > + rc = fx; > > +diff --git a/lib/rpmfi.c b/lib/rpmfi.c > > +index 33b657aa2..740e257fe 100644 > > +--- a/lib/rpmfi.c > > ++++ b/lib/rpmfi.c > > +@@ -55,6 +55,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 */ > > +@@ -309,6 +312,17 @@ int rpmfiDI(rpmfi fi) > > + } > > + #endif > > + > > ++int rpmfiSetOnChdir(rpmfi fi, rpmfiChdirCb cb, void *data) > > ++{ > > ++ int rc = -1; > > ++ if (fi != NULL) { > > ++ fi->onChdir = cb; > > ++ fi->onChdirData = data; > > ++ rc = 0; > > ++ } > > ++ return rc; > > ++} > > ++ > > + int rpmfiFX(rpmfi fi) > > + { > > + return (fi != NULL ? fi->i : -1); > > +@@ -319,9 +333,17 @@ int rpmfiSetFX(rpmfi fi, int fx) > > + int i = -1; > > + > > + if (fi != NULL && fx >= 0 && fx < rpmfilesFC(fi->files)) { > > +- i = fi->i; > > ++ 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; > > + } > > +@@ -1816,10 +1838,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.39.3 > > + > > diff --git a/meta/recipes-devtools/rpm/rpm_4.17.1.bb > b/meta/recipes-devtools/rpm/rpm_4.17.1.bb > > index 9b6446f265..aad8f2468f 100644 > > --- a/meta/recipes-devtools/rpm/rpm_4.17.1.bb > > +++ b/meta/recipes-devtools/rpm/rpm_4.17.1.bb > > @@ -40,6 +40,7 @@ SRC_URI = "git:// > github.com/rpm-software-management/rpm;branch=rpm-4.17.x;protoc > > file://0001-docs-do-not-build-manpages-requires-pandoc.patch > \ > > > file://0001-build-pack.c-do-not-insert-payloadflags-into-.rpm-me.patch \ > > > file://0001-configure.ac-add-linux-gnux32-variant-to-triplet-han.patch \ > > + file://CVE-2021-35939.patch \ > > " > > > > PE = "1" > > -- > > 2.39.3 > > > > > > > > >
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#198710): https://lists.openembedded.org/g/openembedded-core/message/198710 Mute This Topic: https://lists.openembedded.org/mt/105692772/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-