xref: /aosp_15_r20/external/vboot_reference/scripts/image_signing/make_dev_ssd.sh (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1#!/bin/sh
2#
3# Copyright 2012 The ChromiumOS Authors
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7# This script can change key (usually developer keys) and kernel config
8# of kernels on an disk image (usually for SSD but also works for USB).
9
10SCRIPT_BASE="$(dirname "$0")"
11. "$SCRIPT_BASE/common_minimal.sh"
12load_shflags || exit 1
13
14# Constants used by DEFINE_*
15VBOOT_BASE='/usr/share/vboot'
16DEFAULT_KEYS_FOLDER="$VBOOT_BASE/devkeys"
17DEFAULT_PARTITIONS='2 4'
18
19# Only store backup in stateful partition if available.
20if [ -d /mnt/stateful_partition ]; then
21  DEFAULT_BACKUP_FOLDER="/mnt/stateful_partition"
22else
23  DEFAULT_BACKUP_FOLDER="$(pwd)"
24fi
25DEFAULT_BACKUP_FOLDER="${DEFAULT_BACKUP_FOLDER}/cros_sign_backups"
26
27# TODO(hungte) The default image selection is no longer a SSD, so the script
28# works more like "make_dev_image".  We may change the file name in future.
29ROOTDEV="$(rootdev -s 2>/dev/null)"
30ROOTDEV_PARTITION="$(echo $ROOTDEV | sed -n 's/.*[^0-9]\([0-9][0-9]*\)$/\1/p')"
31ROOTDEV_DISK="$(rootdev -s -d 2>/dev/null)"
32ROOTDEV_KERNEL="$((ROOTDEV_PARTITION - 1))"
33
34# DEFINE_string name default_value description flag
35DEFINE_string image "$ROOTDEV_DISK" "Path to device or image file" "i"
36DEFINE_string keys "$DEFAULT_KEYS_FOLDER" "Path to folder of dev keys" "k"
37DEFINE_boolean remove_rootfs_verification \
38  "${FLAGS_FALSE}" "Modify kernel boot config to disable rootfs verification" \
39  "r"
40DEFINE_boolean enable_earlycon "${FLAGS_FALSE}" \
41  "Enable earlycon from stdout-path (ARM/ARM64) or SPCR (x86)." ""
42DEFINE_boolean disable_earlycon "${FLAGS_FALSE}" \
43  "Disable earlycon." ""
44DEFINE_boolean enable_console "${FLAGS_FALSE}" \
45  "Enable serial console." ""
46DEFINE_boolean disable_console "${FLAGS_FALSE}" \
47  "Disable serial console." ""
48DEFINE_string backup_dir \
49  "$DEFAULT_BACKUP_FOLDER" "Path of directory to store kernel backups" ""
50DEFINE_string save_config "" \
51  "Base filename to store kernel configs to, instead of resigning." ""
52DEFINE_string set_config "" \
53  "Base filename to load kernel configs from" ""
54DEFINE_boolean edit_config "${FLAGS_FALSE}" \
55  "Edit kernel config in-place." ""
56DEFINE_string partitions "" \
57  "List of partitions to examine (default: $DEFAULT_PARTITIONS)" ""
58DEFINE_boolean recovery_key "$FLAGS_FALSE" \
59  "Use recovery key to sign image (to boot from USB)" ""
60DEFINE_boolean force "$FLAGS_FALSE" \
61  "Skip validity checks and make the change" "f"
62DEFINE_boolean default_rw_root "${FLAGS_TRUE}" \
63  "When --remove_rootfs_verification is set, change root mount option to RW." ""
64DEFINE_boolean enable_proc_mem_ptrace "${FLAGS_TRUE}" \
65  "When --remove_rootfs_verification is set, allow ptracers to write proc/mem" \
66  ""
67# If neither --enable_kdump nor --disable_kdump was provided, the enablement
68# status won't be changed.
69DEFINE_boolean enable_kdump "${FLAGS_FALSE}" \
70  "Enable Kdump." ""
71DEFINE_boolean disable_kdump "${FLAGS_FALSE}" \
72  "Disable Kdump." ""
73
74# Parse command line
75FLAGS "$@" || exit 1
76ORIGINAL_CMD="$0"
77ORIGINAL_PARAMS="$@"
78eval set -- "$FLAGS_ARGV"
79ORIGINAL_PARTITIONS="$FLAGS_partitions"
80: ${FLAGS_partitions:=$DEFAULT_PARTITIONS}
81
82# Globals
83# ----------------------------------------------------------------------------
84set -e
85
86# a log file to keep the output results of executed command
87EXEC_LOG="$(make_temp_file)"
88
89# Functions
90# ----------------------------------------------------------------------------
91
92# Removes rootfs verification from kernel boot parameter
93# And strip out bootcache args if it exists
94remove_rootfs_verification() {
95  local new_root="PARTUUID=%U/PARTNROFF=1"
96  # the first line in sed is to strip out bootcache details
97  local rw_root_opt="s| ro | rw |"
98  if [ "${FLAGS_default_rw_root}" = "${FLAGS_FALSE}" ]; then
99    rw_root_opt="s| rw | ro |"
100  fi
101
102  local ptracer_opt="proc_mem.restrict_write=ptracer proc_mem.force_override=ptrace"
103  # This is kept for compatibility with ChromeOS kernels until all of them
104  # are up-to-date with the corresponding stable branch.
105  ptracer_opt="${ptracer_opt} proc_mem.restrict_foll_force=ptracer"
106  if [ "${FLAGS_enable_proc_mem_ptrace}" = "${FLAGS_FALSE}" ]; then
107    # we could set proc_mem.restrict_write=all, however that's already default
108    # via Kconfig and we don't want to clutter the cmdline with redundant params
109    ptracer_opt=""
110  fi
111
112  echo "$* chromiumos.allow_overlayfs ${ptracer_opt}" | sed '
113    s| dm=\"2 [^"]*bootcache[^"]* vroot | dm=\"1 vroot |
114    s| root=/dev/dm-[0-9] | root='"$new_root"' |
115    s| dm_verity.dev_wait=1 | dm_verity.dev_wait=0 |
116    s| payload=PARTUUID=%U/PARTNROFF=1 | payload=ROOT_DEV |
117    s| hashtree=PARTUUID=%U/PARTNROFF=1 | hashtree=HASH_DEV |
118    '"${rw_root_opt}"
119}
120
121remove_legacy_boot_rootfs_verification() {
122  # See src/scripts/create_legacy_bootloader_templates
123  local image="$1"
124  local mount_point="$(make_temp_dir)"
125  local config_file
126  debug_msg "Removing rootfs verification for legacy boot configuration."
127  mount_image_partition "$image" 12 "$mount_point" || return $FLAGS_FALSE
128  config_file="$mount_point/efi/boot/grub.cfg"
129  [ ! -f "${config_file}" ] ||
130    sudo sed -i -e 's/^ *defaultA=2 *$/defaultA=0/g' \
131                -e 's/^ *defaultB=3 *$/defaultB=1/g' "${config_file}"
132  config_file="$mount_point/syslinux/default.cfg"
133  [ ! -f "$config_file" ] ||
134    sudo sed -i 's/-vusb/-usb/g; s/-vhd/-hd/g' "$config_file"
135  sudo umount "$mount_point"
136}
137
138# Enable/Disable earlycon or serial console
139insert_parameter() {
140  local cmdline="$1"
141  local param="$2"
142
143  if [ -n "${cmdline##*${param}*}" ]; then
144    cmdline="${param} ${cmdline}"
145  fi
146
147  echo "${cmdline}"
148}
149
150remove_parameter() {
151  local cmdline="$1"
152  local param="$2"
153
154  cmdline=$(echo "${cmdline}" | \
155    sed -E 's/(^|\s)\s*'"${param}"'(=\S*|="(\\"|[^"])*")?\s*/\1/g');
156
157  echo "${cmdline}"
158}
159
160# Wrapped version of dd
161mydd() {
162  # oflag=sync is safer, but since we need bs=512, syncing every block would be
163  # very slow.
164  dd "$@" >"$EXEC_LOG" 2>&1 ||
165    die "Failed in [dd $*], Message: $(cat "${EXEC_LOG}")"
166}
167
168# Prints a more friendly name from kernel index number
169cros_kernel_name() {
170  case $1 in
171    2)
172      echo "Kernel A"
173      ;;
174    4)
175      echo "Kernel B"
176      ;;
177    6)
178      echo "Kernel C"
179      ;;
180    *)
181      echo "Partition $1"
182  esac
183}
184
185find_valid_kernel_partitions() {
186  local part_id
187  local valid_partitions=""
188  for part_id in $*; do
189    local name="$(cros_kernel_name $part_id)"
190    local kernel_part="$(make_partition_dev "$FLAGS_image" "$part_id")"
191    if [ -z "$(futility dump_kernel_config "$kernel_part" 2>"$EXEC_LOG")" ]; then
192      info "${name}: no kernel boot information, ignored." >&2
193    else
194      [ -z "$valid_partitions" ] &&
195        valid_partitions="$part_id" ||
196        valid_partitions="$valid_partitions $part_id"
197      continue
198    fi
199  done
200  debug_msg "find_valid_kernel_partitions: [$*] -> [$valid_partitions]"
201  echo "$valid_partitions"
202}
203
204# Resigns a kernel on SSD or image.
205resign_ssd_kernel() {
206  local ssd_device="$1"
207  local bs="$(blocksize "${ssd_device}")"
208
209  # `fflash` and `cros flash` write their updates to block device partitions,
210  # while this script uses the parent block device plus a block offset.
211  # Sync and flush the page cache to avoid cache aliasing issues.
212  sync; sync; sync
213  if [ -w /proc/sys/vm/drop_caches ]; then
214    echo 1 > /proc/sys/vm/drop_caches
215  fi
216
217  # reasonable size for current kernel partition
218  local min_kernel_size=$((8000 * 1024 / bs))
219  local resigned_kernels=0
220
221  for kernel_index in $FLAGS_partitions; do
222    local old_blob="$(make_temp_file)"
223    local new_blob="$(make_temp_file)"
224    local name="$(cros_kernel_name $kernel_index)"
225    local rootfs_index="$(($kernel_index + 1))"
226
227    debug_msg "Probing $name information"
228    local offset size
229    offset="$(partoffset "$ssd_device" "$kernel_index")" ||
230      die "Failed to get partition ${kernel_index} offset from ${ssd_device}"
231    size="$(partsize "$ssd_device" "$kernel_index")" ||
232      die "Failed to get partition ${kernel_index} size from ${ssd_device}"
233    if [ ! $size -gt $min_kernel_size ]; then
234      info "${name} seems too small (${size}), ignored."
235      continue
236    fi
237
238    debug_msg "Reading $name from partition $kernel_index"
239    mydd if="$ssd_device" of="$old_blob" bs=$bs skip=$offset count=$size
240
241    debug_msg "Checking if $name is valid"
242    local kernel_config
243    if ! kernel_config="$(futility dump_kernel_config "$old_blob" 2>"$EXEC_LOG")"; then
244      debug_msg "dump_kernel_config error message: $(cat "$EXEC_LOG")"
245      info "${name}: no kernel boot information, ignored."
246      continue
247    fi
248
249    if [ -n "${FLAGS_save_config}" ]; then
250      # Save current kernel config
251      local old_config_file
252      old_config_file="${FLAGS_save_config}.$kernel_index"
253      info "Saving ${name} config to ${old_config_file}"
254      echo "$kernel_config" > "$old_config_file"
255      # Just save; don't resign
256      continue
257    fi
258
259    if [ -n "${FLAGS_set_config}" ]; then
260      # Set new kernel config from file
261      local new_config_file
262      new_config_file="${FLAGS_set_config}.$kernel_index"
263      kernel_config="$(cat "$new_config_file")" ||
264        die "Failed to read new kernel config from ${new_config_file}"
265      debug_msg "New kernel config: $kernel_config)"
266      info "${name}: Replaced config from ${new_config_file}"
267    fi
268
269    if [ "${FLAGS_edit_config}" = ${FLAGS_TRUE} ]; then
270      debug_msg "Editing kernel config file."
271      local new_config_file="$(make_temp_file)"
272      echo "${kernel_config}" >"${new_config_file}"
273      local old_md5sum="$(md5sum "${new_config_file}")"
274      "${EDITOR}" "${new_config_file}"
275      kernel_config="$(cat "${new_config_file}")"
276      if [ "$(md5sum "${new_config_file}")" = "${old_md5sum}" ]; then
277        info "${name}: Config not changed."
278      else
279        debug_msg "New kernel config: ${kernel_config})"
280        info "${name}: Config updated"
281      fi
282    fi
283
284    if [ ${FLAGS_remove_rootfs_verification} = $FLAGS_FALSE ]; then
285      debug_msg "Bypassing rootfs verification check"
286    else
287      debug_msg "Changing boot parameter to remove rootfs verification"
288      kernel_config="$(remove_rootfs_verification "$kernel_config")"
289      debug_msg "New kernel config: $kernel_config"
290      info "${name}: Disabled rootfs verification."
291      remove_legacy_boot_rootfs_verification "$ssd_device"
292    fi
293
294    if [ "${FLAGS_enable_earlycon}" = "${FLAGS_TRUE}" ]; then
295      debug_msg "Enabling earlycon"
296      kernel_config="$(insert_parameter "${kernel_config}" "earlycon")"
297      debug_msg "New kernel config: ${kernel_config}"
298    elif [ "${FLAGS_disable_earlycon}" = "${FLAGS_TRUE}" ]; then
299      debug_msg "Disabling earlycon"
300      kernel_config="$(remove_parameter "${kernel_config}" "earlycon")"
301      debug_msg "New kernel config: ${kernel_config}"
302    fi
303
304    if [ "${FLAGS_enable_console}" = "${FLAGS_TRUE}" ]; then
305      debug_msg "Enabling serial console"
306      kernel_config="$(remove_parameter "${kernel_config}" "console")"
307      debug_msg "New kernel config: ${kernel_config}"
308    elif [ "${FLAGS_disable_console}" = "${FLAGS_TRUE}" ]; then
309      debug_msg "Disabling serial console"
310      kernel_config="$(insert_parameter "${kernel_config}" "console=")"
311      debug_msg "New kernel config: ${kernel_config}"
312    fi
313
314    if [ "${FLAGS_enable_kdump}" = "${FLAGS_TRUE}" ]; then
315      debug_msg "Enabling kdump"
316      kernel_config="$(insert_parameter "${kernel_config}" "crashkernel=256M")"
317      debug_msg "New kernel config: ${kernel_config}"
318    elif [ "${FLAGS_disable_kdump}" = "${FLAGS_TRUE}" ]; then
319      debug_msg "Disabling kdump"
320      kernel_config="$(remove_parameter "${kernel_config}" "crashkernel")"
321      debug_msg "New kernel config: ${kernel_config}"
322    fi
323
324    local new_kernel_config_file
325    new_kernel_config_file="$(make_temp_file)"
326    printf %s "${kernel_config}" >"${new_kernel_config_file}"
327
328    debug_msg "Re-signing $name from $old_blob to $new_blob"
329    debug_msg "Using key: $KERNEL_DATAKEY"
330    futility vbutil_kernel \
331      --repack "$new_blob" \
332      --keyblock "$KERNEL_KEYBLOCK" \
333      --config "$new_kernel_config_file" \
334      --signprivate "$KERNEL_DATAKEY" \
335      --oldblob "$old_blob" >"$EXEC_LOG" 2>&1 ||
336      die "Failed to resign ${name}. Message: $(cat "${EXEC_LOG}")"
337
338    debug_msg "Creating new kernel image (vboot+code+config)"
339    local new_kern="$(make_temp_file)"
340    cp "$old_blob" "$new_kern"
341    mydd if="$new_blob" of="$new_kern" conv=notrunc
342
343    if is_debug_mode; then
344      debug_msg "for debug purposes, check *.dbgbin"
345      cp "$old_blob" old_blob.dbgbin
346      cp "$new_blob" new_blob.dbgbin
347      cp "$new_kern" new_kern.dbgbin
348    fi
349
350    debug_msg "Verifying new kernel and keys"
351    futility vbutil_kernel \
352      --verify "$new_kern" \
353      --signpubkey "$KERNEL_PUBKEY" --verbose >"$EXEC_LOG" 2>&1 ||
354      die "Failed to verify new ${name}. Message: $(cat "${EXEC_LOG}")"
355
356    debug_msg "Backup old kernel blob"
357    local backup_date_time="$(date +'%Y%m%d_%H%M%S')"
358    local backup_name="$(echo "$name" | sed 's/ /_/g; s/^K/k/')"
359    local backup_file_name="${backup_name}_${backup_date_time}.bin"
360    local backup_file_path="$FLAGS_backup_dir/$backup_file_name"
361    if mkdir -p "$FLAGS_backup_dir" &&
362      cp -f "$old_blob" "$backup_file_path"; then
363      info "Backup of ${name} is stored in: ${backup_file_path}"
364    else
365      warn "Cannot create file in ${FLAGS_backup_dir} ... Ignore backups."
366    fi
367
368    debug_msg "Writing $name to partition $kernel_index"
369    mydd \
370      if="$new_kern" \
371      of="$ssd_device" \
372      seek=$offset \
373      bs=$bs \
374      count=$size \
375      conv=notrunc
376    resigned_kernels=$(($resigned_kernels + 1))
377
378    debug_msg "Make the root file system writable if needed."
379    # TODO(hungte) for safety concern, a more robust way would be to:
380    # (1) change kernel config to ro
381    # (2) check if we can enable rw mount
382    # (3) change kernel config to rw
383    if [ ${FLAGS_remove_rootfs_verification} = $FLAGS_TRUE ]; then
384      local root_offset_sector=$(partoffset "$ssd_device" $rootfs_index)
385      local root_offset_bytes=$((root_offset_sector * bs))
386      if ! is_ext2 "$ssd_device" "$root_offset_bytes"; then
387        debug_msg "Non-ext2 partition: $ssd_device$rootfs_index, skip."
388      elif ! rw_mount_disabled "$ssd_device" "$root_offset_bytes"; then
389        debug_msg "Root file system is writable. No need to modify."
390      else
391        # disable the RO ext2 hack
392        debug_msg "Disabling rootfs ext2 RO bit hack"
393        enable_rw_mount "$ssd_device" "$root_offset_bytes" >"$EXEC_LOG" 2>&1 ||
394          die "Failed turning off rootfs RO bit. OS may be corrupted. " \
395              "Message: $(cat "${EXEC_LOG}")"
396      fi
397    fi
398
399    # `fflash` and `cros flash` write their updates to block device partitions,
400    # while this script uses the parent block device plus a block offset.
401    # Sync and flush the page cache to avoid cache aliasing issues.
402    sync; sync; sync
403    if [ -w /proc/sys/vm/drop_caches ]; then
404      echo 1 > /proc/sys/vm/drop_caches
405    fi
406
407    info "${name}: Re-signed with developer keys successfully."
408  done
409
410  # If we saved the kernel config, exit now so we don't print an error
411  if [ -n "${FLAGS_save_config}" ]; then
412    info "(Kernels have not been resigned.)"
413    exit 0
414  fi
415
416  return $resigned_kernels
417}
418
419validity_check_crossystem_flags() {
420  debug_msg "crossystem validity check"
421  if [ -n "${FLAGS_save_config}" ]; then
422    debug_msg "not resigning kernel."
423    return
424  fi
425
426  if [ "$(crossystem dev_boot_signed_only)" = "0" ]; then
427    debug_msg "dev_boot_signed_only not set - safe."
428    return
429  fi
430
431  echo "
432  ERROR: YOUR FIRMWARE WILL ONLY BOOT SIGNED IMAGES.
433
434  Modifying the kernel or root filesystem will result in an unusable system.  If
435  you really want to make this change, allow the firmware to boot self-signed
436  images by running:
437
438    sudo -E crossystem dev_boot_signed_only=0
439
440  before re-executing this command.
441  "
442  return $FLAGS_FALSE
443}
444
445validity_check_live_partitions() {
446  debug_msg "Partition validity check"
447  if [ "$FLAGS_partitions" = "$ROOTDEV_KERNEL" ]; then
448    debug_msg "only for current active partition - safe."
449    return
450  fi
451  if [ "$ORIGINAL_PARTITIONS" != "" ]; then
452    debug_msg "user has assigned partitions - provide more info."
453    info "Making change to ${FLAGS_partitions} on ${FLAGS_image}."
454    return
455  fi
456  echo "
457  ERROR: YOU ARE TRYING TO MODIFY THE LIVE SYSTEM IMAGE $FLAGS_image.
458
459  The system may become unusable after that change, especially when you have
460  some auto updates in progress. To make it safer, we suggest you to only
461  change the partition you have booted with. To do that, re-execute this command
462  as:
463
464    sudo -E $ORIGINAL_CMD $ORIGINAL_PARAMS --partitions $ROOTDEV_KERNEL
465
466  If you are sure to modify other partition, please invoke the command again and
467  explicitly assign only one target partition for each time  (--partitions N )
468  "
469  return $FLAGS_FALSE
470}
471
472validity_check_live_firmware() {
473  debug_msg "Firmware compatibility validity check"
474  if [ "$(crossystem mainfw_type)" = "developer" ]; then
475    debug_msg "developer type firmware in active."
476    return
477  fi
478  debug_msg "Loading firmware to check root key..."
479  local rootkey_file="$(make_temp_file)"
480  info "checking system firmware..."
481  futility gbb -g --flash --rootkey="$rootkey_file" >/dev/null 2>&1
482  if [ ! -s "$rootkey_file" ]; then
483    debug_msg "failed to read root key from system firmware..."
484  else
485    # The magic 130 is counted by "od dev-rootkey" for the lines until the body
486    # of key is reached. Trailing bytes (0x00 or 0xFF - both may appear, and
487    # that's why we need to skip them) are started at line 131.
488    # TODO(hungte) compare with rootkey in $VBOOT_BASE directly.
489    local rootkey_hash="$(od "$rootkey_file" |
490                          head -130 | md5sum |
491                          sed 's/ .*$//' )"
492    if [ "$rootkey_hash" = "a13642246ef93daaf75bd791446fec9b" ]; then
493      debug_msg "detected DEV root key in firmware."
494      return
495    else
496      debug_msg "non-devkey hash: $rootkey_hash"
497    fi
498  fi
499
500  echo "
501  ERROR: YOU ARE NOT USING DEVELOPER FIRMWARE, AND RUNNING THIS COMMAND MAY
502  THROW YOUR CHROMEOS DEVICE INTO UN-BOOTABLE STATE.
503
504  You need to either install developer firmware, or change system root key.
505
506   - To install developer firmware: type command
507     sudo -E chromeos-firmwareupdate --mode=todev
508
509   - To change system rootkey: disable firmware write protection (a hardware
510     switch) and then type command:
511     sudo -E $SCRIPT_BASE/make_dev_firmware.sh
512
513  If you are sure that you want to make such image without developer
514  firmware or you've already changed system root keys, please run this
515  command again with --force paramemeter:
516
517     sudo -E $ORIGINAL_CMD --force $ORIGINAL_PARAMS
518  "
519  return $FLAGS_FALSE
520}
521
522validity_check() {
523  validity_check_live_partitions || return $FLAGS_FALSE
524
525  # Remaining checks depend on firmware; skip if device is running in a VM.
526  if crossystem 'inside_vm?1'; then
527    debug_msg "Device is a VM, skipping firmware checks"
528    return $FLAGS_TRUE
529  fi
530  if crossystem 'mainfw_type?nonchrome'; then
531    debug_msg "Device is nonchrome, skipping firmware checks"
532    return $FLAGS_TRUE
533  fi
534
535  validity_check_live_firmware || return $FLAGS_FALSE
536  validity_check_crossystem_flags || return $FLAGS_FALSE
537  return $FLAGS_TRUE
538}
539
540# Main
541# ----------------------------------------------------------------------------
542main() {
543  local num_signed=0
544  local num_given=$(echo "$FLAGS_partitions" | wc -w)
545  # Check parameters
546  if [ "$FLAGS_recovery_key" = "$FLAGS_TRUE" ]; then
547    KERNEL_KEYBLOCK="$FLAGS_keys/recovery_kernel.keyblock"
548    KERNEL_DATAKEY="$FLAGS_keys/recovery_kernel_data_key.vbprivk"
549    KERNEL_PUBKEY="$FLAGS_keys/recovery_key.vbpubk"
550  else
551    KERNEL_KEYBLOCK="$FLAGS_keys/kernel.keyblock"
552    KERNEL_DATAKEY="$FLAGS_keys/kernel_data_key.vbprivk"
553    KERNEL_PUBKEY="$FLAGS_keys/kernel_subkey.vbpubk"
554  fi
555
556  debug_msg "Prerequisite check"
557  ensure_files_exist \
558    "$KERNEL_KEYBLOCK" \
559    "$KERNEL_DATAKEY" \
560    "$KERNEL_PUBKEY" \
561    "$FLAGS_image" ||
562    exit 1
563
564  # checks for running on a live system image.
565  if [ "${FLAGS_image}" = "${ROOTDEV_DISK}" ]; then
566    # Log the operartions and the parameters passed to the script
567    # when the device is changing itself
568    logger -p NOTICE "executing ${ORIGINAL_CMD}" \
569                     "with the following parameters: ${ORIGINAL_PARAMS}"
570
571    debug_msg "check valid kernel partitions for live system"
572    local valid_partitions="$(find_valid_kernel_partitions $FLAGS_partitions)"
573    [ -n "$valid_partitions" ] ||
574      die "No valid kernel partitions on ${FLAGS_image} (${FLAGS_partitions})."
575    FLAGS_partitions="$valid_partitions"
576
577    # Validity checks
578    if [ "$FLAGS_force" = "$FLAGS_TRUE" ]; then
579      echo "
580      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
581      ! INFO: ALL VALIDITY CHECKS WERE BYPASSED. YOU ARE ON YOUR OWN. !
582      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
583      " >&2
584      local i
585      for i in $(seq 5 -1 1); do
586        echo -n "\rStart in $i second(s) (^C to abort)...  " >&2
587        sleep 1
588      done
589      echo ""
590    elif ! validity_check; then
591      die "IMAGE ${FLAGS_image} IS NOT MODIFIED."
592    fi
593  fi
594
595  resign_ssd_kernel "$FLAGS_image" || num_signed=$?
596
597  debug_msg "Complete."
598  if [ $num_signed -gt 0 -a $num_signed -le $num_given ]; then
599    # signed something at least
600    info "Successfully re-signed ${num_signed} of ${num_given} kernel(s)" \
601      " on device ${FLAGS_image}."
602    info "Please remember to reboot before updating the kernel on this device."
603  else
604    die "Failed re-signing kernels."
605  fi
606}
607
608# People using this to process images may forget to add "-i",
609# so adding parameter check is safer.
610if [ "$#" -gt 0 ]; then
611  flags_help
612  die "Unknown parameters: $*"
613fi
614
615main
616