4

I have two SSD's and on HDD.

When I use sudo dd if=/dev/zero of=/dev/sdd count=1000 good things happen and I erase partitions from my USB flashdrive.

When I use sudo dd if=/dev/zero of=/dev/sdb count=1000 bad things happen and I loose Windows 7 and Ubuntu 14.04 partitions from my 500 GB Hard Disk.

Bad things happened once. How can I prevent dd from doing it again?

ie Check that of= doesn't contain sda, sdb or sdc.

  • 1
    I have seen on many systems including two of mine where I skipped a SATA port. Then when I plug in sdf flash drive it is sdf, but on reboot it becomes sdb and every other drive changes. Some have flash promoted to sda also. So if using device for mounting or editing a drive you must always check first with parted, fdisk or gdisk. – oldfred Jan 06 '17 at 00:15
  • @oldfred Well that is scary... A lsblk should always be run to confirm the drives. Or the perfect answer should confirm UUID's of sda, sdb and sdc and complain if different. – WinEunuuchs2Unix Jan 06 '17 at 00:22
  • 3
    The short answer is be very very careful when invoking dd. It doesn't matter if you create a wrapper script for it; you still need to know exactly what you're doing before running the command. – wjandrea Jan 06 '17 at 00:37
  • The problem isn't not knowing dd the problem is accidentally saying sdb instead of sdd. – WinEunuuchs2Unix Jan 06 '17 at 00:56
  • @oldfred Based on your comment, I enhanced the answer by incorporating a display of drive letters, names and sizes within the dd wrapper script below. Thanks for your observations on changing drive letters. – WinEunuuchs2Unix Jan 06 '17 at 11:31

1 Answers1

4

Create dd wrapper script

Open the terminal using Ctrl+Alt+T. Then call gedit with:

gksu gedit /usr/local/bin/dd

and copy and paste these commands:

#!/bin/bash

# Who called this script?
PARENT_COMMAND="$(ps -o comm= $PPID)"   
if [[ $(id -u) != 0 ]]; then # Only non-root processes enter password (ie "sudo dd ..." is ok)
    echo dd must be called with sudo powers
    exit 1
fi

# log dd usage for audit trails
# log-file '"$PARENT_COMMAND"" - ""$@"' "/var/log/dd-usage"

# Display hints & arguments. Get any key to proceed or <Ctrl>+C to abort
echo "╔════════════════════════════════════════════════════════════════╗"
echo "║                                                                ║"
echo "║                      dd - Data Duplicator                      ║"
echo "║                                                                ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo
echo " Parameter 1 hint: if=/dev/zero"
echo " Parameter 2 hint: of=/dev/sdY where Y cannot be a, b or c"
echo " Parms >2 hints:   bs=512 is default block size"
echo " Parms >2 hints:   count=100 will process 100 blocks"
echo
echo " Use /bin/dd --help for more info (don't use dd --help)"
echo
# Display drive letterss, names and sizes without partitions for guide
lsblk -ido KNAME,TYPE,SIZE,MODEL
echo
echo " Current parameters: "”$@”
echo
echo "      Press <Enter> to continue or <Ctrl>+C to abort."

read ANYKEY

if [[ "$2" != of=* ]]; then
    echo -e "\a" # PC speaker beep or pleasant bell with PulseAudio hooks
    echo "ERROR! Parameter 2 must start with 'of=' (output file=)"
    exit 2
fi

if [[ "$2" =~ "sda" ]]; then
    echo -e "\a" # PC speaker beep or pleasant bell with PulseAudio hooks
    echo "ERROR! Output file (of=) cannot be /dev/sda"
    exit 2
fi

if [[ "$2" =~ "sdb" ]]; then
    echo -e "\a" # PC speaker beep or pleasant bell with PulseAudio hooks
    echo "ERROR! Output file (of=) cannot be /dev/sdb"
    exit 2
fi

if [[ "$2" =~ "sdc" ]]; then
    echo -e "\a" # PC speaker beep or pleasant bell with PulseAudio hooks
    echo "ERROR! Output file (of=) cannot be /dev/sdc"
    exit 2
fi  

# Call REAL dd command with parameters passed to this wrapper sript
/bin/dd "$@"

exit 0

Save the file and exit gedit.

Lastly mark the new dd as executable with:

sudo chmod +x /usr/local/bin/dd

What it looks like

Below is how it appears on your terminal screen when you've called the new dd script without using the protected drives.

