[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#247054: Crypto-root patch updated to initrd-tools 0.1.70



Hi!

So, I finally found some time and fixed the problems I had with the newer
initrd-tools. The problem was the introduction of using /sys to locate the
correct major/minor pair for LVM2 devices. I fully agree with whoever made
that change that this is the right thing to do since the minor number might
change across reboot.

Anyways, for this to work with crypto-root it means I had to be able to
locate the backing device's full-name. ie: if cryptsetup is run over
/dev/muffin/root to make /dev/mapper/root, I had to get the symbolic name
'/dev/muffin/root' after examining dmsetup's table for the /dev/mapper/root
which was discovered in /etc/fstab.

The way I solve this at the moment is to look for the entry in a file
called /etc/crypttab. I double and triple check that this value is correct,
and if so, use the symbolic name for the device I find there.

There was one more problem: swap.

Why on earth is swap being configured in the initrd?!
This is totally not the place to do this as far as I can see.
Furthermore, it breaks things since then there may need to be TWO devices
that get decrypted by the initrd --- this interfers with key management.
I had problems b/c I have a swap partition which uses a different crypto key
on every boot.

Anyways, my patch removes the swap support, and adds support for cryptoroot.

I have attached the patch, as well as an updated example of a script which
uses a USB stick to share the keys.

cryptsetup is sitting in NEW.

-- 
Wesley W. Terpstra
--- mkinitrd.orig	2004-06-05 22:54:52.000000000 +0200
+++ mkinitrd.mine	2004-06-05 22:59:28.000000000 +0200
@@ -321,8 +321,90 @@
 	fi
 }
 
+dmcrypt() {
+	local cipher_mode devname submajor subminor
+	
+	if ! command -v cryptsetup > /dev/null 2>&1; then
+		echo Root is on a DM crypt device, but cryptsetup not installed >&2
+	fi
+	
+	cipher_mode=$(dmsetup table $dmname | cut -d" " -f4)
+
+	echo dm-crypt
+	echo $cipher_mode | cut -d- -f1
+
+	devname=$(grep -m 1 "^$dmname[[:space:]]" /etc/crypttab | sed 's/^[^[:space:]]*[[:space:]]\([^[:space:]]*\).*/\1/')
+	if [ ! -b ${devname:-/dev/null} ]; then
+		echo \'$dmname\' does not have a valid block device in /etc/crypttab >&2
+		exit 1
+	fi
+	
+	eval "$(stat -c 'submajor=$((0x%t)); subminor=$((0x%T))' $(readlink -f "$devname"))"
+	
+	if [ $submajor != $(dmsetup deps $dmname | sed 's/^.*(\([0-9]*\), \([0-9]*\))$/\1/') \
+	  -o $subminor != $(dmsetup deps $dmname | sed 's/^.*(\([0-9]*\), \([0-9]*\))$/\2/') ]; then
+		echo /etc/crypttab entry for \'$dmname\' does not agree with dmsetup >&2
+		exit 1
+	fi
+		
+	getroot $devname
+	
+	cat <<EOF >&5
+mount_tmpfs dev2
+
+save_rootdev="\$rootdev"
+save_ROOT="\$ROOT"
+rootdev=$(($submajor*256+$subminor))
+ROOT="$devname"
+get_device
+rootdev="\$save_rootdev"
+ROOT="\$save_ROOT"
+
+export device
+export dmname="$dmname"
+export cipher_mode="$cipher_mode"
+for i in /keyscripts/*; do
+	[ -f "\$i" ] || continue
+	case "\$i" in
+	*.sh)
+		(. \$i)
+		;;
+	*)
+		\$i
+		;;
+	esac
+done
+[ -b /dev/mapper/\$dmname ] || \\
+	/sbin/cryptsetup -c \$cipher_mode create \$dmname \$device
+
+umount -n dev2
+EOF
+	{
+		echo /sbin/cryptsetup
+		echo /lib/libdevmapper.so.1.00
+		echo /lib/libpopt.so.0
+	} >&6
+}
+
 dm() {
-	if command -v lvmiopversion > /dev/null 2>&1; then
+	local dmname
+	
+	if ! command -v dmsetup > /dev/null 2>&1; then
+		echo Root is on a DM device, but dmsetup not installed >&2
+		exit 1
+	fi
+	
+	dmdev=$(printf "(%d, %d)" $major $minor)
+	
+	if ! dmsetup ls | grep -q "$dmdev\$"; then
+		echo Unknown DM device $major:$minor >&2
+		exit 1
+	fi
+	
+	dmname=$(dmsetup ls | grep "$dmdev\$" | sed 's/^\([^[:space:]]*\).*$/\1/')
+	if dmsetup table $dmname | grep -q crypt; then
+		dmcrypt
+	elif command -v lvmiopversion > /dev/null 2>&1; then
 		lvm
 	elif [ ! -x /etc/mkinitrd/scripts/evms ]; then
 		echo Unknown DM device $major:$minor >&2
@@ -608,7 +690,6 @@
 			BEGIN { printf "set -- " }
 			/^#/ { next }
 			$2 == "/" { root = $1; next }
-			$3 == "swap" { printf "'\''%s'\''", $1 }
 			END { print ""; print "root=" root }
 		'
 		root=
@@ -1078,7 +1159,7 @@
 	mv script initrd
 
 	cd initrd
-	mkdir -p dev2 devfs etc mnt proc scripts sys tmp var
+	mkdir -p dev2 devfs etc keyscripts mnt proc scripts sys tmp var
 
 	> etc/mtab
 
#! /bin/bash
modules="usb-storage sd-mod nls_cp437"

mkdir $INITRDDIR/keys
cp /boot/keys/* $INITRDDIR/keys

for mod in $modules; do
  for ko in `modprobe --set-version $VERSION --show-depends $mod | cut -b8-`; do
    install -d $INITRDDIR/${ko%/*}
    install $ko $INITRDDIR/$ko
  done
done

cp /usr/local/bin/xor   $INITRDDIR/bin
cp /usr/local/bin/delay $INITRDDIR/bin

cat <<EOF >$INITRDDIR/keyscripts/usbkeys
modprobe uhci-hcd
modprobe usb-storage
modprobe sd-mod

/bin/dash

for d in	/devfs/scsi/host0/bus0/target0/lun0/part1 \\
		/devfs/scsi/host0/bus0/target0/lun1/disc; do
  if ! mount -n \$d /mnt -o ro -t vfat; then continue; fi
  for i in keys/*; do
    if [ -f /mnt/\${i%.*}.key ]; then
      /bin/xor /mnt/\${i%.*}.key \$i > /dev2/rootkey
    fi
  done
  umount -n /mnt
done

if [ -f /dev2/rootkey ]; then
  /sbin/cryptsetup -d /dev2/rootkey -c \$cipher_mode create \$dmname \$device
fi
EOF

chmod +x $INITRDDIR/keyscripts/usbkeys

Reply to: