diff -Nru cryptsetup-2.7.0/debian/changelog cryptsetup-2.7.0/debian/changelog --- cryptsetup-2.7.0/debian/changelog 2024-03-31 07:30:59.000000000 +0000 +++ cryptsetup-2.7.0/debian/changelog 2024-04-03 06:32:55.000000000 +0000 @@ -1,3 +1,11 @@ +cryptsetup (2:2.7.0-1ubuntu4) noble; urgency=medium + + * Refine proc mounts entries traversal (LP: #2054390) + - d/functions: Backport upstream commit 95fd4be9b4c6: d/functions: + get_mnt_devno(): Speed up execution time on large /proc/mounts. + + -- Chengen Du Wed, 03 Apr 2024 06:32:55 +0000 + cryptsetup (2:2.7.0-1ubuntu3) noble; urgency=medium * No-change rebuild for CVE-2024-3094 diff -Nru cryptsetup-2.7.0/debian/functions cryptsetup-2.7.0/debian/functions --- cryptsetup-2.7.0/debian/functions 2024-02-29 13:13:21.000000000 +0000 +++ cryptsetup-2.7.0/debian/functions 2024-04-03 06:32:49.000000000 +0000 @@ -605,41 +605,59 @@ # Return 0 on success, 1 on error (if $mountpoint is not a mountpoint). # devno will be empty if the filesystem must be excluded. get_mnt_devno() { - local wantmount="$1" devnos="" uuid dev IFS - local spec mountpoint fstype _ DEV MAJ MIN + local wantmount="$1" devnos="" uuid dev + local out spec fstype DEV MAJ MIN - while IFS=" " read -r spec mountpoint fstype _; do - # treat lines starting with '#' as comments; /proc/mounts - # doesn't seem to contain these but per procfs(5) the format of - # that file is analogous to fstab(5)'s - if [ "${spec#\#}" = "$spec" ] && [ -n "$spec" ] && - [ "$(printf '%b' "$mountpoint")" = "$wantmount" ]; then - # take the last mountpoint if used several times (shadowed) - unset -v devnos - spec="$(printf '%b' "$spec")" - fstype="$(printf '%b' "$fstype")" - if [ "$fstype" = "zfs" ]; then - # Ignore ZFS entries as they don't have a major/minor and won't - # be imported when local-top cryptroot script will ran. - # Returns success with empty devno - printf '' - return 0 - fi - _resolve_device "$spec" || continue # _resolve_device() already warns on error - if [ "$fstype" = "btrfs" ]; then - # btrfs can span over multiple devices - if uuid="$(_device_uuid "$DEV")"; then - for dev in "/sys/fs/$fstype/$uuid/devices"/*/dev; do - devnos="${devnos:+$devnos }$(cat "$dev")" - done - else - cryptsetup_message "ERROR: $spec: Couldn't determine UUID" - fi - elif [ -n "$fstype" ]; then - devnos="$MAJ:$MIN" + # use awk rather than a `while read; do done` loop here as /proc/mounts + # can be many thousands lines long and the `read` builtin goes one + # read(2) at the time which slows down execution time, see MR !36 + out="$(awk -v mp="$wantmount" -- ' + BEGIN { + FS = "[ \t]" + ret = "" + } + !/^\s*(#|$)/ { + # decode octal sequences; per procfs(5) the format of /proc/mounts + # is analogous to fstab(5) + head = "" + while (match($2, /\\[0-7]{3}/)) { + oct = substr($2, RSTART+1, RLENGTH-1) + dec = (substr(oct, 1, 1) * 8 + substr(oct, 2, 1)) * 8 + substr(oct, 3, 1) + head = head substr($2, 1, RSTART-1) sprintf("%c", dec) + $2 = substr($2, RSTART+RLENGTH) + } + if (head $2 == mp) { + # take the last mountpoint if used several times (shadowed) + ret = $1 " " $3 + } + } + END { + print ret + }'