From 3de3a8032b3f570be76e338d163d893fb3c10603 Mon Sep 17 00:00:00 2001 From: Anderson Torres Date: Thu, 10 Oct 2024 10:50:46 -0300 Subject: [PATCH 1/4] cvs: refactor and adopt - hammer - nixfmt-rfc-style - finalAttrs - no nested with - meta.mainProgram --- pkgs/by-name/cv/cvs/package.nix | 52 +++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/pkgs/by-name/cv/cvs/package.nix b/pkgs/by-name/cv/cvs/package.nix index 7ec801503f767..882ad7737bf5e 100644 --- a/pkgs/by-name/cv/cvs/package.nix +++ b/pkgs/by-name/cv/cvs/package.nix @@ -1,12 +1,18 @@ -{ lib, stdenv, fetchurl, fetchpatch, nano }: +{ + lib, + fetchpatch, + fetchurl, + nano, + stdenv, +}: -stdenv.mkDerivation rec { +stdenv.mkDerivation (finalAttrs: { pname = "cvs"; version = "1.12.13"; src = fetchurl { - url = "mirror://savannah/cvs/source/feature/${version}/cvs-${version}.tar.bz2"; - sha256 = "0pjir8cwn0087mxszzbsi1gyfc6373vif96cw4q3m1x6p49kd1bq"; + url = "mirror://savannah/cvs/source/feature/${finalAttrs.version}/cvs-${finalAttrs.version}.tar.bz2"; + hash = "sha256-eIU2E7mmhzow4cwkF/c4wzDnX4h6/a97PQgAyxnKUV4="; }; patches = [ @@ -15,19 +21,14 @@ stdenv.mkDerivation rec { ./CVE-2017-12836.patch (fetchpatch { url = "https://raw.githubusercontent.com/Homebrew/formula-patches/24118ec737c7/cvs/vasnprintf-high-sierra-fix.diff"; - sha256 = "1ql6aaia7xkfq3vqhlw5bd2z2ywka82zk01njs1b2szn699liymg"; + hash = "sha256-r/pIUzL2a7GCljaA+QVSk3vxRVuFU4j3wG72o6JShuI="; }) ]; - hardeningDisable = [ "fortify" "format" ]; - - preConfigure = '' - # Apply the Debian patches. - for p in "debian/patches/"*; do - echo "applying \`$p' ..." - patch --verbose -p1 < "$p" - done - ''; + hardeningDisable = [ + "fortify" + "format" + ]; configureFlags = [ "--with-editor=${nano}/bin/nano" @@ -46,10 +47,23 @@ stdenv.mkDerivation rec { doCheck = false; # fails 1 of 1 tests - meta = with lib; { + preConfigure = '' + # Apply the Debian patches. + for p in "debian/patches/"*; do + echo "applying \`$p' ..." + patch --verbose -p1 < "$p" + done + ''; + + meta = { homepage = "http://cvs.nongnu.org"; - description = "Concurrent Versions System - a source control system"; - license = licenses.gpl2Plus; # library is GPLv2, main is GPLv1 - platforms = platforms.all; + description = "Concurrent Versions System"; + license = with lib.licenses; [ + gpl1Plus # program + gpl2Plus # library + ]; + mainProgram = "cvs"; + maintainers = with lib.maintainers; [ AndersonTorres ]; + platforms = lib.platforms.all; }; -} +}) From 6be864b40d869ed9c1ac141c6908a40ae9c2a2fb Mon Sep 17 00:00:00 2001 From: Anderson Torres Date: Thu, 10 Oct 2024 12:06:55 -0300 Subject: [PATCH 2/4] cvs: unpack the patches from getcwd-chroot.patch This removes that uncanny preConfigure. --- pkgs/by-name/cv/cvs/getcwd-chroot.patch | 302 ------------------ pkgs/by-name/cv/cvs/package.nix | 15 +- .../cv/cvs/patches/0000-readdir-errno.patch | 121 +++++++ .../cv/cvs/patches/0001-getcwd-chroot.patch | 172 ++++++++++ .../0002-CVE-2012-0804.patch} | 0 .../0003-CVE-2017-12836.patch} | 0 6 files changed, 297 insertions(+), 313 deletions(-) delete mode 100644 pkgs/by-name/cv/cvs/getcwd-chroot.patch create mode 100644 pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch create mode 100644 pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch rename pkgs/by-name/cv/cvs/{CVE-2012-0804.patch => patches/0002-CVE-2012-0804.patch} (100%) rename pkgs/by-name/cv/cvs/{CVE-2017-12836.patch => patches/0003-CVE-2017-12836.patch} (100%) diff --git a/pkgs/by-name/cv/cvs/getcwd-chroot.patch b/pkgs/by-name/cv/cvs/getcwd-chroot.patch deleted file mode 100644 index 3f827a1e6981e..0000000000000 --- a/pkgs/by-name/cv/cvs/getcwd-chroot.patch +++ /dev/null @@ -1,302 +0,0 @@ -Fix Gnulib's getcwd in chroots. -From Debian bug #456164, http://bugs.debian.org/456164 . - ---- cvs-1.12.13.orig/debian/patches/20_readdir_errno -+++ cvs-1.12.13/debian/patches/20_readdir_errno -@@ -0,0 +1,121 @@ -+# From Gnulib: -+# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=0b78641d85af3b72e3b9d94cb7b94e45f3c08ee5 -+# We don't need this directly, but it's required so that 21_getcwd_chroot -+# applies cleanly. -+# -+# 2005-10-29 Paul Eggert -+# -+# * getcwd.c (__getcwd): Don't assume that system calls after readdir -+# leave errno alone. Problem reported by Dmitry V. Levin. -+ -+--- cvs-1.12.13-old/lib/getcwd.c -++++ cvs-1.12.13/lib/getcwd.c -+@@ -201,6 +201,8 @@ __getcwd (char *buf, size_t size) -+ ino_t dotino; -+ bool mount_point; -+ int parent_status; -++ size_t dirroom; -++ size_t namlen; -+ -+ /* Look at the parent directory. */ -+ #ifdef AT_FDCWD -+@@ -241,11 +243,20 @@ __getcwd (char *buf, size_t size) -+ goto lose; -+ dotlist[dotlen++] = '/'; -+ #endif -+- /* Clear errno to distinguish EOF from error if readdir returns -+- NULL. */ -+- __set_errno (0); -+- while ((d = __readdir (dirstream)) != NULL) -++ for (;;) -+ { -++ /* Clear errno to distinguish EOF from error if readdir returns -++ NULL. */ -++ __set_errno (0); -++ d = __readdir (dirstream); -++ if (d == NULL) -++ { -++ if (errno == 0) -++ /* EOF on dirstream, which means that the current directory -++ has been removed. */ -++ __set_errno (ENOENT); -++ goto lose; -++ } -+ if (d->d_name[0] == '.' && -+ (d->d_name[1] == '\0' || -+ (d->d_name[1] == '.' && d->d_name[2] == '\0'))) -+@@ -303,48 +314,38 @@ __getcwd (char *buf, size_t size) -+ break; -+ } -+ } -+- if (d == NULL) -+- { -+- if (errno == 0) -+- /* EOF on dirstream, which means that the current directory -+- has been removed. */ -+- __set_errno (ENOENT); -+- goto lose; -+- } -+- else -+- { -+- size_t dirroom = dirp - dir; -+- size_t namlen = _D_EXACT_NAMLEN (d); -+ -+- if (dirroom <= namlen) -++ dirroom = dirp - dir; -++ namlen = _D_EXACT_NAMLEN (d); -++ -++ if (dirroom <= namlen) -++ { -++ if (size != 0) -+ { -+- if (size != 0) -+- { -+- __set_errno (ERANGE); -+- goto lose; -+- } -+- else -+- { -+- char *tmp; -+- size_t oldsize = allocated; -++ __set_errno (ERANGE); -++ goto lose; -++ } -++ else -++ { -++ char *tmp; -++ size_t oldsize = allocated; -+ -+- allocated += MAX (allocated, namlen); -+- if (allocated < oldsize -+- || ! (tmp = realloc (dir, allocated))) -+- goto memory_exhausted; -++ allocated += MAX (allocated, namlen); -++ if (allocated < oldsize -++ || ! (tmp = realloc (dir, allocated))) -++ goto memory_exhausted; -+ -+- /* Move current contents up to the end of the buffer. -+- This is guaranteed to be non-overlapping. */ -+- dirp = memcpy (tmp + allocated - (oldsize - dirroom), -+- tmp + dirroom, -+- oldsize - dirroom); -+- dir = tmp; -+- } -++ /* Move current contents up to the end of the buffer. -++ This is guaranteed to be non-overlapping. */ -++ dirp = memcpy (tmp + allocated - (oldsize - dirroom), -++ tmp + dirroom, -++ oldsize - dirroom); -++ dir = tmp; -+ } -+- dirp -= namlen; -+- memcpy (dirp, d->d_name, namlen); -+- *--dirp = '/'; -+ } -++ dirp -= namlen; -++ memcpy (dirp, d->d_name, namlen); -++ *--dirp = '/'; -+ -+ thisdev = dotdev; -+ thisino = dotino; ---- cvs-1.12.13.orig/debian/patches/21_getcwd_chroot -+++ cvs-1.12.13/debian/patches/21_getcwd_chroot -@@ -0,0 +1,172 @@ -+# From Gnulib: -+# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=79c0a43808d9ca85acd04600149fc1a9b75bd1b9 -+# -+# 2006-07-03 Paul Eggert -+# -+# Merge from coreutils. -+# -+# 2006-03-19 Jim Meyering -+# -+# Work even in a chroot where d_ino values for entries in "/" -+# don't match the stat.st_ino values for the same names. -+# * getcwd.c (__getcwd): When no d_ino value matches the target inode -+# number, iterate through all entries again, using lstat instead. -+# Reported by Kenshi Muto in http://bugs.debian.org/355810, and by -+# Zouhir Hafidi in https://bugzilla.redhat.com/bugzilla/190656. -+# -+# * getcwd.c (__getcwd): Clarify a comment. -+# Use memcpy in place of a call to strcpy. -+ -+--- cvs-1.12.13-old/lib/getcwd.c -++++ cvs-1.12.13/lib/getcwd.c -+@@ -211,6 +211,7 @@ __getcwd (char *buf, size_t size) -+ int parent_status; -+ size_t dirroom; -+ size_t namlen; -++ bool use_d_ino = true; -+ -+ /* Look at the parent directory. */ -+ #ifdef AT_FDCWD -+@@ -257,11 +258,26 @@ __getcwd (char *buf, size_t size) -+ NULL. */ -+ __set_errno (0); -+ d = __readdir (dirstream); -++ -++ /* When we've iterated through all directory entries without finding -++ one with a matching d_ino, rewind the stream and consider each -++ name again, but this time, using lstat. This is necessary in a -++ chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where -++ .., ../.., ../../.., etc. all had the same device number, yet the -++ d_ino values for entries in / did not match those obtained -++ via lstat. */ -++ if (d == NULL && errno == 0 && use_d_ino) -++ { -++ use_d_ino = false; -++ rewinddir (dirstream); -++ d = __readdir (dirstream); -++ } -++ -+ if (d == NULL) -+ { -+ if (errno == 0) -+- /* EOF on dirstream, which means that the current directory -+- has been removed. */ -++ /* EOF on dirstream, which can mean e.g., that the current -++ directory has been removed. */ -+ __set_errno (ENOENT); -+ goto lose; -+ } -+@@ -269,58 +285,65 @@ __getcwd (char *buf, size_t size) -+ (d->d_name[1] == '\0' || -+ (d->d_name[1] == '.' && d->d_name[2] == '\0'))) -+ continue; -+- if (MATCHING_INO (d, thisino) || mount_point) -++ -++ if (use_d_ino) -+ { -+- int entry_status; -++ bool match = (MATCHING_INO (d, thisino) || mount_point); -++ if (! match) -++ continue; -++ } -++ -++ { -++ int entry_status; -+ #ifdef AT_FDCWD -+- entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); -++ entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); -+ #else -+- /* Compute size needed for this file name, or for the file -+- name ".." in the same directory, whichever is larger. -+- Room for ".." might be needed the next time through -+- the outer loop. */ -+- size_t name_alloc = _D_ALLOC_NAMLEN (d); -+- size_t filesize = dotlen + MAX (sizeof "..", name_alloc); -+- -+- if (filesize < dotlen) -+- goto memory_exhausted; -+- -+- if (dotsize < filesize) -+- { -+- /* My, what a deep directory tree you have, Grandma. */ -+- size_t newsize = MAX (filesize, dotsize * 2); -+- size_t i; -+- if (newsize < dotsize) -+- goto memory_exhausted; -+- if (dotlist != dots) -+- free (dotlist); -+- dotlist = malloc (newsize); -+- if (dotlist == NULL) -+- goto lose; -+- dotsize = newsize; -+- -+- i = 0; -+- do -+- { -+- dotlist[i++] = '.'; -+- dotlist[i++] = '.'; -+- dotlist[i++] = '/'; -+- } -+- while (i < dotlen); -+- } -+- -+- strcpy (dotlist + dotlen, d->d_name); -+- entry_status = __lstat (dotlist, &st); -++ /* Compute size needed for this file name, or for the file -++ name ".." in the same directory, whichever is larger. -++ Room for ".." might be needed the next time through -++ the outer loop. */ -++ size_t name_alloc = _D_ALLOC_NAMLEN (d); -++ size_t filesize = dotlen + MAX (sizeof "..", name_alloc); -++ -++ if (filesize < dotlen) -++ goto memory_exhausted; -++ -++ if (dotsize < filesize) -++ { -++ /* My, what a deep directory tree you have, Grandma. */ -++ size_t newsize = MAX (filesize, dotsize * 2); -++ size_t i; -++ if (newsize < dotsize) -++ goto memory_exhausted; -++ if (dotlist != dots) -++ free (dotlist); -++ dotlist = malloc (newsize); -++ if (dotlist == NULL) -++ goto lose; -++ dotsize = newsize; -++ -++ i = 0; -++ do -++ { -++ dotlist[i++] = '.'; -++ dotlist[i++] = '.'; -++ dotlist[i++] = '/'; -++ } -++ while (i < dotlen); -++ } -++ -++ memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d)); -++ entry_status = __lstat (dotlist, &st); -+ #endif -+- /* We don't fail here if we cannot stat() a directory entry. -+- This can happen when (network) file systems fail. If this -+- entry is in fact the one we are looking for we will find -+- out soon as we reach the end of the directory without -+- having found anything. */ -+- if (entry_status == 0 && S_ISDIR (st.st_mode) -+- && st.st_dev == thisdev && st.st_ino == thisino) -+- break; -+- } -++ /* We don't fail here if we cannot stat() a directory entry. -++ This can happen when (network) file systems fail. If this -++ entry is in fact the one we are looking for we will find -++ out soon as we reach the end of the directory without -++ having found anything. */ -++ if (entry_status == 0 && S_ISDIR (st.st_mode) -++ && st.st_dev == thisdev && st.st_ino == thisino) -++ break; -++ } -+ } -+ -+ dirroom = dirp - dir; diff --git a/pkgs/by-name/cv/cvs/package.nix b/pkgs/by-name/cv/cvs/package.nix index 882ad7737bf5e..5df60e97ea740 100644 --- a/pkgs/by-name/cv/cvs/package.nix +++ b/pkgs/by-name/cv/cvs/package.nix @@ -16,9 +16,10 @@ stdenv.mkDerivation (finalAttrs: { }; patches = [ - ./getcwd-chroot.patch - ./CVE-2012-0804.patch - ./CVE-2017-12836.patch + ./patches/0000-readdir-errno.patch + ./patches/0001-getcwd-chroot.patch + ./patches/0002-CVE-2012-0804.patch + ./patches/0003-CVE-2017-12836.patch (fetchpatch { url = "https://raw.githubusercontent.com/Homebrew/formula-patches/24118ec737c7/cvs/vasnprintf-high-sierra-fix.diff"; hash = "sha256-r/pIUzL2a7GCljaA+QVSk3vxRVuFU4j3wG72o6JShuI="; @@ -47,14 +48,6 @@ stdenv.mkDerivation (finalAttrs: { doCheck = false; # fails 1 of 1 tests - preConfigure = '' - # Apply the Debian patches. - for p in "debian/patches/"*; do - echo "applying \`$p' ..." - patch --verbose -p1 < "$p" - done - ''; - meta = { homepage = "http://cvs.nongnu.org"; description = "Concurrent Versions System"; diff --git a/pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch b/pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch new file mode 100644 index 0000000000000..6fd574f0b4d8a --- /dev/null +++ b/pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch @@ -0,0 +1,121 @@ +# From Gnulib: +# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=0b78641d85af3b72e3b9d94cb7b94e45f3c08ee5 +# We don't need this directly, but it's required so that 21_getcwd_chroot +# applies cleanly. +# +# 2005-10-29 Paul Eggert +# +# * getcwd.c (__getcwd): Don't assume that system calls after readdir +# leave errno alone. Problem reported by Dmitry V. Levin. + +--- cvs-1.12.13-old/lib/getcwd.c ++++ cvs-1.12.13/lib/getcwd.c +@@ -201,6 +201,8 @@ __getcwd (char *buf, size_t size) + ino_t dotino; + bool mount_point; + int parent_status; ++ size_t dirroom; ++ size_t namlen; + + /* Look at the parent directory. */ + #ifdef AT_FDCWD +@@ -241,11 +243,20 @@ __getcwd (char *buf, size_t size) + goto lose; + dotlist[dotlen++] = '/'; + #endif +- /* Clear errno to distinguish EOF from error if readdir returns +- NULL. */ +- __set_errno (0); +- while ((d = __readdir (dirstream)) != NULL) ++ for (;;) + { ++ /* Clear errno to distinguish EOF from error if readdir returns ++ NULL. */ ++ __set_errno (0); ++ d = __readdir (dirstream); ++ if (d == NULL) ++ { ++ if (errno == 0) ++ /* EOF on dirstream, which means that the current directory ++ has been removed. */ ++ __set_errno (ENOENT); ++ goto lose; ++ } + if (d->d_name[0] == '.' && + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) +@@ -303,48 +314,38 @@ __getcwd (char *buf, size_t size) + break; + } + } +- if (d == NULL) +- { +- if (errno == 0) +- /* EOF on dirstream, which means that the current directory +- has been removed. */ +- __set_errno (ENOENT); +- goto lose; +- } +- else +- { +- size_t dirroom = dirp - dir; +- size_t namlen = _D_EXACT_NAMLEN (d); + +- if (dirroom <= namlen) ++ dirroom = dirp - dir; ++ namlen = _D_EXACT_NAMLEN (d); ++ ++ if (dirroom <= namlen) ++ { ++ if (size != 0) + { +- if (size != 0) +- { +- __set_errno (ERANGE); +- goto lose; +- } +- else +- { +- char *tmp; +- size_t oldsize = allocated; ++ __set_errno (ERANGE); ++ goto lose; ++ } ++ else ++ { ++ char *tmp; ++ size_t oldsize = allocated; + +- allocated += MAX (allocated, namlen); +- if (allocated < oldsize +- || ! (tmp = realloc (dir, allocated))) +- goto memory_exhausted; ++ allocated += MAX (allocated, namlen); ++ if (allocated < oldsize ++ || ! (tmp = realloc (dir, allocated))) ++ goto memory_exhausted; + +- /* Move current contents up to the end of the buffer. +- This is guaranteed to be non-overlapping. */ +- dirp = memcpy (tmp + allocated - (oldsize - dirroom), +- tmp + dirroom, +- oldsize - dirroom); +- dir = tmp; +- } ++ /* Move current contents up to the end of the buffer. ++ This is guaranteed to be non-overlapping. */ ++ dirp = memcpy (tmp + allocated - (oldsize - dirroom), ++ tmp + dirroom, ++ oldsize - dirroom); ++ dir = tmp; + } +- dirp -= namlen; +- memcpy (dirp, d->d_name, namlen); +- *--dirp = '/'; + } ++ dirp -= namlen; ++ memcpy (dirp, d->d_name, namlen); ++ *--dirp = '/'; + + thisdev = dotdev; + thisino = dotino; diff --git a/pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch b/pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch new file mode 100644 index 0000000000000..da68c3b4351d9 --- /dev/null +++ b/pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch @@ -0,0 +1,172 @@ +# From Gnulib: +# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=79c0a43808d9ca85acd04600149fc1a9b75bd1b9 +# +# 2006-07-03 Paul Eggert +# +# Merge from coreutils. +# +# 2006-03-19 Jim Meyering +# +# Work even in a chroot where d_ino values for entries in "/" +# don't match the stat.st_ino values for the same names. +# * getcwd.c (__getcwd): When no d_ino value matches the target inode +# number, iterate through all entries again, using lstat instead. +# Reported by Kenshi Muto in http://bugs.debian.org/355810, and by +# Zouhir Hafidi in https://bugzilla.redhat.com/bugzilla/190656. +# +# * getcwd.c (__getcwd): Clarify a comment. +# Use memcpy in place of a call to strcpy. + +--- cvs-1.12.13-old/lib/getcwd.c ++++ cvs-1.12.13/lib/getcwd.c +@@ -211,6 +211,7 @@ __getcwd (char *buf, size_t size) + int parent_status; + size_t dirroom; + size_t namlen; ++ bool use_d_ino = true; + + /* Look at the parent directory. */ + #ifdef AT_FDCWD +@@ -257,11 +258,26 @@ __getcwd (char *buf, size_t size) + NULL. */ + __set_errno (0); + d = __readdir (dirstream); ++ ++ /* When we've iterated through all directory entries without finding ++ one with a matching d_ino, rewind the stream and consider each ++ name again, but this time, using lstat. This is necessary in a ++ chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where ++ .., ../.., ../../.., etc. all had the same device number, yet the ++ d_ino values for entries in / did not match those obtained ++ via lstat. */ ++ if (d == NULL && errno == 0 && use_d_ino) ++ { ++ use_d_ino = false; ++ rewinddir (dirstream); ++ d = __readdir (dirstream); ++ } ++ + if (d == NULL) + { + if (errno == 0) +- /* EOF on dirstream, which means that the current directory +- has been removed. */ ++ /* EOF on dirstream, which can mean e.g., that the current ++ directory has been removed. */ + __set_errno (ENOENT); + goto lose; + } +@@ -269,58 +285,65 @@ __getcwd (char *buf, size_t size) + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; +- if (MATCHING_INO (d, thisino) || mount_point) ++ ++ if (use_d_ino) + { +- int entry_status; ++ bool match = (MATCHING_INO (d, thisino) || mount_point); ++ if (! match) ++ continue; ++ } ++ ++ { ++ int entry_status; + #ifdef AT_FDCWD +- entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); ++ entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); + #else +- /* Compute size needed for this file name, or for the file +- name ".." in the same directory, whichever is larger. +- Room for ".." might be needed the next time through +- the outer loop. */ +- size_t name_alloc = _D_ALLOC_NAMLEN (d); +- size_t filesize = dotlen + MAX (sizeof "..", name_alloc); +- +- if (filesize < dotlen) +- goto memory_exhausted; +- +- if (dotsize < filesize) +- { +- /* My, what a deep directory tree you have, Grandma. */ +- size_t newsize = MAX (filesize, dotsize * 2); +- size_t i; +- if (newsize < dotsize) +- goto memory_exhausted; +- if (dotlist != dots) +- free (dotlist); +- dotlist = malloc (newsize); +- if (dotlist == NULL) +- goto lose; +- dotsize = newsize; +- +- i = 0; +- do +- { +- dotlist[i++] = '.'; +- dotlist[i++] = '.'; +- dotlist[i++] = '/'; +- } +- while (i < dotlen); +- } +- +- strcpy (dotlist + dotlen, d->d_name); +- entry_status = __lstat (dotlist, &st); ++ /* Compute size needed for this file name, or for the file ++ name ".." in the same directory, whichever is larger. ++ Room for ".." might be needed the next time through ++ the outer loop. */ ++ size_t name_alloc = _D_ALLOC_NAMLEN (d); ++ size_t filesize = dotlen + MAX (sizeof "..", name_alloc); ++ ++ if (filesize < dotlen) ++ goto memory_exhausted; ++ ++ if (dotsize < filesize) ++ { ++ /* My, what a deep directory tree you have, Grandma. */ ++ size_t newsize = MAX (filesize, dotsize * 2); ++ size_t i; ++ if (newsize < dotsize) ++ goto memory_exhausted; ++ if (dotlist != dots) ++ free (dotlist); ++ dotlist = malloc (newsize); ++ if (dotlist == NULL) ++ goto lose; ++ dotsize = newsize; ++ ++ i = 0; ++ do ++ { ++ dotlist[i++] = '.'; ++ dotlist[i++] = '.'; ++ dotlist[i++] = '/'; ++ } ++ while (i < dotlen); ++ } ++ ++ memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d)); ++ entry_status = __lstat (dotlist, &st); + #endif +- /* We don't fail here if we cannot stat() a directory entry. +- This can happen when (network) file systems fail. If this +- entry is in fact the one we are looking for we will find +- out soon as we reach the end of the directory without +- having found anything. */ +- if (entry_status == 0 && S_ISDIR (st.st_mode) +- && st.st_dev == thisdev && st.st_ino == thisino) +- break; +- } ++ /* We don't fail here if we cannot stat() a directory entry. ++ This can happen when (network) file systems fail. If this ++ entry is in fact the one we are looking for we will find ++ out soon as we reach the end of the directory without ++ having found anything. */ ++ if (entry_status == 0 && S_ISDIR (st.st_mode) ++ && st.st_dev == thisdev && st.st_ino == thisino) ++ break; ++ } + } + + dirroom = dirp - dir; diff --git a/pkgs/by-name/cv/cvs/CVE-2012-0804.patch b/pkgs/by-name/cv/cvs/patches/0002-CVE-2012-0804.patch similarity index 100% rename from pkgs/by-name/cv/cvs/CVE-2012-0804.patch rename to pkgs/by-name/cv/cvs/patches/0002-CVE-2012-0804.patch diff --git a/pkgs/by-name/cv/cvs/CVE-2017-12836.patch b/pkgs/by-name/cv/cvs/patches/0003-CVE-2017-12836.patch similarity index 100% rename from pkgs/by-name/cv/cvs/CVE-2017-12836.patch rename to pkgs/by-name/cv/cvs/patches/0003-CVE-2017-12836.patch From b15f30323c8212cfe03a4e70f6d59b70f6509ebf Mon Sep 17 00:00:00 2001 From: Anderson Torres Date: Thu, 10 Oct 2024 12:17:00 -0300 Subject: [PATCH 3/4] cvs: pick patches from their origins instead of vendoring them --- pkgs/by-name/cv/cvs/package.nix | 22 ++- .../cv/cvs/patches/0000-readdir-errno.patch | 121 ------------ .../cv/cvs/patches/0001-getcwd-chroot.patch | 172 ------------------ 3 files changed, 18 insertions(+), 297 deletions(-) delete mode 100644 pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch delete mode 100644 pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch diff --git a/pkgs/by-name/cv/cvs/package.nix b/pkgs/by-name/cv/cvs/package.nix index 5df60e97ea740..35c47b44d150b 100644 --- a/pkgs/by-name/cv/cvs/package.nix +++ b/pkgs/by-name/cv/cvs/package.nix @@ -1,6 +1,6 @@ { lib, - fetchpatch, + fetchpatch2, fetchurl, nano, stdenv, @@ -16,11 +16,25 @@ stdenv.mkDerivation (finalAttrs: { }; patches = [ - ./patches/0000-readdir-errno.patch - ./patches/0001-getcwd-chroot.patch + (fetchpatch2 { + name = "0000-readdir-errno.patch"; + url = "https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff_plain;h=0b78641d85af3b72e3b9d94cb7b94e45f3c08ee5"; + includes = [ + "lib/getcwd.c" + ]; + hash = "sha256-pfvFp335MNeRd8r1ZGHTN7MQfOKLB390WE4MW1cH3Y0="; + }) + (fetchpatch2 { + name = "0001-getcwd-chroot.patch"; + url = "https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff_plain;h=79c0a43808d9ca85acd04600149fc1a9b75bd1b9"; + includes = [ + "lib/getcwd.c" + ]; + hash = "sha256-u9sziWbZvjUH6flxOexLcn1ZEWTfn/ce6Es9/PxTKSM="; + }) ./patches/0002-CVE-2012-0804.patch ./patches/0003-CVE-2017-12836.patch - (fetchpatch { + (fetchpatch2 { url = "https://raw.githubusercontent.com/Homebrew/formula-patches/24118ec737c7/cvs/vasnprintf-high-sierra-fix.diff"; hash = "sha256-r/pIUzL2a7GCljaA+QVSk3vxRVuFU4j3wG72o6JShuI="; }) diff --git a/pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch b/pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch deleted file mode 100644 index 6fd574f0b4d8a..0000000000000 --- a/pkgs/by-name/cv/cvs/patches/0000-readdir-errno.patch +++ /dev/null @@ -1,121 +0,0 @@ -# From Gnulib: -# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=0b78641d85af3b72e3b9d94cb7b94e45f3c08ee5 -# We don't need this directly, but it's required so that 21_getcwd_chroot -# applies cleanly. -# -# 2005-10-29 Paul Eggert -# -# * getcwd.c (__getcwd): Don't assume that system calls after readdir -# leave errno alone. Problem reported by Dmitry V. Levin. - ---- cvs-1.12.13-old/lib/getcwd.c -+++ cvs-1.12.13/lib/getcwd.c -@@ -201,6 +201,8 @@ __getcwd (char *buf, size_t size) - ino_t dotino; - bool mount_point; - int parent_status; -+ size_t dirroom; -+ size_t namlen; - - /* Look at the parent directory. */ - #ifdef AT_FDCWD -@@ -241,11 +243,20 @@ __getcwd (char *buf, size_t size) - goto lose; - dotlist[dotlen++] = '/'; - #endif -- /* Clear errno to distinguish EOF from error if readdir returns -- NULL. */ -- __set_errno (0); -- while ((d = __readdir (dirstream)) != NULL) -+ for (;;) - { -+ /* Clear errno to distinguish EOF from error if readdir returns -+ NULL. */ -+ __set_errno (0); -+ d = __readdir (dirstream); -+ if (d == NULL) -+ { -+ if (errno == 0) -+ /* EOF on dirstream, which means that the current directory -+ has been removed. */ -+ __set_errno (ENOENT); -+ goto lose; -+ } - if (d->d_name[0] == '.' && - (d->d_name[1] == '\0' || - (d->d_name[1] == '.' && d->d_name[2] == '\0'))) -@@ -303,48 +314,38 @@ __getcwd (char *buf, size_t size) - break; - } - } -- if (d == NULL) -- { -- if (errno == 0) -- /* EOF on dirstream, which means that the current directory -- has been removed. */ -- __set_errno (ENOENT); -- goto lose; -- } -- else -- { -- size_t dirroom = dirp - dir; -- size_t namlen = _D_EXACT_NAMLEN (d); - -- if (dirroom <= namlen) -+ dirroom = dirp - dir; -+ namlen = _D_EXACT_NAMLEN (d); -+ -+ if (dirroom <= namlen) -+ { -+ if (size != 0) - { -- if (size != 0) -- { -- __set_errno (ERANGE); -- goto lose; -- } -- else -- { -- char *tmp; -- size_t oldsize = allocated; -+ __set_errno (ERANGE); -+ goto lose; -+ } -+ else -+ { -+ char *tmp; -+ size_t oldsize = allocated; - -- allocated += MAX (allocated, namlen); -- if (allocated < oldsize -- || ! (tmp = realloc (dir, allocated))) -- goto memory_exhausted; -+ allocated += MAX (allocated, namlen); -+ if (allocated < oldsize -+ || ! (tmp = realloc (dir, allocated))) -+ goto memory_exhausted; - -- /* Move current contents up to the end of the buffer. -- This is guaranteed to be non-overlapping. */ -- dirp = memcpy (tmp + allocated - (oldsize - dirroom), -- tmp + dirroom, -- oldsize - dirroom); -- dir = tmp; -- } -+ /* Move current contents up to the end of the buffer. -+ This is guaranteed to be non-overlapping. */ -+ dirp = memcpy (tmp + allocated - (oldsize - dirroom), -+ tmp + dirroom, -+ oldsize - dirroom); -+ dir = tmp; - } -- dirp -= namlen; -- memcpy (dirp, d->d_name, namlen); -- *--dirp = '/'; - } -+ dirp -= namlen; -+ memcpy (dirp, d->d_name, namlen); -+ *--dirp = '/'; - - thisdev = dotdev; - thisino = dotino; diff --git a/pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch b/pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch deleted file mode 100644 index da68c3b4351d9..0000000000000 --- a/pkgs/by-name/cv/cvs/patches/0001-getcwd-chroot.patch +++ /dev/null @@ -1,172 +0,0 @@ -# From Gnulib: -# http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=79c0a43808d9ca85acd04600149fc1a9b75bd1b9 -# -# 2006-07-03 Paul Eggert -# -# Merge from coreutils. -# -# 2006-03-19 Jim Meyering -# -# Work even in a chroot where d_ino values for entries in "/" -# don't match the stat.st_ino values for the same names. -# * getcwd.c (__getcwd): When no d_ino value matches the target inode -# number, iterate through all entries again, using lstat instead. -# Reported by Kenshi Muto in http://bugs.debian.org/355810, and by -# Zouhir Hafidi in https://bugzilla.redhat.com/bugzilla/190656. -# -# * getcwd.c (__getcwd): Clarify a comment. -# Use memcpy in place of a call to strcpy. - ---- cvs-1.12.13-old/lib/getcwd.c -+++ cvs-1.12.13/lib/getcwd.c -@@ -211,6 +211,7 @@ __getcwd (char *buf, size_t size) - int parent_status; - size_t dirroom; - size_t namlen; -+ bool use_d_ino = true; - - /* Look at the parent directory. */ - #ifdef AT_FDCWD -@@ -257,11 +258,26 @@ __getcwd (char *buf, size_t size) - NULL. */ - __set_errno (0); - d = __readdir (dirstream); -+ -+ /* When we've iterated through all directory entries without finding -+ one with a matching d_ino, rewind the stream and consider each -+ name again, but this time, using lstat. This is necessary in a -+ chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where -+ .., ../.., ../../.., etc. all had the same device number, yet the -+ d_ino values for entries in / did not match those obtained -+ via lstat. */ -+ if (d == NULL && errno == 0 && use_d_ino) -+ { -+ use_d_ino = false; -+ rewinddir (dirstream); -+ d = __readdir (dirstream); -+ } -+ - if (d == NULL) - { - if (errno == 0) -- /* EOF on dirstream, which means that the current directory -- has been removed. */ -+ /* EOF on dirstream, which can mean e.g., that the current -+ directory has been removed. */ - __set_errno (ENOENT); - goto lose; - } -@@ -269,58 +285,65 @@ __getcwd (char *buf, size_t size) - (d->d_name[1] == '\0' || - (d->d_name[1] == '.' && d->d_name[2] == '\0'))) - continue; -- if (MATCHING_INO (d, thisino) || mount_point) -+ -+ if (use_d_ino) - { -- int entry_status; -+ bool match = (MATCHING_INO (d, thisino) || mount_point); -+ if (! match) -+ continue; -+ } -+ -+ { -+ int entry_status; - #ifdef AT_FDCWD -- entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); -+ entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); - #else -- /* Compute size needed for this file name, or for the file -- name ".." in the same directory, whichever is larger. -- Room for ".." might be needed the next time through -- the outer loop. */ -- size_t name_alloc = _D_ALLOC_NAMLEN (d); -- size_t filesize = dotlen + MAX (sizeof "..", name_alloc); -- -- if (filesize < dotlen) -- goto memory_exhausted; -- -- if (dotsize < filesize) -- { -- /* My, what a deep directory tree you have, Grandma. */ -- size_t newsize = MAX (filesize, dotsize * 2); -- size_t i; -- if (newsize < dotsize) -- goto memory_exhausted; -- if (dotlist != dots) -- free (dotlist); -- dotlist = malloc (newsize); -- if (dotlist == NULL) -- goto lose; -- dotsize = newsize; -- -- i = 0; -- do -- { -- dotlist[i++] = '.'; -- dotlist[i++] = '.'; -- dotlist[i++] = '/'; -- } -- while (i < dotlen); -- } -- -- strcpy (dotlist + dotlen, d->d_name); -- entry_status = __lstat (dotlist, &st); -+ /* Compute size needed for this file name, or for the file -+ name ".." in the same directory, whichever is larger. -+ Room for ".." might be needed the next time through -+ the outer loop. */ -+ size_t name_alloc = _D_ALLOC_NAMLEN (d); -+ size_t filesize = dotlen + MAX (sizeof "..", name_alloc); -+ -+ if (filesize < dotlen) -+ goto memory_exhausted; -+ -+ if (dotsize < filesize) -+ { -+ /* My, what a deep directory tree you have, Grandma. */ -+ size_t newsize = MAX (filesize, dotsize * 2); -+ size_t i; -+ if (newsize < dotsize) -+ goto memory_exhausted; -+ if (dotlist != dots) -+ free (dotlist); -+ dotlist = malloc (newsize); -+ if (dotlist == NULL) -+ goto lose; -+ dotsize = newsize; -+ -+ i = 0; -+ do -+ { -+ dotlist[i++] = '.'; -+ dotlist[i++] = '.'; -+ dotlist[i++] = '/'; -+ } -+ while (i < dotlen); -+ } -+ -+ memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d)); -+ entry_status = __lstat (dotlist, &st); - #endif -- /* We don't fail here if we cannot stat() a directory entry. -- This can happen when (network) file systems fail. If this -- entry is in fact the one we are looking for we will find -- out soon as we reach the end of the directory without -- having found anything. */ -- if (entry_status == 0 && S_ISDIR (st.st_mode) -- && st.st_dev == thisdev && st.st_ino == thisino) -- break; -- } -+ /* We don't fail here if we cannot stat() a directory entry. -+ This can happen when (network) file systems fail. If this -+ entry is in fact the one we are looking for we will find -+ out soon as we reach the end of the directory without -+ having found anything. */ -+ if (entry_status == 0 && S_ISDIR (st.st_mode) -+ && st.st_dev == thisdev && st.st_ino == thisino) -+ break; -+ } - } - - dirroom = dirp - dir; From eaaddd4141ab8795c75744dbb96d724587f6505d Mon Sep 17 00:00:00 2001 From: Anderson Torres Date: Thu, 10 Oct 2024 12:34:02 -0300 Subject: [PATCH 4/4] cvs: new options ___forceSSH and ___withEditor Co-authored-by: Joshua baker --- pkgs/by-name/cv/cvs/package.nix | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/cv/cvs/package.nix b/pkgs/by-name/cv/cvs/package.nix index 35c47b44d150b..742449f1d5b29 100644 --- a/pkgs/by-name/cv/cvs/package.nix +++ b/pkgs/by-name/cv/cvs/package.nix @@ -3,7 +3,11 @@ fetchpatch2, fetchurl, nano, + openssh, stdenv, + # Boolean flags + ___forceSSH ? true, # Sets SSH (openssh) as the remote shell + ___withEditor ? true, # Sets the default editor (nano) }: stdenv.mkDerivation (finalAttrs: { @@ -46,8 +50,8 @@ stdenv.mkDerivation (finalAttrs: { ]; configureFlags = [ - "--with-editor=${nano}/bin/nano" - + (lib.withFeatureAs ___forceSSH "rsh" (lib.getExe openssh)) + (lib.withFeatureAs ___withEditor "editor" (lib.getExe nano)) # Required for cross-compilation. "cvs_cv_func_printf_ptr=yes" ];