Your message dated Wed, 07 Sep 2016 22:11:47 +0000
with message-id <[email protected]>
and subject line Bug#726388: fixed in wipe 0.22-4
has caused the Debian Bug report #726388,
regarding wipe: Wipe does not succeed in hiding filenames of wiped files
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
726388: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=726388
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: wipe
Version: 0.22-1
Severity: normal
Tags: upstream patch

The wipe man-page states:
"Normally, wipe tries to cover file names by renaming them"

However, this does not work for me for different versions of wipe.
Using fls from the sleuthkit, its easy to see the name of the wiped file
in the filesystem on the ext{2,3,4} filesystems. On vfat, btrfs and xfs
the filename can be retrieved easily, too.

My testcase was:
$ dd if=/dev/zero bs=1M count=256 of=wipeimagefile-ext2.bin;
$ losetup /dev/loop2 wipeimagefile-ext2.bin;
$ mkfs.ext2 /dev/loop2;
$ mkdir /mnt/wipetest;
$ mount /dev/loop2 /mnt/wipetest;
$ echo "very secret data that should be deleted after use" > 
/mnt/wipetest/secretfile.txt;
$ wipe -fc /mnt/wipetest/secretfile.txt;
$ umount /mnt/wipetest;
$ losetup -d /dev/loop2;
$ rmdir /mnt/wipetest;
$ fls wipeimagefile-ext2.bin
  wipeimagefile-ext2.bin
  d/d 11: lost+found
  r/- * 0:        secretfile.txt
  r/- * 0:        4hv06IB9SyTgVt
  d/d 2561:       $OrphanFiles

In contrast to this behaviour, shred from coreutils-8.5 succeeds in
hiding the filenames. shred was used with the parameters -fu for this
comparison.

I believe that this is from the different usage of sync() in wipe and
fsync(dir_fd, dirname) in shred.

Note that this isn't a limitation of the filesystem or the operating
system, as shred succeeds in hiding the original filename.

Used for the test were the following versions of wipe:
wipe-0.21-9 from debian squeeze,
wipe-0.22-1 from debian wheezy and sid,
wipe-0.21-5.fc15 from fedora 15,
wipe-0.21-8.fc19 from fedora 19
on ext2, ext3, ext4, vfat, xfs and btrfs.

I have written a patch that fixes the mentioned issue.
It is heavily based on the source of shred from coreutils by Colin Plumb.
While shred is now licensed under GPLv3, the parts of my patch that were
derived from shred could easily be changed to a version of shred
(git cad884a..) that was licensed under GPLv2.

For the same testcase as written in my first mail, the fls output is:
d/d 11: lost+found
r/- * 0:        0
r/- * 0:        00
d/d 2561:       $OrphanFiles

Note that this patch only keeps the filename from being readable in the
filesystem structure. For journaling fileystems, such as ext{3,4}, the
filename is still retained in the journal.
Description: really delete filenames of deleted files
Author: Timo Boettcher <[email protected]>
Last-Update: 2013-10-15

--- a/wipe.c
+++ b/wipe.c
@@ -77,6 +79,7 @@
 #ifdef HAVE_GETOPT
 #include <getopt.h>
 #endif
+#include <assert.h>
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
@@ -174,6 +177,9 @@
 
 /* End of Options ***/
 
+static int ignorable_sync_errno (int errno_val);
+static int dosync (int fd, char const *qname);
+static int incname (char *name, size_t len);
 static int wipe_filename_and_remove (char *fn);
 
 /*** do_remove */
@@ -501,73 +507,176 @@
 static char valid_filename_chars[64] =
 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-.";
 
+static int
+ignorable_sync_errno (int errno_val)
+{
+    return (errno_val == EINVAL
+          || errno_val == EBADF
+          /* HP-UX does this */
+          || errno_val == EISDIR);
+}
+
+
+#define HAVE_FDATASYNC 1
+static int
+dosync (int fd, char const *qname)
+{
+  int err;
+
+#if HAVE_FDATASYNC
+    if (fdatasync (fd) == 0)
+        return 0;
+    err = errno;
+    if ( ! ignorable_sync_errno (err)) {
+        fprintf (stderr, "%s: fdatasync failed", qname);
+        errno = err;
+        return -1;
+    }
+#endif
+
+    if (fsync (fd) == 0)
+        return 0;
+    err = errno;
+    if ( ! ignorable_sync_errno (err)) {
+        fprintf (stderr, "%s: fsync failed", qname);
+        errno = err;
+        return -1;
+    }
+
+    sync ();
+    return 0;
+}
+
+static int
+incname (char *name, size_t len)
+{
+    while (len--) {
+      char const *p = strchr (valid_filename_chars, name[len]);
+
+      /* Given that NAME is composed of bytes from NAMESET,
+         P will never be NULL here.  */
+      assert (p);
+
+      /* If this character has a successor, use it.  */
+      if (p[1]) {
+          name[len] = p[1];
+          return 0;
+      }
+
+      /* Otherwise, set this digit to 0 and increment the prefix.  */
+      name[len] = valid_filename_chars[0];
+    }
+
+    return -1;
+}
+
+#ifndef ISSLASH
+# define ISSLASH(C) ((C) == '/')
+#endif
+
+char *
+last_component (char const *name)
+{
+    char const *base = name;
+    char const *p;
+    int saw_slash = -1;
+
+    while (ISSLASH (*base))
+        base++;
+
+    for (p = base; *p; p++) {
+        if (ISSLASH (*p))
+            saw_slash = -1;
+        else if (saw_slash) {
+            base = p;
+            saw_slash = 0;
+        }
+    }
+
+    return (char *) base;
+}
+
+
 /*** wipe_filename_and_remove */
 
 /* actually, after renaming a file, the only way to make sure that the
  * name change is physically carried out is to call sync (), which flushes
  * out ALL the disk caches of the system, whereas for
- * reading and writing one can use the O_SYNC bit to get syncrhonous
+ * reading and writing one can use the O_SYNC bit to get synchronous
  * I/O for one file. as sync () is very slow, calling sync () after
  * every rename () makes wipe extremely slow.
  */
 
 static int wipe_filename_and_remove (char *fn)
 {
-    int i, j, k, l;
+    int len;
     int r = -1;
     int fn_l, dn_l;
-    /* char *dn; */
-    char *buf[2];
+    char *oldname, *newname;
+    char *dir, *dirc;
+    dirc = strdup(fn);
+    dir = dirname(dirc);
     struct stat st;
-    int t_l; /* target length */
 
-    /* dn = directory_name (fn); */
     fn_l = strlen (fn);
     dn_l = directory_name_length (fn);
 
-    buf[0] = malloc (fn_l + NAME_MAX + 1);
-    buf[1] = malloc (fn_l + NAME_MAX + 1);
+    oldname = malloc (fn_l + NAME_MAX + 1);
+    newname = malloc (fn_l + NAME_MAX + 1);
 
     r = 0;
 
-    t_l = fn_l - dn_l; /* first target length */
+    if (oldname && newname) {
+        strcpy (oldname, fn);
+        strcpy (newname, fn);
+
+        int dir_fd = open (dir, O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
+
+
+        char *base = last_component(newname);
+        len = strlen(base);
+        fprintf (stderr, "\n");
+        while (len) {
+            memset (base, valid_filename_chars[0], len);
+            base[len] = 0;
+            do {
+                if (lstat (newname, &st) < 0) {
+                    if (!o_silent) {
+                        fprintf (stderr, "\rRenaming %32.32s -> %32.32s", oldname, newname);
+                        middle_of_line = 1;
+                        fflush (stderr);
+                    }
+                    if (rename (oldname, newname) == 0) {
+                        if (0 <= dir_fd && dosync (dir_fd, dir) != 0)
+                          r = -1;
+                        memcpy (oldname + (base - newname), base, len + 1);
+                        break;
+                      } else {
+                        /* The rename failed: give up on this length.  */
+                        fprintf (stderr, "%.32s: could not rename '%s' to '%s': %s (%d)\n", fn, oldname, newname, strerror (errno), errno);
+                        break;
+                      }
+                } else {
+                    //fprintf (stderr, "%.32s: rename target '%s' exists\n", fn, newname);
+                }
+            } while (incname (base, len));
+            len--;
+        }
 
-    if (buf[0] && buf[1]) {
-        strcpy (buf[0], fn);
-        strcpy (buf[1], fn);
-        for (j = 1, i = 0; i < o_name_max_passes;  j ^= 1, i++) {
-            for (k = o_name_max_tries; k; k--) {
-                l = t_l;
-                fill_random_from_table (buf[j] + dn_l, l,
-                        valid_filename_chars, 0x3f);
-                buf[j][dn_l + l] = 0;
-                if (stat (buf[j], &st)) break;
-            }
 
-            if (k) {
-                if (!o_silent) {
-                    fprintf (stderr, "\rRenaming %32.32s -> %32.32s", buf[j^1], buf[j]);
-                    middle_of_line = 1;
-                    fflush (stderr);
-                }
-                if (rename (buf[j^1], buf[j])) {
-                    FLUSH_MIDDLE
-                        fprintf (stderr, "%.32s: could not rename '%s' to '%s': %s (%d)\n",
-                                fn, buf[j^1], buf[j], strerror (errno), errno);
-                    r = -1;
-                    break;
-                }
-                (void) sync ();
-            } else {
-                /* we could not find a target name of desired length, so
-                 * increase target length until we find one. */
-                t_l ++;
-                j ^= 1;
+        if (remove (oldname)) {
+            fprintf (stderr, "%.32s: failed to unlink '%s'\n", fn, oldname);
+            r = -1;
+        }
+        if (0 <= dir_fd) {
+            dosync (dir_fd, dir);
+            if (close (dir_fd) != 0) {
+                fprintf (stderr, "%s: failed to close\n", dir);
+                r = -1;
             }
         }
-        if (remove (buf[j^1])) r = -1;
     }
-    free (buf[0]); free (buf[1]);
+    free (oldname); free (newname); free(dirc);
     return r;
 }
 
@@ -1017,7 +1126,7 @@
                 }
 
 #ifndef HAVE_OSYNC
-                if (fsync (fd)) {
+                if (dosync (fd,fn)) {
                     fnerror ("fsync error [1]");
                     close (fd);
                     return -1;
@@ -1025,7 +1134,7 @@
 #endif
             }
 
-            if (fsync (fd)) {
+            if (dosync (fd,fn)) {
                 fnerror ("fsync error [2]");
                 close (fd);
                 return -1;
@@ -1221,7 +1330,7 @@
             "Web site:                http://lambda-diode.com/software/wipe/\n";
             "Release date:            " WIPE_DATE "\n"
             "Compiled:                " __DATE__ "\n"
-            "Git version:             " WIPE_GIT "\n"
+            "Git version:             TEST\n"
             "\n"
             "Based on data from \"Secure Deletion of Data from Magnetic and Solid-State\n"
             "Memory\" by Peter Gutmann <[email protected]>.\n");

--- End Message ---
--- Begin Message ---
Source: wipe
Source-Version: 0.22-4

We believe that the bug you reported is fixed in the latest version of
wipe, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [email protected],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Joao Eriberto Mota Filho <[email protected]> (supplier of updated wipe 
package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [email protected])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Format: 1.8
Date: Tue, 06 Sep 2016 14:44:36 -0300
Source: wipe
Binary: wipe
Architecture: source
Version: 0.22-4
Distribution: unstable
Urgency: medium
Maintainer: Debian Forensics <[email protected]>
Changed-By: Joao Eriberto Mota Filho <[email protected]>
Description:
 wipe       - secure file deletion
Closes: 411971 544774 726388
Changes:
 wipe (0.22-4) unstable; urgency=medium
 .
   * debian/control:
       - Bumped Standards-Version to 3.9.8.
       - Improved the long description.
       - Updated the Vcs-* fields to use https instead of http and git.
   * debian/copyright: updated packaging copyright years.
   * debian/patches/:
       - 001_fix-manpages.diff: removed. No longer necessary escape hyphens in
         manpages.
       - 002-add-hardening: renamed to 10_add-hardening.patch.
       - 20_fix-manpage.patch:
           ~ Added to fix a spelling error and remove invalid macro SP.
           ~ Fix a wrong example. Thanks to (No Name)
             <[email protected]>. (Closes: #411971)
           ~ Make clearer the -Q option use. (LP: #801472)
           ~ Make the man page clear about number of default passes. For this,
             thanks to Runa Sandvik <[email protected]> (Closes: #544774)
       - 30_fix-spelling-binary.patch: added to fix a spelling error in final
         binary.
       - 40-fix_warnings.patch: added to fix some GCC warnings.
       - 50_hide-filenames.patch: added to really delete filenames of deleted
         files. Thanks to Timo Boettcher <[email protected],
         [email protected]> (Closes: #726388)
       - 60_fix-warnings.patch: added to fix some GCC warnings in previous
         patch.
   * debian/README.source: added to tell about new upstream's repository.
   * debian/rules:
       - Added specific rules to build to GNU/kFreeBSD.
       - Removed unnecessary lines because the current upstream Makefile already
         provides all necessary flags.
   * debian/watch: bumped to version 4.
Checksums-Sha1:
 005fdc9e2fe0d05ae5b2a50a9a9336b50d26b71f 1837 wipe_0.22-4.dsc
 82fdfe2932264eb09a8b7982fe1a2e5286d813d6 10440 wipe_0.22-4.debian.tar.xz
Checksums-Sha256:
 2a8232301a7427cbe29924d539d5e91ce2a5d375a6adc5493c3acf12aa077c0d 1837 
wipe_0.22-4.dsc
 9a96448b7a44a7e21419bb670ec6315ac790276ff0fd08f610911f36bfb18c0f 10440 
wipe_0.22-4.debian.tar.xz
Files:
 35730895264eb56b81b058c34e664d92 1837 utils extra wipe_0.22-4.dsc
 e210f79434f6d0e03f04b660c194c949 10440 utils extra wipe_0.22-4.debian.tar.xz

-----BEGIN PGP SIGNATURE-----

iQIcBAEBCAAGBQJXzydKAAoJEN5juccE6+nvHz8QAIyAGHNUbUYBU7OHLSCY4hMp
aNmQwBBX5MaltEaKIp6VimyjCkWhVfKN4m1TlojJiUw/ht/fi8GkWcYyQebOA2wr
rbqSx0M3GwjHs6ww+7OKXv2GgbszWPY8uV3q0YBik3uOwb5Sq5fTU+R9Ou+uD2lM
nY1Ftz/5SQZQylfwhVDoOwrx/Q/U3unb9kY/Tt/HSDu7ZnwjugsUi7x13kWQGs0b
WeD2RTNrjr4KOGhAEGHN5ew0tM9gfO3SYvIfFyA0FFPGUbYUPCKlLUA3BThEqQ3p
VbTQVvJ7W0M2vpWwCu17AiSRD1idauqXxyQGidjeuggLnKgJQEmlFkJ9b4H/QjWr
AcCvuJGihvlCLh2TQUwzh8a+aNas5CcgeD7uJFQ4CJHpzzAf3Q4vEXrHnZApbN8Y
dEyUOdifvYZIXJjRQhUVHpjJnicmCBv0WlU1hL6ArHENIP52N3BBo0mOTtI3lidk
T6gk2FPio15VU7/yU7TtZUC4cooYKttSii2lYNh64OQpkd9N4BX04GGHUTEtwfsV
1zVuFVqUh17QHRshedlcDoNyY7xZCY3jKITg8uNYtcViYxN7YiYZLXU22qCcefNl
Kg7niAoyNtvn/+o/gmXrL2mIMH6wgY27YkvQpSpqvhqwGE34yF1qUCocaSxld9sl
gHDOD64kceXfByRBNI+A
=E4ck
-----END PGP SIGNATURE-----

--- End Message ---
_______________________________________________
forensics-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/forensics-devel

Reply via email to