maint: revert "build: update gnulib submodule to latest"
[coreutils/ericb.git] / src / shred.c
bloba2365b0fb438a53b371830ce1493819f4d6210a6
1 /* shred.c - overwrite files and devices to make it harder to recover data
3 Copyright (C) 1999-2011 Free Software Foundation, Inc.
4 Copyright (C) 1997, 1998, 1999 Colin Plumb.
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 Written by Colin Plumb. */
21 /* TODO:
22 - use consistent non-capitalization in error messages
23 - add standard GNU copyleft comment
25 - Add -r/-R/--recursive
26 - Add -i/--interactive
27 - Reserve -d
28 - Add -L
29 - Add an unlink-all option to emulate rm.
33 * Do a more secure overwrite of given files or devices, to make it harder
34 * for even very expensive hardware probing to recover the data.
36 * Although this process is also known as "wiping", I prefer the longer
37 * name both because I think it is more evocative of what is happening and
38 * because a longer name conveys a more appropriate sense of deliberateness.
40 * For the theory behind this, see "Secure Deletion of Data from Magnetic
41 * and Solid-State Memory", on line at
42 * http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
44 * Just for the record, reversing one or two passes of disk overwrite
45 * is not terribly difficult with hardware help. Hook up a good-quality
46 * digitizing oscilloscope to the output of the head preamplifier and copy
47 * the high-res digitized data to a computer for some off-line analysis.
48 * Read the "current" data and average all the pulses together to get an
49 * "average" pulse on the disk. Subtract this average pulse from all of
50 * the actual pulses and you can clearly see the "echo" of the previous
51 * data on the disk.
53 * Real hard drives have to balance the cost of the media, the head,
54 * and the read circuitry. They use better-quality media than absolutely
55 * necessary to limit the cost of the read circuitry. By throwing that
56 * assumption out, and the assumption that you want the data processed
57 * as fast as the hard drive can spin, you can do better.
59 * If asked to wipe a file, this also unlinks it, renaming it to in a
60 * clever way to try to leave no trace of the original filename.
62 * This was inspired by a desire to improve on some code titled:
63 * Wipe V1.0-- Overwrite and delete files. S. 2/3/96
64 * but I've rewritten everything here so completely that no trace of
65 * the original remains.
67 * Thanks to:
68 * Bob Jenkins, for his good RNG work and patience with the FSF copyright
69 * paperwork.
70 * Jim Meyering, for his work merging this into the GNU fileutils while
71 * still letting me feel a sense of ownership and pride. Getting me to
72 * tolerate the GNU brace style was quite a feat of diplomacy.
73 * Paul Eggert, for lots of useful discussion and code. I disagree with
74 * an awful lot of his suggestions, but they're disagreements worth having.
76 * Things to think about:
77 * - Security: Is there any risk to the race
78 * between overwriting and unlinking a file? Will it do anything
79 * drastically bad if told to attack a named pipe or socket?
82 /* The official name of this program (e.g., no `g' prefix). */
83 #define PROGRAM_NAME "shred"
85 #define AUTHORS proper_name ("Colin Plumb")
87 #include <config.h>
89 #include <getopt.h>
90 #include <stdio.h>
91 #include <assert.h>
92 #include <setjmp.h>
93 #include <sys/types.h>
95 #include "system.h"
96 #include "xstrtol.h"
97 #include "error.h"
98 #include "fcntl--.h"
99 #include "human.h"
100 #include "quotearg.h" /* For quotearg_colon */
101 #include "randint.h"
102 #include "randread.h"
103 #include "stat-size.h"
105 /* Default number of times to overwrite. */
106 enum { DEFAULT_PASSES = 3 };
108 /* How many seconds to wait before checking whether to output another
109 verbose output line. */
110 enum { VERBOSE_UPDATE = 5 };
112 /* Sector size and corresponding mask, for recovering after write failures.
113 The size must be a power of 2. */
114 enum { SECTOR_SIZE = 512 };
115 enum { SECTOR_MASK = SECTOR_SIZE - 1 };
116 verify (0 < SECTOR_SIZE && (SECTOR_SIZE & SECTOR_MASK) == 0);
118 struct Options
120 bool force; /* -f flag: chmod files if necessary */
121 size_t n_iterations; /* -n flag: Number of iterations */
122 off_t size; /* -s flag: size of file */
123 bool remove_file; /* -u flag: remove file after shredding */
124 bool verbose; /* -v flag: Print progress */
125 bool exact; /* -x flag: Do not round up file size */
126 bool zero_fill; /* -z flag: Add a final zero pass */
129 /* For long options that have no equivalent short option, use a
130 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
131 enum
133 RANDOM_SOURCE_OPTION = CHAR_MAX + 1
136 static struct option const long_opts[] =
138 {"exact", no_argument, NULL, 'x'},
139 {"force", no_argument, NULL, 'f'},
140 {"iterations", required_argument, NULL, 'n'},
141 {"size", required_argument, NULL, 's'},
142 {"random-source", required_argument, NULL, RANDOM_SOURCE_OPTION},
143 {"remove", no_argument, NULL, 'u'},
144 {"verbose", no_argument, NULL, 'v'},
145 {"zero", no_argument, NULL, 'z'},
146 {GETOPT_HELP_OPTION_DECL},
147 {GETOPT_VERSION_OPTION_DECL},
148 {NULL, 0, NULL, 0}
151 void
152 usage (int status)
154 if (status != EXIT_SUCCESS)
155 fprintf (stderr, _("Try `%s --help' for more information.\n"),
156 program_name);
157 else
159 printf (_("Usage: %s [OPTION]... FILE...\n"), program_name);
160 fputs (_("\
161 Overwrite the specified FILE(s) repeatedly, in order to make it harder\n\
162 for even very expensive hardware probing to recover the data.\n\
164 "), stdout);
165 fputs (_("\
166 Mandatory arguments to long options are mandatory for short options too.\n\
167 "), stdout);
168 printf (_("\
169 -f, --force change permissions to allow writing if necessary\n\
170 -n, --iterations=N overwrite N times instead of the default (%d)\n\
171 --random-source=FILE get random bytes from FILE\n\
172 -s, --size=N shred this many bytes (suffixes like K, M, G accepted)\n\
173 "), DEFAULT_PASSES);
174 fputs (_("\
175 -u, --remove truncate and remove file after overwriting\n\
176 -v, --verbose show progress\n\
177 -x, --exact do not round file sizes up to the next full block;\n\
178 this is the default for non-regular files\n\
179 -z, --zero add a final overwrite with zeros to hide shredding\n\
180 "), stdout);
181 fputs (HELP_OPTION_DESCRIPTION, stdout);
182 fputs (VERSION_OPTION_DESCRIPTION, stdout);
183 fputs (_("\
185 If FILE is -, shred standard output.\n\
187 Delete FILE(s) if --remove (-u) is specified. The default is not to remove\n\
188 the files because it is common to operate on device files like /dev/hda,\n\
189 and those files usually should not be removed. When operating on regular\n\
190 files, most people use the --remove option.\n\
192 "), stdout);
193 fputs (_("\
194 CAUTION: Note that shred relies on a very important assumption:\n\
195 that the file system overwrites data in place. This is the traditional\n\
196 way to do things, but many modern file system designs do not satisfy this\n\
197 assumption. The following are examples of file systems on which shred is\n\
198 not effective, or is not guaranteed to be effective in all file system modes:\n\
200 "), stdout);
201 fputs (_("\
202 * log-structured or journaled file systems, such as those supplied with\n\
203 AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)\n\
205 * file systems that write redundant data and carry on even if some writes\n\
206 fail, such as RAID-based file systems\n\
208 * file systems that make snapshots, such as Network Appliance's NFS server\n\
210 "), stdout);
211 fputs (_("\
212 * file systems that cache in temporary locations, such as NFS\n\
213 version 3 clients\n\
215 * compressed file systems\n\
217 "), stdout);
218 fputs (_("\
219 In the case of ext3 file systems, the above disclaimer applies\n\
220 (and shred is thus of limited effectiveness) only in data=journal mode,\n\
221 which journals file data in addition to just metadata. In both the\n\
222 data=ordered (default) and data=writeback modes, shred works as usual.\n\
223 Ext3 journaling modes can be changed by adding the data=something option\n\
224 to the mount options for a particular file system in the /etc/fstab file,\n\
225 as documented in the mount man page (man mount).\n\
227 "), stdout);
228 fputs (_("\
229 In addition, file system backups and remote mirrors may contain copies\n\
230 of the file that cannot be removed, and that will allow a shredded file\n\
231 to be recovered later.\n\
232 "), stdout);
233 emit_ancillary_info ();
235 exit (status);
240 * Fill a buffer with a fixed pattern.
242 * The buffer must be at least 3 bytes long, even if
243 * size is less. Larger sizes are filled exactly.
245 static void
246 fillpattern (int type, unsigned char *r, size_t size)
248 size_t i;
249 unsigned int bits = type & 0xfff;
251 bits |= bits << 12;
252 r[0] = (bits >> 4) & 255;
253 r[1] = (bits >> 8) & 255;
254 r[2] = bits & 255;
255 for (i = 3; i < size / 2; i *= 2)
256 memcpy (r + i, r, i);
257 if (i < size)
258 memcpy (r + i, r, size - i);
260 /* Invert the first bit of every sector. */
261 if (type & 0x1000)
262 for (i = 0; i < size; i += SECTOR_SIZE)
263 r[i] ^= 0x80;
267 * Generate a 6-character (+ nul) pass name string
268 * FIXME: allow translation of "random".
270 #define PASS_NAME_SIZE 7
271 static void
272 passname (unsigned char const *data, char name[PASS_NAME_SIZE])
274 if (data)
275 sprintf (name, "%02x%02x%02x", data[0], data[1], data[2]);
276 else
277 memcpy (name, "random", PASS_NAME_SIZE);
280 /* Return true when it's ok to ignore an fsync or fdatasync
281 failure that set errno to ERRNO_VAL. */
282 static bool
283 ignorable_sync_errno (int errno_val)
285 return (errno_val == EINVAL
286 || errno_val == EBADF
287 /* HP-UX does this */
288 || errno_val == EISDIR);
291 /* Request that all data for FD be transferred to the corresponding
292 storage device. QNAME is the file name (quoted for colons).
293 Report any errors found. Return 0 on success, -1
294 (setting errno) on failure. It is not an error if fdatasync and/or
295 fsync is not supported for this file, or if the file is not a
296 writable file descriptor. */
297 static int
298 dosync (int fd, char const *qname)
300 int err;
302 #if HAVE_FDATASYNC
303 if (fdatasync (fd) == 0)
304 return 0;
305 err = errno;
306 if ( ! ignorable_sync_errno (err))
308 error (0, err, _("%s: fdatasync failed"), qname);
309 errno = err;
310 return -1;
312 #endif
314 if (fsync (fd) == 0)
315 return 0;
316 err = errno;
317 if ( ! ignorable_sync_errno (err))
319 error (0, err, _("%s: fsync failed"), qname);
320 errno = err;
321 return -1;
324 sync ();
325 return 0;
328 /* Turn on or off direct I/O mode for file descriptor FD, if possible.
329 Try to turn it on if ENABLE is true. Otherwise, try to turn it off. */
330 static void
331 direct_mode (int fd, bool enable)
333 if (O_DIRECT)
335 int fd_flags = fcntl (fd, F_GETFL);
336 if (0 < fd_flags)
338 int new_flags = (enable
339 ? (fd_flags | O_DIRECT)
340 : (fd_flags & ~O_DIRECT));
341 if (new_flags != fd_flags)
342 fcntl (fd, F_SETFL, new_flags);
346 #if HAVE_DIRECTIO && defined DIRECTIO_ON && defined DIRECTIO_OFF
347 /* This is Solaris-specific. See the following for details:
348 http://docs.sun.com/db/doc/816-0213/6m6ne37so?q=directio&a=view */
349 directio (fd, enable ? DIRECTIO_ON : DIRECTIO_OFF);
350 #endif
354 * Do pass number k of n, writing "size" bytes of the given pattern "type"
355 * to the file descriptor fd. Qname, k and n are passed in only for verbose
356 * progress message purposes. If n == 0, no progress messages are printed.
358 * If *sizep == -1, the size is unknown, and it will be filled in as soon
359 * as writing fails.
361 * Return 1 on write error, -1 on other error, 0 on success.
363 static int
364 dopass (int fd, char const *qname, off_t *sizep, int type,
365 struct randread_source *s, unsigned long int k, unsigned long int n)
367 off_t size = *sizep;
368 off_t offset; /* Current file posiiton */
369 time_t thresh IF_LINT ( = 0); /* Time to maybe print next status update */
370 time_t now = 0; /* Current time */
371 size_t lim; /* Amount of data to try writing */
372 size_t soff; /* Offset into buffer for next write */
373 ssize_t ssize; /* Return value from write */
375 /* Fill pattern buffer. Aligning it to a 32-bit boundary speeds up randread
376 in some cases. */
377 typedef uint32_t fill_pattern_buffer[3 * 1024];
378 union
380 fill_pattern_buffer buffer;
381 char c[sizeof (fill_pattern_buffer)];
382 unsigned char u[sizeof (fill_pattern_buffer)];
383 } r;
385 off_t sizeof_r = sizeof r;
386 char pass_string[PASS_NAME_SIZE]; /* Name of current pass */
387 bool write_error = false;
388 bool first_write = true;
390 /* Printable previous offset into the file */
391 char previous_offset_buf[LONGEST_HUMAN_READABLE + 1];
392 char const *previous_human_offset IF_LINT ( = 0);
394 if (lseek (fd, 0, SEEK_SET) == -1)
396 error (0, errno, _("%s: cannot rewind"), qname);
397 return -1;
400 /* Constant fill patterns need only be set up once. */
401 if (type >= 0)
403 lim = (0 <= size && size < sizeof_r ? size : sizeof_r);
404 fillpattern (type, r.u, lim);
405 passname (r.u, pass_string);
407 else
409 passname (0, pass_string);
412 /* Set position if first status update */
413 if (n)
415 error (0, 0, _("%s: pass %lu/%lu (%s)..."), qname, k, n, pass_string);
416 thresh = time (NULL) + VERBOSE_UPDATE;
417 previous_human_offset = "";
420 offset = 0;
421 while (true)
423 /* How much to write this time? */
424 lim = sizeof r;
425 if (0 <= size && size - offset < sizeof_r)
427 if (size < offset)
428 break;
429 lim = size - offset;
430 if (!lim)
431 break;
433 if (type < 0)
434 randread (s, &r, lim);
435 /* Loop to retry partial writes. */
436 for (soff = 0; soff < lim; soff += ssize, first_write = false)
438 ssize = write (fd, r.c + soff, lim - soff);
439 if (ssize <= 0)
441 if (size < 0 && (ssize == 0 || errno == ENOSPC))
443 /* Ah, we have found the end of the file */
444 *sizep = size = offset + soff;
445 break;
447 else
449 int errnum = errno;
450 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
452 /* If the first write of the first pass for a given file
453 has just failed with EINVAL, turn off direct mode I/O
454 and try again. This works around a bug in Linux kernel
455 2.4 whereby opening with O_DIRECT would succeed for some
456 file system types (e.g., ext3), but any attempt to
457 access a file through the resulting descriptor would
458 fail with EINVAL. */
459 if (k == 1 && first_write && errno == EINVAL)
461 direct_mode (fd, false);
462 ssize = 0;
463 continue;
465 error (0, errnum, _("%s: error writing at offset %s"),
466 qname, umaxtostr (offset + soff, buf));
468 /* 'shred' is often used on bad media, before throwing it
469 out. Thus, it shouldn't give up on bad blocks. This
470 code works because lim is always a multiple of
471 SECTOR_SIZE, except at the end. */
472 verify (sizeof r % SECTOR_SIZE == 0);
473 if (errnum == EIO && 0 <= size && (soff | SECTOR_MASK) < lim)
475 size_t soff1 = (soff | SECTOR_MASK) + 1;
476 if (lseek (fd, offset + soff1, SEEK_SET) != -1)
478 /* Arrange to skip this block. */
479 ssize = soff1 - soff;
480 write_error = true;
481 continue;
483 error (0, errno, _("%s: lseek failed"), qname);
485 return -1;
490 /* Okay, we have written "soff" bytes. */
492 if (offset > OFF_T_MAX - (off_t) soff)
494 error (0, 0, _("%s: file too large"), qname);
495 return -1;
498 offset += soff;
500 /* Time to print progress? */
501 if (n
502 && ((offset == size && *previous_human_offset)
503 || thresh <= (now = time (NULL))))
505 char offset_buf[LONGEST_HUMAN_READABLE + 1];
506 char size_buf[LONGEST_HUMAN_READABLE + 1];
507 int human_progress_opts = (human_autoscale | human_SI
508 | human_base_1024 | human_B);
509 char const *human_offset
510 = human_readable (offset, offset_buf,
511 human_floor | human_progress_opts, 1, 1);
513 if (offset == size
514 || !STREQ (previous_human_offset, human_offset))
516 if (size < 0)
517 error (0, 0, _("%s: pass %lu/%lu (%s)...%s"),
518 qname, k, n, pass_string, human_offset);
519 else
521 uintmax_t off = offset;
522 int percent = (size == 0
523 ? 100
524 : (off <= TYPE_MAXIMUM (uintmax_t) / 100
525 ? off * 100 / size
526 : off / (size / 100)));
527 char const *human_size
528 = human_readable (size, size_buf,
529 human_ceiling | human_progress_opts,
530 1, 1);
531 if (offset == size)
532 human_offset = human_size;
533 error (0, 0, _("%s: pass %lu/%lu (%s)...%s/%s %d%%"),
534 qname, k, n, pass_string, human_offset, human_size,
535 percent);
538 strcpy (previous_offset_buf, human_offset);
539 previous_human_offset = previous_offset_buf;
540 thresh = now + VERBOSE_UPDATE;
543 * Force periodic syncs to keep displayed progress accurate
544 * FIXME: Should these be present even if -v is not enabled,
545 * to keep the buffer cache from filling with dirty pages?
546 * It's a common problem with programs that do lots of writes,
547 * like mkfs.
549 if (dosync (fd, qname) != 0)
551 if (errno != EIO)
552 return -1;
553 write_error = true;
559 /* Force what we just wrote to hit the media. */
560 if (dosync (fd, qname) != 0)
562 if (errno != EIO)
563 return -1;
564 write_error = true;
567 return write_error;
571 * The passes start and end with a random pass, and the passes in between
572 * are done in random order. The idea is to deprive someone trying to
573 * reverse the process of knowledge of the overwrite patterns, so they
574 * have the additional step of figuring out what was done to the disk
575 * before they can try to reverse or cancel it.
577 * First, all possible 1-bit patterns. There are two of them.
578 * Then, all possible 2-bit patterns. There are four, but the two
579 * which are also 1-bit patterns can be omitted.
580 * Then, all possible 3-bit patterns. Likewise, 8-2 = 6.
581 * Then, all possible 4-bit patterns. 16-4 = 12.
583 * The basic passes are:
584 * 1-bit: 0x000, 0xFFF
585 * 2-bit: 0x555, 0xAAA
586 * 3-bit: 0x249, 0x492, 0x924, 0x6DB, 0xB6D, 0xDB6 (+ 1-bit)
587 * 100100100100 110110110110
588 * 9 2 4 D B 6
589 * 4-bit: 0x111, 0x222, 0x333, 0x444, 0x666, 0x777,
590 * 0x888, 0x999, 0xBBB, 0xCCC, 0xDDD, 0xEEE (+ 1-bit, 2-bit)
591 * Adding three random passes at the beginning, middle and end
592 * produces the default 25-pass structure.
594 * The next extension would be to 5-bit and 6-bit patterns.
595 * There are 30 uncovered 5-bit patterns and 64-8-2 = 46 uncovered
596 * 6-bit patterns, so they would increase the time required
597 * significantly. 4-bit patterns are enough for most purposes.
599 * The main gotcha is that this would require a trickier encoding,
600 * since lcm(2,3,4) = 12 bits is easy to fit into an int, but
601 * lcm(2,3,4,5) = 60 bits is not.
603 * One extension that is included is to complement the first bit in each
604 * 512-byte block, to alter the phase of the encoded data in the more
605 * complex encodings. This doesn't apply to MFM, so the 1-bit patterns
606 * are considered part of the 3-bit ones and the 2-bit patterns are
607 * considered part of the 4-bit patterns.
610 * How does the generalization to variable numbers of passes work?
612 * Here's how...
613 * Have an ordered list of groups of passes. Each group is a set.
614 * Take as many groups as will fit, plus a random subset of the
615 * last partial group, and place them into the passes list.
616 * Then shuffle the passes list into random order and use that.
618 * One extra detail: if we can't include a large enough fraction of the
619 * last group to be interesting, then just substitute random passes.
621 * If you want more passes than the entire list of groups can
622 * provide, just start repeating from the beginning of the list.
624 static int const
625 patterns[] =
627 -2, /* 2 random passes */
628 2, 0x000, 0xFFF, /* 1-bit */
629 2, 0x555, 0xAAA, /* 2-bit */
630 -1, /* 1 random pass */
631 6, 0x249, 0x492, 0x6DB, 0x924, 0xB6D, 0xDB6, /* 3-bit */
632 12, 0x111, 0x222, 0x333, 0x444, 0x666, 0x777,
633 0x888, 0x999, 0xBBB, 0xCCC, 0xDDD, 0xEEE, /* 4-bit */
634 -1, /* 1 random pass */
635 /* The following patterns have the frst bit per block flipped */
636 8, 0x1000, 0x1249, 0x1492, 0x16DB, 0x1924, 0x1B6D, 0x1DB6, 0x1FFF,
637 14, 0x1111, 0x1222, 0x1333, 0x1444, 0x1555, 0x1666, 0x1777,
638 0x1888, 0x1999, 0x1AAA, 0x1BBB, 0x1CCC, 0x1DDD, 0x1EEE,
639 -1, /* 1 random pass */
640 0 /* End */
644 * Generate a random wiping pass pattern with num passes.
645 * This is a two-stage process. First, the passes to include
646 * are chosen, and then they are shuffled into the desired
647 * order.
649 static void
650 genpattern (int *dest, size_t num, struct randint_source *s)
652 size_t randpasses;
653 int const *p;
654 int *d;
655 size_t n;
656 size_t accum, top, swap;
657 int k;
659 if (!num)
660 return;
662 /* Stage 1: choose the passes to use */
663 p = patterns;
664 randpasses = 0;
665 d = dest; /* Destination for generated pass list */
666 n = num; /* Passes remaining to fill */
668 while (true)
670 k = *p++; /* Block descriptor word */
671 if (!k)
672 { /* Loop back to the beginning */
673 p = patterns;
675 else if (k < 0)
676 { /* -k random passes */
677 k = -k;
678 if ((size_t) k >= n)
680 randpasses += n;
681 break;
683 randpasses += k;
684 n -= k;
686 else if ((size_t) k <= n)
687 { /* Full block of patterns */
688 memcpy (d, p, k * sizeof (int));
689 p += k;
690 d += k;
691 n -= k;
693 else if (n < 2 || 3 * n < (size_t) k)
694 { /* Finish with random */
695 randpasses += n;
696 break;
698 else
699 { /* Pad out with k of the n available */
702 if (n == (size_t) k || randint_choose (s, k) < n)
704 *d++ = *p;
705 n--;
707 p++;
709 while (n);
710 break;
713 top = num - randpasses; /* Top of initialized data */
714 /* assert (d == dest+top); */
717 * We now have fixed patterns in the dest buffer up to
718 * "top", and we need to scramble them, with "randpasses"
719 * random passes evenly spaced among them.
721 * We want one at the beginning, one at the end, and
722 * evenly spaced in between. To do this, we basically
723 * use Bresenham's line draw (a.k.a DDA) algorithm
724 * to draw a line with slope (randpasses-1)/(num-1).
725 * (We use a positive accumulator and count down to
726 * do this.)
728 * So for each desired output value, we do the following:
729 * - If it should be a random pass, copy the pass type
730 * to top++, out of the way of the other passes, and
731 * set the current pass to -1 (random).
732 * - If it should be a normal pattern pass, choose an
733 * entry at random between here and top-1 (inclusive)
734 * and swap the current entry with that one.
736 randpasses--; /* To speed up later math */
737 accum = randpasses; /* Bresenham DDA accumulator */
738 for (n = 0; n < num; n++)
740 if (accum <= randpasses)
742 accum += num - 1;
743 dest[top++] = dest[n];
744 dest[n] = -1;
746 else
748 swap = n + randint_choose (s, top - n);
749 k = dest[n];
750 dest[n] = dest[swap];
751 dest[swap] = k;
753 accum -= randpasses;
755 /* assert (top == num); */
759 * The core routine to actually do the work. This overwrites the first
760 * size bytes of the given fd. Return true if successful.
762 static bool
763 do_wipefd (int fd, char const *qname, struct randint_source *s,
764 struct Options const *flags)
766 size_t i;
767 struct stat st;
768 off_t size; /* Size to write, size to read */
769 unsigned long int n; /* Number of passes for printing purposes */
770 int *passarray;
771 bool ok = true;
772 struct randread_source *rs;
774 n = 0; /* dopass takes n -- 0 to mean "don't print progress" */
775 if (flags->verbose)
776 n = flags->n_iterations + flags->zero_fill;
778 if (fstat (fd, &st))
780 error (0, errno, _("%s: fstat failed"), qname);
781 return false;
784 /* If we know that we can't possibly shred the file, give up now.
785 Otherwise, we may go into an infinite loop writing data before we
786 find that we can't rewind the device. */
787 if ((S_ISCHR (st.st_mode) && isatty (fd))
788 || S_ISFIFO (st.st_mode)
789 || S_ISSOCK (st.st_mode))
791 error (0, 0, _("%s: invalid file type"), qname);
792 return false;
795 direct_mode (fd, true);
797 /* Allocate pass array */
798 passarray = xnmalloc (flags->n_iterations, sizeof *passarray);
800 size = flags->size;
801 if (size == -1)
803 /* Accept a length of zero only if it's a regular file.
804 For any other type of file, try to get the size another way. */
805 if (S_ISREG (st.st_mode))
807 size = st.st_size;
808 if (size < 0)
810 error (0, 0, _("%s: file has negative size"), qname);
811 return false;
814 else
816 size = lseek (fd, 0, SEEK_END);
817 if (size <= 0)
819 /* We are unable to determine the length, up front.
820 Let dopass do that as part of its first iteration. */
821 size = -1;
825 /* Allow `rounding up' only for regular files. */
826 if (0 <= size && !(flags->exact) && S_ISREG (st.st_mode))
828 size += ST_BLKSIZE (st) - 1 - (size - 1) % ST_BLKSIZE (st);
830 /* If in rounding up, we've just overflowed, use the maximum. */
831 if (size < 0)
832 size = TYPE_MAXIMUM (off_t);
836 /* Schedule the passes in random order. */
837 genpattern (passarray, flags->n_iterations, s);
839 rs = randint_get_source (s);
841 /* Do the work */
842 for (i = 0; i < flags->n_iterations; i++)
844 int err = dopass (fd, qname, &size, passarray[i], rs, i + 1, n);
845 if (err)
847 if (err < 0)
849 memset (passarray, 0, flags->n_iterations * sizeof (int));
850 free (passarray);
851 return false;
853 ok = false;
857 memset (passarray, 0, flags->n_iterations * sizeof (int));
858 free (passarray);
860 if (flags->zero_fill)
862 int err = dopass (fd, qname, &size, 0, rs, flags->n_iterations + 1, n);
863 if (err)
865 if (err < 0)
866 return false;
867 ok = false;
871 /* Okay, now deallocate the data. The effect of ftruncate on
872 non-regular files is unspecified, so don't worry about any
873 errors reported for them. */
874 if (flags->remove_file && ftruncate (fd, 0) != 0
875 && S_ISREG (st.st_mode))
877 error (0, errno, _("%s: error truncating"), qname);
878 return false;
881 return ok;
884 /* A wrapper with a little more checking for fds on the command line */
885 static bool
886 wipefd (int fd, char const *qname, struct randint_source *s,
887 struct Options const *flags)
889 int fd_flags = fcntl (fd, F_GETFL);
891 if (fd_flags < 0)
893 error (0, errno, _("%s: fcntl failed"), qname);
894 return false;
896 if (fd_flags & O_APPEND)
898 error (0, 0, _("%s: cannot shred append-only file descriptor"), qname);
899 return false;
901 return do_wipefd (fd, qname, s, flags);
904 /* --- Name-wiping code --- */
906 /* Characters allowed in a file name - a safe universal set. */
907 static char const nameset[] =
908 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.";
910 /* Increment NAME (with LEN bytes). NAME must be a big-endian base N
911 number with the digits taken from nameset. Return true if successful.
912 Otherwise, (because NAME already has the greatest possible value)
913 return false. */
915 static bool
916 incname (char *name, size_t len)
918 while (len--)
920 char const *p = strchr (nameset, name[len]);
922 /* Given that NAME is composed of bytes from NAMESET,
923 P will never be NULL here. */
924 assert (p);
926 /* If this character has a successor, use it. */
927 if (p[1])
929 name[len] = p[1];
930 return true;
933 /* Otherwise, set this digit to 0 and increment the prefix. */
934 name[len] = nameset[0];
937 return false;
941 * Repeatedly rename a file with shorter and shorter names,
942 * to obliterate all traces of the file name on any system that
943 * adds a trailing delimiter to on-disk file names and reuses
944 * the same directory slot. Finally, unlink it.
945 * The passed-in filename is modified in place to the new filename.
946 * (Which is unlinked if this function succeeds, but is still present if
947 * it fails for some reason.)
949 * The main loop is written carefully to not get stuck if all possible
950 * names of a given length are occupied. It counts down the length from
951 * the original to 0. While the length is non-zero, it tries to find an
952 * unused file name of the given length. It continues until either the
953 * name is available and the rename succeeds, or it runs out of names
954 * to try (incname wraps and returns 1). Finally, it unlinks the file.
956 * The unlink is Unix-specific, as ANSI-standard remove has more
957 * portability problems with C libraries making it "safe". rename
958 * is ANSI-standard.
960 * To force the directory data out, we try to open the directory and
961 * invoke fdatasync and/or fsync on it. This is non-standard, so don't
962 * insist that it works: just fall back to a global sync in that case.
963 * This is fairly significantly Unix-specific. Of course, on any
964 * file system with synchronous metadata updates, this is unnecessary.
966 static bool
967 wipename (char *oldname, char const *qoldname, struct Options const *flags)
969 char *newname = xstrdup (oldname);
970 char *base = last_component (newname);
971 size_t len = base_len (base);
972 char *dir = dir_name (newname);
973 char *qdir = xstrdup (quotearg_colon (dir));
974 bool first = true;
975 bool ok = true;
977 int dir_fd = open (dir, O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
979 if (flags->verbose)
980 error (0, 0, _("%s: removing"), qoldname);
982 while (len)
984 memset (base, nameset[0], len);
985 base[len] = 0;
988 struct stat st;
989 if (lstat (newname, &st) < 0)
991 if (rename (oldname, newname) == 0)
993 if (0 <= dir_fd && dosync (dir_fd, qdir) != 0)
994 ok = false;
995 if (flags->verbose)
998 * People seem to understand this better than talking
999 * about renaming oldname. newname doesn't need
1000 * quoting because we picked it. oldname needs to
1001 * be quoted only the first time.
1003 char const *old = (first ? qoldname : oldname);
1004 error (0, 0, _("%s: renamed to %s"), old, newname);
1005 first = false;
1007 memcpy (oldname + (base - newname), base, len + 1);
1008 break;
1010 else
1012 /* The rename failed: give up on this length. */
1013 break;
1016 else
1018 /* newname exists, so increment BASE so we use another */
1021 while (incname (base, len));
1022 len--;
1024 if (unlink (oldname) != 0)
1026 error (0, errno, _("%s: failed to remove"), qoldname);
1027 ok = false;
1029 else if (flags->verbose)
1030 error (0, 0, _("%s: removed"), qoldname);
1031 if (0 <= dir_fd)
1033 if (dosync (dir_fd, qdir) != 0)
1034 ok = false;
1035 if (close (dir_fd) != 0)
1037 error (0, errno, _("%s: failed to close"), qdir);
1038 ok = false;
1041 free (newname);
1042 free (dir);
1043 free (qdir);
1044 return ok;
1048 * Finally, the function that actually takes a filename and grinds
1049 * it into hamburger.
1051 * FIXME
1052 * Detail to note: since we do not restore errno to EACCES after
1053 * a failed chmod, we end up printing the error code from the chmod.
1054 * This is actually the error that stopped us from proceeding, so
1055 * it's arguably the right one, and in practice it'll be either EACCES
1056 * again or EPERM, which both give similar error messages.
1057 * Does anyone disagree?
1059 static bool
1060 wipefile (char *name, char const *qname,
1061 struct randint_source *s, struct Options const *flags)
1063 bool ok;
1064 int fd;
1066 fd = open (name, O_WRONLY | O_NOCTTY | O_BINARY);
1067 if (fd < 0
1068 && (errno == EACCES && flags->force)
1069 && chmod (name, S_IWUSR) == 0)
1070 fd = open (name, O_WRONLY | O_NOCTTY | O_BINARY);
1071 if (fd < 0)
1073 error (0, errno, _("%s: failed to open for writing"), qname);
1074 return false;
1077 ok = do_wipefd (fd, qname, s, flags);
1078 if (close (fd) != 0)
1080 error (0, errno, _("%s: failed to close"), qname);
1081 ok = false;
1083 if (ok && flags->remove_file)
1084 ok = wipename (name, qname, flags);
1085 return ok;
1089 /* Buffers for random data. */
1090 static struct randint_source *randint_source;
1092 /* Just on general principles, wipe buffers containing information
1093 that may be related to the possibly-pseudorandom values used during
1094 shredding. */
1095 static void
1096 clear_random_data (void)
1098 randint_all_free (randint_source);
1103 main (int argc, char **argv)
1105 bool ok = true;
1106 struct Options flags = { 0, };
1107 char **file;
1108 int n_files;
1109 int c;
1110 int i;
1111 char const *random_source = NULL;
1113 initialize_main (&argc, &argv);
1114 set_program_name (argv[0]);
1115 setlocale (LC_ALL, "");
1116 bindtextdomain (PACKAGE, LOCALEDIR);
1117 textdomain (PACKAGE);
1119 atexit (close_stdout);
1121 flags.n_iterations = DEFAULT_PASSES;
1122 flags.size = -1;
1124 while ((c = getopt_long (argc, argv, "fn:s:uvxz", long_opts, NULL)) != -1)
1126 switch (c)
1128 case 'f':
1129 flags.force = true;
1130 break;
1132 case 'n':
1134 uintmax_t tmp;
1135 if (xstrtoumax (optarg, NULL, 10, &tmp, NULL) != LONGINT_OK
1136 || MIN (UINT32_MAX, SIZE_MAX / sizeof (int)) < tmp)
1138 error (EXIT_FAILURE, 0, _("%s: invalid number of passes"),
1139 quotearg_colon (optarg));
1141 flags.n_iterations = tmp;
1143 break;
1145 case RANDOM_SOURCE_OPTION:
1146 if (random_source && !STREQ (random_source, optarg))
1147 error (EXIT_FAILURE, 0, _("multiple random sources specified"));
1148 random_source = optarg;
1149 break;
1151 case 'u':
1152 flags.remove_file = true;
1153 break;
1155 case 's':
1157 uintmax_t tmp;
1158 if (xstrtoumax (optarg, NULL, 0, &tmp, "cbBkKMGTPEZY0")
1159 != LONGINT_OK)
1161 error (EXIT_FAILURE, 0, _("%s: invalid file size"),
1162 quotearg_colon (optarg));
1164 flags.size = tmp;
1166 break;
1168 case 'v':
1169 flags.verbose = true;
1170 break;
1172 case 'x':
1173 flags.exact = true;
1174 break;
1176 case 'z':
1177 flags.zero_fill = true;
1178 break;
1180 case_GETOPT_HELP_CHAR;
1182 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1184 default:
1185 usage (EXIT_FAILURE);
1189 file = argv + optind;
1190 n_files = argc - optind;
1192 if (n_files == 0)
1194 error (0, 0, _("missing file operand"));
1195 usage (EXIT_FAILURE);
1198 randint_source = randint_all_new (random_source, SIZE_MAX);
1199 if (! randint_source)
1200 error (EXIT_FAILURE, errno, "%s", quotearg_colon (random_source));
1201 atexit (clear_random_data);
1203 for (i = 0; i < n_files; i++)
1205 char *qname = xstrdup (quotearg_colon (file[i]));
1206 if (STREQ (file[i], "-"))
1208 ok &= wipefd (STDOUT_FILENO, qname, randint_source, &flags);
1210 else
1212 /* Plain filename - Note that this overwrites *argv! */
1213 ok &= wipefile (file[i], qname, randint_source, &flags);
1215 free (qname);
1218 exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
1221 * vim:sw=2:sts=2: