LUKS meets badblocks

Most linux users know the famous badblocks tutorial because almost every harddrive starts to produce bad sectors at some point in its life. In some cases they correspond to real damages on the platter surfaces, but sometimes the drive logic has just made an error and blocked further reading of the sector. To give the drive a chance to reallocate the sector to unused space OR to rethink its decision (yes, some bad sectors just disappear after this) you will need to overwrite the sector, best with zeroes. Before this, it is always smart to probe the sector for its occupation, and which file it has been assigned to, if so. The tutorial describes a way to do this.

Things get more complicated if the drive in question is encrypted using LUKS, because the encryption system adds its own header to the start of the disk/partition and offsets all data towards the end, while the order of the sectors is left untouched. The workaround is pretty simple!

Let’s assume the device is /dev/sda, with at least one (encrypted) partition inside.

cryptsetup luksDump /dev/sda1

will dump the header information to the terminal, including the “payload offset” in LBA units. Now, if you want to determine the position of the bad sector inside the LUKS drive, you add the starting sector of the affected encrypted partition to its payload offset. Use that number for the “S”-parameter in the first example of the tutorial. From there, continue just as described.

Remember to use the mapped drive (e.g. /dev/mapper/sda1) for all filesystem related commands in the badblocks tutorial. If “fdisk” can’t show you the starting sector of the mapper device partitions, use “parted”:

select /dev/sda1

unit s

print

quit

I double-checked this method by dumping the sector data before and after the change (LUKS and physical) and comparing the contents with a hex editor – the calculation seems to be spot-on.

Another little piece of advice: After determining what damage will occur inside the encrypted partition, zero the sector ONLY on the physical drive and NEVER inside of the encrypted partition. LUKS will encrypt the zeroes to random gibberish, which will sometimes not trigger the sector remapping procedure of the drive. If you zero it on the physical drive instead, it will again be overwritten with valid data the next time you modify its encrypted version.

Also, if you are using a CBC encryption mode and zero the affected 512 byte block on the physical drive, a whole filesystem block (usually 4096 bytes) inside the LUKS partition will become corrupted, caused by CBC’s chained sector encryption scheme. To circumvent this from the start, use the newer LRW or XTS modes.

There IS one downside though. If a defective sector alters the encryption header and there is no header backup or duplicate of the contents – well, then that’s just that. With the header gone, there is no way to restore the contents of the drive! Same thing for your repair attempt – triple-check all dd-commands for typos before executing (especially if you are correctly using -skip or -seek)!

2 thoughts on “LUKS meets badblocks

  1. Thanks, this helped me. I had read about the “error amplification” property in the LUKS FAQ before and thought this meant that there wasn’t a one-to-one sector correspondence, but I guess this was an incorrect assumption.

    One thing that threw me at first was that the badblocks HOWTO assumes all disks have a hardware sector size of 512 bytes, which is not the case for AF disks. My disk had a sector size of 4096, so I had to replace the 512 in the formulas to 4096 for them to work correctly.

Leave a Reply

Your email address will not be published. Required fields are marked *