$ sudo dd if=/dev/zero of=/dev/sdd bs=512 count=100
╔════════════════════════════════════════════════════════════════╗
║                                                                ║
║                       dd - Data Duplicator                     ║
║                                                                ║
╚════════════════════════════════════════════════════════════════╝

 Parameter 1 hint: if=/dev/zero
 Parameter 2 hint: of=/dev/sdY where Y cannot be a, b or c
 Parms >2 hints:   bs=512 is default block size
 Parms >2 hints:   count=100 will process 100 blocks

 Use /bin/dd --help for more info (don't use dd --help)

KNAME TYPE   SIZE MODEL
sda   disk 223.6G KINGSTON SHSS37A
sdb   disk 465.8G ST9500423AS     
sdc   disk 119.2G KingFast        
sdd   disk  29.8G USB Flash Drive 
sr0   rom   1024M DVD+-RW GT80N   

 Current parameters: 'if=/dev/zero of=/dev/sdd bs=512 count=100'

      Press <Enter> to continue or <Ctrl>+C to abort.

100+0 records in
100+0 records out
51200 bytes (51 kB, 50 KiB) copied, 0.00339331 s, 15.1 MB/s

Notes

Because the wrapper script is located in /usr/local/bin it is called before the regular command stored in /bin.

The second parameter must begin with of= and can not contain sda, sdb or sdc, add more drives to protect or subtract drives depending on your installation.

Line draw characters may not work on older platforms or different character sets. Use "+---+" for top and bottom lines and "|" for middle lines or remove them altogether.

log-file is a script for logging commands to audit files. You can replace it with your own command and un-comment the line by removing the leading #.

  • Recommend putting the script as /usr/local/sbin/dd or /usr/local/bin/dd. They come earlier in the usual PATH than /bin, so either will run instead of /bin/dd, and they won't be overwritten if the coreutils package comes with a new dd binary during some future apt upgrade. Plus things like debsums won't complain. – Chai T. Rex Jan 04 '17 at 03:48
  • @ChaiT.Rex There is a problem with moving to /usr/local/bin because the permissions: drwxr-xr-x 5 are different than /bin which has drwxr-xr-x 2 and unless you are elevated to sudo it appears /bin version is executed automatically. – WinEunuuchs2Unix Jan 05 '17 at 03:21
  • That doesn't happen here. With or without sudo, /usr/local/bin/dd runs. Those permissions look identical (the number after drwxr-xr-x is the number of hardlinks to that directory entry, it's not a part of the permissions). One issue might be if you're using a terminal that started before you created /usr/local/bin/dd or set it executable, it might have cached dd as being in /bin. If that's the case, closing the terminal and reopening should fix it. – Chai T. Rex Jan 05 '17 at 03:29
  • @ChaiT.Rex You are correct. My terminal window had become corrupted with experiments of calling sudo -s followed by exit in test scripts to see if password could be verified and return to user powers. Opening a new window returned behavior to normal. Sorry for inconvenience. – WinEunuuchs2Unix Jan 05 '17 at 03:43
  • 1
    -1 This is a bad idea, for the exact same reason that aliasing rm is a bad idea. – wjandrea Jan 06 '17 at 00:45
  • 1
    I just read an article yesterday recommending alias in .bashrc for rm = rm -i. – WinEunuuchs2Unix Jan 06 '17 at 00:57
  • 1
    Also, checking just $2 is not resilient. E.g. sudo dd count=1000 of=/dev/sda if=/dev/zero is a valid command. – wjandrea Jan 06 '17 at 00:59
  • @WinEunuuchs2Unix Also not a good idea. See here: alias rm=“rm -i” considered harmful? – wjandrea Jan 06 '17 at 01:03
  • I wish we could post that on the article I read yesterday. Too bad I can't remember the link. – WinEunuuchs2Unix Jan 06 '17 at 01:07
  • @wjandrea I found a simple way of ensuring parameter 2 always starts with of= to protect sda, sdb and sdc. Along with revision to display drive letters, mfg. models and drive sizes, all known short comings have been addressed. – WinEunuuchs2Unix Jan 09 '17 at 01:42
  • Welcome to the club "making scripts that wrap a safety belt around dd" :-) - my wrapper is mkusb, https://help.ubuntu.com/community/mkusb – sudodus Jan 10 '17 at 12:15
  • @sudodus Hi. After I wrote my script on a different topic I saw OBI (One Button Installation) stuff you wrote (quite lengthy!) referencing dd wrapper but never actually drilled down into it. I wish I had known beforehand and saved the effort :). Oh BTW still haven't got 17.04 live USB working yet on BIOS format on UEFI machine :( – WinEunuuchs2Unix Jan 10 '17 at 12:45
  • @ WinEunuuchs2Unix, Please tell more details about what does not work in 17.04 - I want to check with mkusb too, and either modify my script or write a bug report. I think the 64-bit iso files should work in both BIOS mode and UEFI mode. And the 32-bit iso files should work in BIOS mode. - By the way, do you think that the BIOS emulator of your UEFI machine could be faulty (not complying to the standard)? – sudodus Jan 10 '17 at 13:14
  • I'm on mobile for 10 hours. I'll post a question with screen shots and link you to it then. – WinEunuuchs2Unix Jan 10 '17 at 13:19
  • Thanks :-) In the meantime I zsynced today's Ubuntu Zesty amd64, cloned it with mkusb-dus (with dd under the hood), and it works live in by 3-4 year old Toshiba laptop in BIOS alias CSM mode (InsydeH2O rev. 3.7, System BIOS version 6.10 EC version 6.00). It works in UEFI mode too in that computer. It boots in my newest computer, an Intel NUC6i3SYH in both BIOS and UEFI modes (Intel Visual BIOS SYSKLi35.86A.0024.2015.1027.2142) – sudodus Jan 10 '17 at 15:06
  • @sudodus Here's the question I posted with the Live USB boot problem: http://askubuntu.com/questions/870452/iso-linux-6-03-error-booting-live-usb Thanks for taking the time to check out the problem. – WinEunuuchs2Unix Jan 11 '17 at 00:37