Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package dd_rescue for openSUSE:Factory 
checked in at 2025-03-15 16:15:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dd_rescue (Old)
 and      /work/SRC/openSUSE:Factory/.dd_rescue.new.19136 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dd_rescue"

Sat Mar 15 16:15:10 2025 rev:66 rq:1253156 version:1.99.21

Changes:
--------
--- /work/SRC/openSUSE:Factory/dd_rescue/dd_rescue.changes      2025-01-28 
14:58:05.403348756 +0100
+++ /work/SRC/openSUSE:Factory/.dd_rescue.new.19136/dd_rescue.changes   
2025-03-15 16:15:22.190275928 +0100
@@ -1,0 +2,13 @@
+Fri Mar 14 18:25:52 CET 2025 - k...@garloff.de
+
+- Update to dd_rescue-1.99.21:
+  * New option -H to inject interrupted and short IO calls for
+    testing.
+  * Fix handling of receiving short reads after EINTR/EAGAIN.
+  * Fix handling of short writes and EINTR/EAGAIN.
+  * When several retries happened in real_writeblock(), we would
+    corrupt the stack by increasing pointer rather than the
+    variable pointed to. (This was reported by Sam James and
+    analyzed with -fsanitizer.)
+
+-------------------------------------------------------------------

Old:
----
  dd_rescue-1.99.20.tar.bz2
  dd_rescue-1.99.20.tar.bz2.asc

New:
----
  dd_rescue-1.99.21.tar.bz2
  dd_rescue-1.99.21.tar.bz2.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dd_rescue.spec ++++++
--- /var/tmp/diff_new_pack.nVibmA/_old  2025-03-15 16:15:23.650337187 +0100
+++ /var/tmp/diff_new_pack.nVibmA/_new  2025-03-15 16:15:23.650337187 +0100
@@ -21,7 +21,7 @@
 %define _lto_cflags %{nil}
 %endif
 Name:           dd_rescue
-Version:        1.99.20
+Version:        1.99.21
 Release:        0
 Summary:        Data copying in the presence of I/O Errors
 License:        GPL-2.0-only OR GPL-3.0-only

++++++ dd_rescue-1.99.20.tar.bz2 -> dd_rescue-1.99.21.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/Makefile 
new/dd_rescue-1.99.21/Makefile
--- old/dd_rescue-1.99.20/Makefile      2025-01-20 09:03:41.692897770 +0100
+++ new/dd_rescue-1.99.21/Makefile      2025-03-14 17:40:10.516737617 +0100
@@ -1,7 +1,7 @@
 # (c) garl...@suse.de, 99/10/09, GNU GPL
 # (c) k...@garloff.de, 2010 -- 2021, GNU GPL v2 or v3
 
-VERSION = 1.99.20
+VERSION = 1.99.21
 
 DESTDIR = 
 SRCDIR ?= .
@@ -38,7 +38,7 @@
 LIBDIR = /usr/$(LIB)
 COMPILER = $(shell $(CC) --version | head -n1)
 ID = $(shell git describe --tags || cat REL-ID)
-DEFINES = -DVERSION=\"$(VERSION)\"  -D__COMPILER__="\"$(COMPILER)\"" 
-DID=\"$(ID)\" # -DPLUGSEARCH="\"$(LIBDIR)\""
+DEFINES = -DIO_HAVOC=1 -DVERSION=\"$(VERSION)\"  
-D__COMPILER__="\"$(COMPILER)\"" -DID=\"$(ID)\" # -DPLUGSEARCH="\"$(LIBDIR)\""
 OUT = -o dd_rescue
 PIC = -fPIC
 PIE = -fPIE
@@ -261,7 +261,7 @@
 # Automated dependency generation
 .dep: $(SRCDIR)/Makefile config.h $(SRCDIR)/*.h $(SRCDIR)/*.c
        #$(CC) $(CFLAGS) -DGEN_DEP $(ARCHFLAGS) -MM $(SRCDIR)/*.c >.dep
-       $(CC) $(CFLAGS) -DGEN_DEP $(DEP_SSE) -I . -MM $(SRCDIR)/*.c >.dep
+       $(CC) $(CFLAGS) -DGEN_DEP $(DEP_SSE) -I . -I $(SRCDIR) -MM 
$(SRCDIR)/*.c >.dep
        sed 's/\.o:/\.po:/' <.dep >.dep2
        cat .dep2 >> .dep
        rm .dep2
@@ -273,10 +273,10 @@
        make .dep
 
 # These need optimization
-archdep.o: $(SRCDIR)/archdep.c archdep.h config.h
+archdep.o: $(SRCDIR)/archdep.c $(SRCDIR)/archdep.h config.h
        $(CC) $(CFLAGS_OPT) $(ARCHFLAGS) $(PIE) -c $<
 
-archdep.po: $(SRCDIR)/archdep.c archdep.h config.h
+archdep.po: $(SRCDIR)/archdep.c $(SRCDIR)/archdep.h config.h
        $(CC) $(CFLAGS_OPT) $(ARCHFLAGS) $(PIC) -c $<
 
 frandom.o: $(SRCDIR)/frandom.c config.h
@@ -436,7 +436,7 @@
        $(CC) $(CFLAGS_OPT) $(PIE) $(LDPIE) -DSHA1_MAIN -o $@ $<
 
 fuzz_lzo: fuzz_lzo.o
-       $(CC) -o $@ $(LDPIE) $^ -llzo2
+       $(CC) -o $@ $(CFLAGS) $(LDPIE) $^ -llzo2
 
 # More dd_rescue variants
 libfalloc-dl: dd_rescue
@@ -476,6 +476,9 @@
 pbkdf2: $(SRCDIR)/ossl_pbkdf2.c
        $(CC) $(CFLAGS) $(PIE) $(LDPIE) -o $@ $< $(CRYPTOLIB)
 
+test_aligned_alloc: $(SRCDIR)/test_aligned_alloc.c
+       $(CC) $(CFLAGS) $(PIE) $(LDPIE) -o $@ $<
+
 test_aes: $(SRCDIR)/test_aes.c $(AESNI_O) $(AES_ARM64_O) aes_c.o secmem.o 
sha256.o $(SHAOBJ) archdep.o $(AES_OSSL_O) aes.o $(SRCDIR)/aesni.h 
$(SRCDIR)/aes_arm64.h config.h $(OBJECTS2)
        $(CC) $(CFLAGS) $(PIE) $(LDPIE) $(DEF) -o $@ $< $(AESNI_O) 
$(AES_ARM64_O) aes_c.o secmem.o sha256.o $(SHAOBJ) $(AES_OSSL_O) aes.o 
archdep.o $(OBJECTS2) $(CRYPTOLIB)
 
@@ -752,28 +755,28 @@
 
 check_sparse: $(TARGETS)
        @echo "***** dd_rescue sparse tests with plugins *****"
-       ./test_sparse.sh
-       ./test_sparse.sh "-L ./libddr_null.so=unsparse"
-       ./test_sparse.sh "-L ./libddr_hash.so=sha256"
-       ./test_sparse.sh "-L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:skiphole:" "encrypt" 
"decrypt"
-       ./test_sparse.sh "-L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:" "encrypt" "decrypt"
-       if test $(HAVE_LZO) = 1; then ./test_sparse.sh "-L ./libddr_lzo.so=" 
"compress" "decompress"; fi
-       if test $(HAVE_LZMA) = 1; then ./test_sparse.sh "-L ./libddr_lzma.so=" 
"compress" "decompress"; fi
+       ./test_sparse.sh "-H 15"
+       ./test_sparse.sh "-H 15 -L ./libddr_null.so=unsparse"
+       ./test_sparse.sh "-H 15 -L ./libddr_hash.so=sha256"
+       ./test_sparse.sh "-H 15 -L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:skiphole:" "encrypt" 
"decrypt"
+       ./test_sparse.sh "-H 15 -L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:" "encrypt" "decrypt"
+       if test $(HAVE_LZO) = 1; then ./test_sparse.sh "-H 15 -L 
./libddr_lzo.so=" "compress" "decompress"; fi
+       if test $(HAVE_LZMA) = 1; then ./test_sparse.sh "-H 15 -L 
./libddr_lzma.so=" "compress" "decompress"; fi
        # Sparse files with odd sizes
-       ./test_sparse.sh "-L ./libddr_null.so=unsparse" "" "" 8388612
-       ./test_sparse.sh "-L ./libddr_hash.so=sha256" "" "" 8388612
-       ./test_sparse.sh "-L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:skiphole:" "encrypt" 
"decrypt" 8388612
-       ./test_sparse.sh "-L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:" "encrypt" "decrypt" 
8388612
-       if test $(HAVE_LZO) = 1; then ./test_sparse.sh "-L ./libddr_lzo.so=" 
"compress" "decompress" 8388612; fi
-       if test $(HAVE_LZMA) = 1; then ./test_sparse.sh "-L ./libddr_lzma.so=" 
"compress" "decompress" 8388612; fi
+       ./test_sparse.sh "-H 15 -L ./libddr_null.so=unsparse" "" "" 8388612
+       ./test_sparse.sh "-H 15 -L ./libddr_hash.so=sha256" "" "" 8388612
+       ./test_sparse.sh "-H 15 -L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:skiphole:" "encrypt" 
"decrypt" 8388612
+       ./test_sparse.sh "-H 15 -L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:" "encrypt" "decrypt" 
8388612
+       if test $(HAVE_LZO) = 1; then ./test_sparse.sh "-H 15 -L 
./libddr_lzo.so=" "compress" "decompress" 8388612; fi
+       if test $(HAVE_LZMA) = 1; then ./test_sparse.sh "-H 15 -L 
./libddr_lzma.so=" "compress" "decompress" 8388612; fi
        # Sparse files with holes at end and at beginning
-       ./test_sparse.sh "" "" "" 7596032 1
-       ./test_sparse.sh "-L ./libddr_null.so=unsparse" "" "" 7596032 1
-       ./test_sparse.sh "-L ./libddr_hash.so=sha256" "" "" 7596032 1
-       ./test_sparse.sh "-L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:skiphole:" "encrypt" 
"decrypt" 7596032 1
-       ./test_sparse.sh "-L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:" "encrypt" "decrypt" 
7596032 1
-       if test $(HAVE_LZO) = 1; then ./test_sparse.sh "-L ./libddr_lzo.so=" 
"compress" "decompress" 7596032 1; fi
-       if test $(HAVE_LZMA) = 1; then ./test_sparse.sh "-L ./libddr_lzma.so=" 
"compress" "decompress" 7596032 1; fi
+       ./test_sparse.sh "-H 15 " "" "" 7596032 1
+       ./test_sparse.sh "-H 15 -L ./libddr_null.so=unsparse" "" "" 7596032 1
+       ./test_sparse.sh "-H 15 -L ./libddr_hash.so=sha256" "" "" 7596032 1
+       ./test_sparse.sh "-H 15 -L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:skiphole:" "encrypt" 
"decrypt" 7596032 1
+       ./test_sparse.sh "-H 15 -L 
./libddr_crypt.so=AES192-CTR:weakrnd:pbkdf2:pass=ABC:" "encrypt" "decrypt" 
7596032 1
+       if test $(HAVE_LZO) = 1; then ./test_sparse.sh "-H 15 -L 
./libddr_lzo.so=" "compress" "decompress" 7596032 1; fi
+       if test $(HAVE_LZMA) = 1; then ./test_sparse.sh "-H 15 -L 
./libddr_lzma.so=" "compress" "decompress" 7596032 1; fi
        if test $(HAVE_LZO) = 1; then ./test_sparse_compress_crypt.sh; fi
        if test $(HAVE_LZMA) = 1; then ./test_sparse_compress_crypt.sh lzma; fi
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/README.dd_rescue 
new/dd_rescue-1.99.21/README.dd_rescue
--- old/dd_rescue-1.99.20/README.dd_rescue      2025-01-19 20:49:32.167108800 
+0100
+++ new/dd_rescue-1.99.21/README.dd_rescue      2025-03-14 17:40:10.520737718 
+0100
@@ -234,6 +234,8 @@
 * Double -p makes failure to copy ownership/perms/times/xattrs reported in
   exit code. Failure on copying ownership/perms will error out early (to avoid
   exposing sensitive data).
+* 1.99.21 was made safe against interrupted and short read/write calls and
+  the option -H allows to test for this. (This only worked partically before.)
 
 
 Copyright
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/REL-ID new/dd_rescue-1.99.21/REL-ID
--- old/dd_rescue-1.99.20/REL-ID        2025-01-20 15:43:43.340943216 +0100
+++ new/dd_rescue-1.99.21/REL-ID        2025-03-14 17:51:28.621171757 +0100
@@ -1 +1 @@
-DD_RESCUE_1_99_20
+DD_RESCUE_1_99_21
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/dd_rescue.1 
new/dd_rescue-1.99.21/dd_rescue.1
--- old/dd_rescue-1.99.20/dd_rescue.1   2025-01-19 20:54:07.157626133 +0100
+++ new/dd_rescue-1.99.21/dd_rescue.1   2025-03-14 17:40:10.520737718 +0100
@@ -887,7 +887,18 @@
 the middle of a file with -s or reverse copying won't affect the absolute
 position that is hit with the fault injection. (This has changed since
 1.98.)
-
+.br
+The option
+.B -H percent
+on the command line will cause read and write havoc by returning short
+reads and writes and by returning an indication that a read or write
+has to be redone as the system call was interrupted or would block.
+The percentage given will be evenly split between interrupted calls
+and short reads/writes. According to the GNU libc documentation, such
+things can happen; the fact they only do happen seldomly and only under
+certain circumstances makes it hard to test, thus this option to force
+it to randomly happen. (This has led to bug fixes in 1.99.21.)
+.br
 .SH BUGS/LIMITATIONS
 The source code does use the 64bit functions provided by glibc for file
 positioning. However, your kernel might not support it, so you might be
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/dd_rescue.c 
new/dd_rescue-1.99.21/dd_rescue.c
--- old/dd_rescue-1.99.20/dd_rescue.c   2025-01-20 15:38:27.925465127 +0100
+++ new/dd_rescue-1.99.21/dd_rescue.c   2025-03-14 17:40:10.524737818 +0100
@@ -200,6 +200,8 @@
 #include "pread64.h"
 #endif
 
+#include "iohavoc.h"
+
 #define MIN(a,b) ((a)<(b)? (a): (b))
 
 #if __WORDSIZE == 64
@@ -1767,7 +1769,7 @@
        if (fst->i_chr)
                rd = read(fd, bf, sz);
        else
-               rd = pread64(fd, bf, sz, off);
+               rd = PREAD64(fd, bf, sz, off);
        if (rd == (ssize_t)-1 && !op->reverse && fst->fin_ipos && fst->ipos == 
fst->fin_ipos) {
                errno = 0;
                return 0;
@@ -1804,15 +1806,15 @@
                if (op->avoidwrite) {
                        ssize_t ln = pread64(fd, fst->buf2, sz, off);
                        if (ln < (ssize_t)sz)
-                               return pwrite64(fd, bf, sz, off);
+                               return PWRITE64(fd, bf, sz, off);
                        if (memcmp(bf, fst->buf2, ln))
-                               return pwrite64(fd, bf, sz, off);
+                               return PWRITE64(fd, bf, sz, off);
                        else {
                                prg->axfer += ln;
                                return ln;
                        }
                } else
-                       return pwrite64(fd, bf, sz, off);
+                       return PWRITE64(fd, bf, sz, off);
        }
 }
 
@@ -1822,14 +1824,18 @@
                  dpopt_t *dop, dpstate_t *dst)
 {
        ssize_t err, rd = 0;
-       //errno = 0; /* should not be necessary */
        do {
+               //errno = 0; /* should not be necessary */
                rd += (err = mypread(fst->ides, fst->buf+rd, toread-rd, 
fst->ipos+rd-op->reverse*toread, op, fst, rep, dop, dst));
-               if (err == -1) 
-                       rd++;
+               if (err == -1)
+                       ++rd;
        } while ((err == -1 && (errno == EINTR || errno == EAGAIN))
-                 || (rd < toread && err > 0 && errno == 0));
+                 || (rd < toread && err > 0 && (errno == 0 || errno == EINTR 
|| errno == EAGAIN)));
        //if (rd < toread) memset (fst->buf+rd, 0, toread-rd);
+       //if (rd < toread)
+       //      fplog(stderr, WARN, "Short read %li/%li\n", rd, toread);
+       if (errno == EINTR || errno == EAGAIN)
+               errno = 0;
        return (/*err == -1? err:*/ rd);
 }
 
@@ -1851,9 +1857,12 @@
                                      fst->opos+wr-op->reverse*towrite, op, 
fst, prg));
                if (err == -1)
                        wr++;
-       } while ((err == -1 && (errno == EINTR || errno == EAGAIN || !*retry++))
-             || (err > 0 && errno == 0 && wr < towrite)
-             || (err == 0 && !*retry++));
+               if (!err)
+                       sched_yield();
+       } while ((err == -1 && (errno == EINTR || errno == EAGAIN))
+             || (err >= 0 && (errno == 0 || errno == EINTR || errno == EAGAIN) 
&& wr < towrite &&!*retry));
+       if (errno == EINTR || errno == EAGAIN)
+               errno = 0;
 
        if (wr < towrite && err != 0) {
                /* HANDLE write errors here ... */
@@ -1916,7 +1925,7 @@
                        if (e2 == -1)
                                w2++;
                } while ((e2 == -1 && (errno == EINTR || errno == EAGAIN))
-                         || (w2 < towrite && e2 > 0 && errno == 0));
+                         || (w2 < towrite && e2 >= 0 && (errno == 0 || errno 
== EINTR || errno == EAGAIN)));
                if (w2 < towrite && e2 != 0)
                        fplog(stderr, WARN, "2ndary write %s (%skiB): %s\n",
                              oft->name, fmt_kiB(fst->opos, !nocol), 
strerror(errno));
@@ -2840,7 +2849,7 @@
                                {"shred3", 1, NULL, '3'}, {"shred4", 1, NULL, 
'4'},
                                {"shred2", 1, NULL, '2'},
                                {"rmvtrim", 0, NULL, 'u'}, {"plugins", 1, NULL, 
'L'},
-                               {"fault", 1, NULL, 'F'},
+                               {"fault", 1, NULL, 'F'}, {"havoc", 1, NULL, 
'H'},
                                /* GNU ddrescue compat */
                                {"block-size", 1, NULL, 'B'}, 
{"input-position", 1, NULL, 's'},
                                {"output-position", 1, NULL, 'S'}, {"max-size", 
1, NULL, 'm'},
@@ -2897,6 +2906,7 @@
        fprintf(stderr, "         -C limit   rateControl: avoid xfer data 
faster than limit B/s\n");
        fprintf(stderr, "         -Y oname   Secondary output file (multiple 
possible),\n");
        fprintf(stderr, "         -F off[-off]r/rep[,off[-off]w/rep[,...]]  
fault injection (hardbs off) r/w\n");
+       fprintf(stderr, "         -H pct     Inject pct percent EINTR/EAGAIN 
and short reads/writes\n");
        fprintf(stderr, "         -q         quiet operation,\n");
        fprintf(stderr, "         -v         verbose operation,\n");
        fprintf(stderr, "         -E loglv   set plugin loglevel (0 = verbose, 
2 = default, 5 = quiet, max 6),\n");
@@ -2966,6 +2976,12 @@
        }
 }
 
+void ignoredsignal(int sig)
+{
+       fplog(stderr, WARN, "Caught signal %i \"%s\". Ignore ...\n",
+             sig, strsignal(sig));
+}
+
 unsigned char* zalloc_aligned_buf(unsigned int bs, unsigned char**obuf)
 {
        unsigned char *ptr = 0;
@@ -3149,11 +3165,13 @@
        ofiles = NULL;
 
        int tmpfd = 0;
+       int pct;
+       IOHAVOC_INIT(0, 0, 0);
 
 #ifdef LACK_GETOPT_LONG
-       while ((c = getopt(argc, argv, 
":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:")) != -1)
+       while ((c = getopt(argc, argv, 
":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:H:")) != -1)
 #else
-       while ((c = getopt_long(argc, argv, 
":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:", longopts, 
NULL)) != -1)
+       while ((c = getopt_long(argc, argv, 
":rtTfihqvVwWaAdDkMRpPuc:b:B:m:e:s:S:l:L:o:y:z:Z:2:3:4:xY:F:C:E:H:", longopts, 
NULL)) != -1)
 #endif
        {
                switch (c) {
@@ -3204,6 +3222,7 @@
                        case 'x': op->extend = 1; break;
                        case 'u': op->rmvtrim = 1; break;
                        case 'F': populate_faultlists(optarg, op); break;
+                       case 'H': pct = atoi(optarg); IOHAVOC_INIT(1, pct, 
pct); break;
                        case 'Y': do { ofile_t of; of.name = optarg; of.fd = 
-1; of.cdev = 0; LISTAPPEND(ofiles, of, ofile_t); } while (0); break;
                        case 'z': dop->prng_libc = 1; if (is_filename(optarg)) 
dop->prng_sfile = optarg; else dop->prng_seed = readint(optarg, 0); break;
                        case 'Z': dop->prng_frnd = 1; if (is_filename(optarg)) 
dop->prng_sfile = optarg; else dop->prng_seed = readint(optarg, 0); break;
@@ -3587,6 +3606,8 @@
        static repeat_t _repeat;
        repeat_t *repeat = &_repeat;
 
+       char* iohavoc_report;
+
        /* Initialize: static vars should be zeroed, but better safe than sorry 
*/
        memset(dpstate, 0, sizeof(dpstate_t));
        memset(fstate, 0, sizeof(fstate_t));
@@ -3690,6 +3711,7 @@
        signal(SIGTERM, breakhandler);
        /* Used to signal clean abort from plugins */
        signal(SIGQUIT, breakhandler);
+       signal(SIGWINCH, ignoredsignal);
 
        /* Save time and start to work */
        fstate->ipos = opts->init_ipos;
@@ -3728,6 +3750,9 @@
        printreport(opts, fstate, progress, dpopts);
        fadvise(1, opts, fstate, progress);
        err += cleanup(0);
+       iohavoc_report = IOHAVOC_REPORT();
+       if (iohavoc_report)
+               fplog(stderr, INFO, "%s", iohavoc_report);
        if (int_by == SIGQUIT)
                ++err;
        if (err)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/iohavoc.h 
new/dd_rescue-1.99.21/iohavoc.h
--- old/dd_rescue-1.99.20/iohavoc.h     1970-01-01 01:00:00.000000000 +0100
+++ new/dd_rescue-1.99.21/iohavoc.h     2025-03-14 17:42:43.024528387 +0100
@@ -0,0 +1,186 @@
+/* iohavoc.h
+ *
+ * wrapper around read() and write() calls,
+ * deliberately injecting behavior like
+ * interrupted system calls returning with EINTR
+ * or EAGAIN and short reads/writes.
+ *
+ * These are things that can happen in real life
+ * according to glibc documentation, yet do happen
+ * only rarely and only under certain circumstances,
+ * which make robustness against these things hard
+ * to test.
+ * This collection of wrappers allow to inject such
+ * things, so we can test robustness.
+ *
+ * (c) Kurt Garloff <k...@garloff.de>, 3/2025
+ * SPDX-License-Identifier: LGPL-v2.1
+ */
+
+#ifndef _IOHAVOC_H
+#define _IOHAVOC_H
+
+//#define _FILE_OFFSET_BITS 64
+#include <random.h>
+#include <unistd.h>
+#include <errno.h>
+
+/* From GNU libc info pages
+ * 
+ * read() can return -1 with errno EAGAIN or EINTR, indicating that
+ *  it needs to be called again.
+ * read() can return only a subset of the requested bytes,
+ *  which means it needs to be called again for the rest.
+ * read() returning 0 (with a non-zero size param) means EOF.
+ * pread() and pread64() behave the same way.
+ *
+ * write() has the same behavior w.r.t. EAGAIN/EINTR and short
+ *  writes as read().
+ * write() returning 0 should be treated as short writes, not EOF.
+ * pwrite, pwrite64() behaves as write() does.
+ */
+
+#ifdef IO_HAVOC
+
+static int limit1, limit2;
+static long cnt_sh, cnt_in, cnt_reg;
+
+/* configure limits */
+static inline
+void iohavoc_init(int seed, char shortpct, char intrpct)
+{
+       if (!seed)
+               seed = time(0);
+       srand(seed);
+       assert(intrpct+shortpct <= 100);
+       /* We generate random numbers
+        * - If they are below limit1, we do short reads/writes
+        * - If they are below limit2 (but above limit1), we do EINTR/EAGAIN
+        * - Else (above limit2), we do normal reads/writes
+        */
+       limit1 = shortpct*(RAND_MAX/100);
+       limit2 = (shortpct+intrpct)*(RAND_MAX/100);
+       cnt_sh = 0; cnt_in = 0; cnt_reg = 0;
+}
+
+
+/* Call rand and determine action */
+static inline
+ssize_t io_determine(ssize_t sz)
+{
+       int rd = rand();
+       /* Full read/write */
+       if (rd >= limit2)
+               return sz;
+       /* EINTR/EAGAIN */
+       if (rd >= limit1)
+               return rd&1? -EINTR: -EAGAIN;
+       /* Short read/write */
+       ssize_t shortln = sz*rd/limit1;
+       return shortln - shortln%512;
+}
+
+
+#define IOWRAP3(fn, wr, fd, bf, sz)    \
+       ssize_t nsz = io_determine(sz); \
+       if (nsz < 0) {                  \
+               ++cnt_in;               \
+               errno = -nsz;           \
+               return -1;              \
+       }                               \
+       /* Avoid 0-sized read (EOF) */  \
+       if (!wr && !nsz)                \
+               nsz = sz;               \
+       if (nsz != sz)                  \
+               ++cnt_sh;               \
+       else                            \
+               ++cnt_reg;              \
+       /*errno = 0;*/                  \
+       return fn(fd, bf, nsz);
+
+#define IOWRAP4(fn, wr, fd, bf, sz, off)\
+       ssize_t nsz = io_determine(sz); \
+       if (nsz < 0) {                  \
+               ++cnt_in;               \
+               errno = -nsz;           \
+               return -1;              \
+       }                               \
+       /* Avoid 0-sized read (EOF) */  \
+       if (!wr && !nsz)                \
+               nsz = sz;               \
+       if (nsz != sz)                  \
+               ++cnt_sh;               \
+       else                            \
+               ++cnt_reg;              \
+       /*errno = 0;*/                  \
+       return fn(fd, bf, nsz, off);
+
+
+#define IOHAVOC_INIT(s, sh, in)        \
+       iohavoc_init(s, sh, in)
+
+static char _iohavoc_report[80];
+static inline char* IOHAVOC_REPORT()
+{
+       if (cnt_sh || cnt_in) {
+               snprintf(_iohavoc_report, 79, "iohavoc stats: %li regular 
calls, %li short, %li intr\n",
+                        cnt_reg, cnt_sh, cnt_in);
+               return _iohavoc_report;
+       }
+       return NULL;
+}
+
+/*
+static inline ssize_t READ(int fd, void *bf, size_t sz)
+{
+       IOWRAP3(read, 0, fd, bf, sz)
+}
+
+static inline ssize_t WRITE(int fd, void *bf, size_t sz)
+{
+       IOWRAP3(write, 1, fd, bf, sz)
+}
+*/
+
+static inline ssize_t PREAD64(int fd, void *bf, size_t sz, loff_t off)
+{
+       IOWRAP4(pread64, 0, fd, bf, sz, off)
+}
+
+static inline ssize_t PWRITE64(int fd, void *bf, size_t sz, loff_t off)
+{
+       IOWRAP4(pwrite64, 1, fd, bf, sz, off)
+}
+
+#else  /* IO_HAVOC */
+
+#define IOHAVOC_INIT(s, sh, in) \
+       do {} while(0)
+#define IOHAVOC_REPORT() NULL
+
+
+/*
+static inline ssize_t READ(int fd, void *bf, size_t sz)
+{
+       return read(fd, bf, sz);
+}
+
+static inline ssize_t WRITE(int fd, void *bf, size_t sz)
+{
+       return write(fd, bf, sz);
+}
+*/
+
+static inline ssize_t PREAD64(int fd, void *bf, size_t sz, loff_t off)
+{
+       return pread64(fd, bf, sz, off);
+}
+
+static inline ssize_t PWRITE64(int fd, void *bf, size_t sz, loff_t off)
+{
+       return pwrite64(fd, bf, sz, off);
+}
+
+#endif /* IO_HAVOC */
+
+#endif /* _IOHAVOC_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/libddr_crypt.c 
new/dd_rescue-1.99.21/libddr_crypt.c
--- old/dd_rescue-1.99.20/libddr_crypt.c        2025-01-19 18:03:32.932040623 
+0100
+++ new/dd_rescue-1.99.21/libddr_crypt.c        2025-02-16 19:49:11.559820366 
+0100
@@ -139,7 +139,7 @@
 int read_file(unsigned char*, const char*, uint maxlen);
 char* mystrncpy(unsigned char*, const char*, uint maxlen);
 int stripcrlf(char* str, uint maxlen);
-void whiteout(char* str, char quiet);
+void whiteout(char* str, char quiet, const char* opt);
 
 int set_flag(char* flg, const char* msg)
 {
@@ -299,7 +299,7 @@
                else if (!memcmp(param, "keyhex=", 7)) {
                        //err += parse_hex_u32((unsigned 
int*)state->sec->userkey1, param+7, state->alg->keylen/(8*sizeof(int))); 
                        err += parse_hex(state->sec->userkey1, param+7, 
state->alg->keylen/8); 
-                       whiteout(param+7, opt->quiet);
+                       whiteout(param+7, opt->quiet, "keyhex");
                        err += set_flag(&state->kset, "key");
                } else if (!memcmp(param, "keyfd=", 6)) {
                        err += read_fd(state->sec->userkey1, param+6, 32, 
"key");
@@ -314,7 +314,7 @@
                else if (!memcmp(param, "ivhex=", 6)) {
                        //err += parse_hex_u32((unsigned 
int*)state->sec->nonce1, param+6, BLKSZ/sizeof(int));
                        err += parse_hex(state->sec->nonce1, param+6, BLKSZ);
-                       whiteout(param+6, opt->quiet);
+                       whiteout(param+6, opt->quiet, "ivhex");
                        err += set_flag(&state->iset, "IV");
                } else if (!memcmp(param, "ivfd=", 5)) {
                        err += read_fd(state->sec->nonce1, param+5, BLKSZ, 
"iv");
@@ -328,7 +328,7 @@
                        state->ivf = 1;
                else if (!memcmp(param, "pass=", 5)) {
                        mystrncpy(state->sec->passphr, param+5, 128);
-                       whiteout(param+5, opt->quiet);
+                       whiteout(param+5, opt->quiet, "pass");
                        err += set_flag(&state->pset, "password");
 #if 0
                } else if (!memcmp(param, "passhex=", 8)) {
@@ -350,11 +350,11 @@
                } else if (!memcmp(param, "salt=", 5)) {
                        //mystrncpy(state->sec->salt, param+5, 64);
                        gensalt(state->sec->salt, 8, param+5, NULL, 0); 
-                       whiteout(param+5, opt->quiet);
+                       whiteout(param+5, opt->quiet, NULL);
                        err += set_flag(&state->sset, "salt");
                } else if (!memcmp(param, "salthex=", 8)) {
                        err += parse_hex(state->sec->salt, param+8, 8);
-                       whiteout(param+8, opt->quiet);
+                       whiteout(param+8, opt->quiet, NULL);
                        err += set_flag(&state->sset, "salt");
                } else if (!memcmp(param, "saltfd=", 7)) {
                        err += read_fd(state->sec->salt, param+7, 8, "salt");
@@ -699,7 +699,7 @@
        return (oln == ln? 0: 1);
 }
 
-void whiteout(char* str, char quiet)
+void whiteout(char* str, char quiet, const char* opt)
 {
 #ifndef NO_WRITE_ARGV
        int ln = strlen(str);
@@ -708,8 +708,8 @@
        if (ln >= 1)
                str[0] = 'X';
 #endif
-       if (!quiet)
-               FPLOG_(-1, WARN, "Don't specify sensitive data on the command 
line!\n", NULL);
+       if (!quiet && opt)
+               FPLOG_(-1, WARN, "Don't specify sensitive data (%s=) on the 
command line!\n", opt);
 }
 
 const char* mybasenm(const char* nm)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dd_rescue-1.99.20/test_aes.c 
new/dd_rescue-1.99.21/test_aes.c
--- old/dd_rescue-1.99.20/test_aes.c    2024-09-28 23:56:22.962494763 +0200
+++ new/dd_rescue-1.99.21/test_aes.c    2025-03-14 17:40:10.528737918 +0100
@@ -21,7 +21,10 @@
 
 void usage()
 {
-       printf("Usage: test_aes [-s[-][N]] [-w] [ALG [REP [SEED [LEN 
[FILL]]]]]\n");
+       printf("Usage: test_aes [-s[-][N]] [-w] [-2] [ALG [REP [SEED [LEN 
[FILL]]]]]\n");
+       printf("-s: shift len by N for repeated runs\n");
+       printf("-w: do a warmup round before measuring time\n");
+       printf("-2: Disable VAES (fallback to AESNI if avail), x86-64 only\n");
        exit(0);
 }
 

Reply via email to