From a8edcf8fa34b1d6c0fab77e0062d84d910205560 Mon Sep 17 00:00:00 2001 From: cenhuilin Date: Thu, 21 Mar 2024 15:18:43 +0800 Subject: [PATCH] fix scrub stopped working for links pointing to a block device (cherry picked from commit bd0c59a4f47e8883a25cf0560b82d45fd6a73d7c) --- scrub.spec | 7 +- symlinks-to-block-device.patch | 125 +++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 symlinks-to-block-device.patch diff --git a/scrub.spec b/scrub.spec index 7b0cf3c..783fb08 100644 --- a/scrub.spec +++ b/scrub.spec @@ -1,6 +1,6 @@ Name: scrub Version: 2.6.1 -Release: 3 +Release: 4 Summary: A disk overwrite utility License: GPLv2+ URL: https://github.com/chaos/scrub @@ -9,6 +9,8 @@ Source0: http://github.com/chaos/scrub/releases/download/2.6.1/scrub-2.6. Patch0: usage-Exit-with-status-code-0-for-help.patch # https://github.com/chaos/scrub/commit/bd88864d8ee15a65d5ecdb3818afa4d5193d2455 Patch1: usage-Output-to-stdout-on-exit-code-0.patch +# https://github.com/chaos/scrub/commit/499a491c21b5a18be79334282dfa11fd4f408c49 +Patch2: symlinks-to-block-device.patch BuildRequires: gettext, gcc @@ -38,6 +40,9 @@ retrieving the data more difficult. It operates in one of three modes: %{_mandir}/man1/scrub.1* %changelog +* Thu Mar 21 2024 cenhuilin - 2.6.1-4 +- fix scrub stopped working for links pointing to a block device + * Tue Jan 30 2024 yaoxin - 2.6.1-3 - Fix exit with status code 0 for --help diff --git a/symlinks-to-block-device.patch b/symlinks-to-block-device.patch new file mode 100644 index 0000000..0d908cf --- /dev/null +++ b/symlinks-to-block-device.patch @@ -0,0 +1,125 @@ +From e3382e63b9d30b9c56b000fbfbb2edb2e4319ee7 Mon Sep 17 00:00:00 2001 +From: Sergio Correia +Date: Thu, 21 Mar 2024 14:52:41 +0800 +Subject: [PATCH] scrub should work for symlinks pointing to block devices + +In [1] (add -L option to avoid scrubbing symlink target [Tim +Boronczyk]), scrub introduced a -L (--no-link) option so that it would +not scrub the target, if it was a link and this new option was set. + +A side-effect of that change is that scrub stopped working for links +pointing to a block device, whereas it would still work for links +pointing to regular files -- it is not clear from the commit changelog +and the added documentation for this new option that this was an +intended change. + +In this commit we fix this regression, and scrub works again for links +pointing to block devices. -L/--no-link option also works for these +links. + +[1] https://github.com/chaos/scrub/commit/01915c442288b4b274261fa07e42e116fb9d6b60 +--- + src/scrub.c | 13 ++++++++----- + src/util.c | 13 +++++++++---- + src/util.h | 2 +- + 3 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/src/scrub.c b/src/scrub.c +index 08389d8..22f18d0 100644 +--- a/src/scrub.c ++++ b/src/scrub.c +@@ -329,6 +329,10 @@ static int scrub_object(char *filename, const struct opt_struct *opt, + fprintf(stderr, "%s: %s already scrubbed? (-f to force)\n", + prog, filename); + errcount++; ++ } else if (is_symlink(filename) && opt->nofollow) { ++ fprintf(stderr, "%s: skipping symlink %s because --no-link (-L) option was set\n", ++ prog, filename); ++ errcount++; + } else if (!noexec) { + if (dryrun) { + printf("%s: (dryrun) scrub special file %s\n", +@@ -338,8 +342,8 @@ static int scrub_object(char *filename, const struct opt_struct *opt, + } + } + break; +- case FILE_LINK: +- if (opt->nofollow) { ++ case FILE_REGULAR: ++ if (is_symlink(filename) && opt->nofollow) { + if (opt->remove && !noexec) { + if (dryrun) { + printf("%s: (dryrun) unlink %s\n", prog, filename); +@@ -354,8 +358,7 @@ static int scrub_object(char *filename, const struct opt_struct *opt, + } + break; + } +- /* FALL THRU */ +- case FILE_REGULAR: ++ + if (access(filename, R_OK|W_OK) < 0) { + fprintf(stderr, "%s: no rw access to %s\n", prog, filename); + errcount++; +@@ -656,7 +659,7 @@ scrub_file(char *path, const struct opt_struct *opt) + filetype_t ftype = filetype(path); + off_t size = opt->devsize; + +- assert(ftype == FILE_REGULAR || ftype == FILE_LINK); ++ assert(ftype == FILE_REGULAR); + + if (stat(path, &sb) < 0) { + fprintf(stderr, "%s: stat %s: %s\n", prog, path, strerror(errno)); +diff --git a/src/util.c b/src/util.c +index 96dd59b..fb85368 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -71,6 +71,15 @@ write_all(int fd, const unsigned char *buf, int count) + return n; + } + ++/* Indicates whether the file represented by 'path' is a symlink. ++ */ ++int ++is_symlink(char *path) ++{ ++ struct stat sb; ++ return lstat(path, &sb) == 0 && S_ISLNK(sb.st_mode); ++} ++ + /* Return the type of file represented by 'path'. + */ + filetype_t +@@ -80,10 +89,6 @@ filetype(char *path) + + filetype_t res = FILE_NOEXIST; + +- if (lstat(path, &sb) == 0 && S_ISLNK(sb.st_mode)) { +- return FILE_LINK; +- } +- + if (stat(path, &sb) == 0) { + if (S_ISREG(sb.st_mode)) + res = FILE_REGULAR; +diff --git a/src/util.h b/src/util.h +index a409f2b..7beff4d 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -9,7 +9,6 @@ typedef enum { + FILE_REGULAR, + FILE_CHAR, + FILE_BLOCK, +- FILE_LINK, + FILE_OTHER, + } filetype_t; + +@@ -17,6 +16,7 @@ typedef enum { UP, DOWN } round_t; + + int read_all(int fd, unsigned char *buf, int count); + int write_all(int fd, const unsigned char *buf, int count); ++int is_symlink(char *path); + filetype_t filetype(char *path); + off_t blkalign(off_t offset, int blocksize, round_t rtype); + void * alloc_buffer(int bufsize); +-- +2.27.0 +