Hi Stuart,

On Thu, Apr 16, 2020 at 11:53:19AM +0100, Stuart Henderson wrote:
> Rather than downloading it and deleting it again, it would be more
> useful if BUILDINFO was kept around after installing. Then sysupgrade
> could check to make sure it isn't going backwards with a future update.
> (e.g. if some malicious mirror or mitm intentionally serves an old
> snapshot [with a good signature] to prevent users getting a security
> fix).
> 
> I started looking at this a while ago and have had this in my tree (I'd
> forgotten about until I just did a cvs up) - maybe worth some more thought 
> (it's not super-robust but I'm not sure if it needs to be..) ENOTIME to
> look at it more now though.

I really like it. I've looked into miniroot directory to implement
bsd.rd part needed for sysupgrade(8) changes. Diff at the end of this
email.

> Index: usr.sbin/sysupgrade/sysupgrade.sh
> ===================================================================
> RCS file: /cvs/src/usr.sbin/sysupgrade/sysupgrade.sh,v
> retrieving revision 1.37
> diff -u -p -r1.37 sysupgrade.sh
> --- usr.sbin/sysupgrade/sysupgrade.sh 26 Jan 2020 22:08:36 -0000      1.37
> +++ usr.sbin/sysupgrade/sysupgrade.sh 16 Apr 2020 10:40:37 -0000
> @@ -131,6 +131,7 @@ cd ${SETSDIR}
>  
>  echo "Fetching from ${URL}"
>  unpriv -f SHA256.sig ftp -N sysupgrade -Vmo SHA256.sig ${URL}SHA256.sig
> +unpriv -f BUILDINFO ftp -N sysupgrade -Vmo BUILDINFO ${URL}BUILDINFO
>  
>  _KEY=openbsd-${_KERNV[0]%.*}${_KERNV[0]#*.}-base.pub
>  _NEXTKEY=openbsd-${NEXT_VERSION%.*}${NEXT_VERSION#*.}-base.pub
> @@ -147,11 +148,26 @@ esac
>  unpriv -f SHA256 signify -Ve -p "${SIGNIFY_KEY}" -x SHA256.sig -m SHA256
>  rm SHA256.sig
>  
> +unpriv cksum -qC SHA256 BUILDINFO
> +
>  if cmp -s /var/db/installed.SHA256 SHA256 && ! $FORCE; then
>       echo "Already on latest snapshot."
>       exit 0
>  fi
>  
> +if [[ -r /var/db/installed.BUILDINFO ]] && ! $FORCE; then
> +     read _skip _skip _oldbuildtime _skip < /var/db/installed.BUILDINFO
> +     read _skip _skip _newbuildtime _skip < BUILDINFO
> +     if [[ $_newbuildtime -lt $_oldbuildtime ]]; then
> +             echo "Snapshot on mirror is older than installed version!"
> +             exit 1
> +     fi
> +     if [[ $_newbuildtime -eq $_oldbuildtime ]]; then
> +             echo "Already on latest snapshot? Mismatch between BUILDINFO 
> and SHA256?"
> +             exit 1
> +     fi
> +fi
> +
>  # INSTALL.*, bsd*, *.tgz
>  SETS=$(sed -n -e 's/^SHA256 (\(.*\)) .*/\1/' \
>      -e '/^INSTALL\./p;/^bsd/p;/\.tgz$/p' SHA256)
> @@ -187,9 +203,14 @@ Set name(s) = done
>  Directory does not contain SHA256.sig. Continue without verification = yes
>  __EOT
>  
> +# XXX should be done in bsd.rd so that this is present for a clean install 
> too
> +cat <<__EOT > /etc/rc.firsttime
> +cp /home/_sysupgrade/BUILDINFO /var/db/installed.BUILDINFO
> +__EOT
> +
>  if ! ${KEEP}; then
>       CLEAN=$(echo SHA256 ${SETS} | sed -e 's/ /,/g')
> -     cat <<__EOT > /etc/rc.firsttime
> +     cat <<__EOT >> /etc/rc.firsttime
>  rm -f /home/_sysupgrade/{${CLEAN}}
>  __EOT
>  fi
> 

A bit of explanation with `cat -n install.sub | expand -t 2`


  1599  
  1600      # Fetch and verify the set files.
  1601      for _f in BUILDINFO $_get_sets; do
  1602        $UU && reset_watchdog
  1603  

I've put BUILDINFO, but I guess it could be added directly to
$_get_sets. However I think it needs to be added after baseXX.tgz set,
so directory /var/db is created before ftp tries to copy it into
/mnt/var/db.

  1663  
  1664    # Install the set files.
  1665    for _f in $_get_sets BUILDINFO; do
  1666      $UU && reset_watchdog
  1667      _fsrc="$_src/$_f"

I'm adding it at the end here, to make sure it's before baseXX.tgz, per
above explanation about /var/db.

  1672      # Extract the set files and put the kernel files in place.
  1673      case $_f in

I just need a basename of the set and I think using $_f doesn't
introduce any breakage.

I've tested below diff by fresh install of OpenBSD on amd64. It works
for me, file /mnt/var/db/installed.BUILDINFO is created during install
and after reboot file /var/db/installed.BUILDINFO is present on disk.

Here is output of the part which diff modifies:

Set name(s)? (or 'abort' or 'done') [done]
Get/Verify SHA256.sig   100% |**************************|  2141       00:00
Signature Verified
Get/Verify BUILDINFO    100% |**************************|    54       00:00
Get/Verify bsd          100% |**************************| 18117 KB    02:30
Get/Verify bsd.rd       100% |**************************| 10109 KB    00:29
Get/Verify base67.tgz   100% |**************************|   238 MB    13:57
Get/Verify comp67.tgz   100% |**************************| 74451 KB    02:54
Get/Verify man67.tgz    100% |**************************|  7464 KB    00:19
Get/Verify game67.tgz   100% |**************************|  2745 KB    00:07
Get/Verify xbase67.tgz  100% |**************************| 22912 KB    00:58
Get/Verify xshare67.tgz 100% |**************************|  4499 KB    00:10
Get/Verify xfont67.tgz  100% |**************************| 39342 KB    01:30
Get/Verify xserv67.tgz  100% |**************************| 16767 KB    00:32
Installing bsd          100% |**************************| 18117 KB    00:01
Installing bsd.rd       100% |**************************| 10109 KB    00:00
Installing base67.tgz   100% |**************************|   238 MB    00:28
Extracting etc.tgz      100% |**************************|   261 KB    00:00
Installing comp67.tgz   100% |**************************| 74451 KB    00:17
Installing man67.tgz    100% |**************************|  7464 KB    00:03
Installing game67.tgz   100% |**************************|  2745 KB    00:00
Installing xbase67.tgz  100% |**************************| 22912 KB    00:04
Extracting xetc.tgz     100% |**************************|  7023       00:00
Installing xshare67.tgz 100% |**************************|  4499 KB    00:03
Installing xfont67.tgz  100% |**************************| 39342 KB    00:06
Installing xserv67.tgz  100% |**************************| 16767 KB    00:02
Installing BUILDINFO    100% |**************************|    54       00:00
Location of sets? (disk http nfs or 'done') [done]


Index: distrib/miniroot/install.sub
===================================================================
RCS file: /cvs/src/distrib/miniroot/install.sub,v
retrieving revision 1.1150
diff -u -p -u -r1.1150 install.sub
--- distrib/miniroot/install.sub        5 Apr 2020 15:15:42 -0000       1.1150
+++ distrib/miniroot/install.sub        9 May 2020 22:29:49 -0000
@@ -1598,7 +1598,7 @@ install_files() {
                        _issue="Signature check of SHA256.sig failed" && break
 
                # Fetch and verify the set files.
-               for _f in $_get_sets; do
+               for _f in BUILDINFO $_get_sets; do
                        $UU && reset_watchdog
 
                        rm -f /tmp/h /tmp/fail
@@ -1662,7 +1662,7 @@ install_files() {
        fi
 
        # Install the set files.
-       for _f in $_get_sets; do
+       for _f in $_get_sets BUILDINFO; do
                $UU && reset_watchdog
                _fsrc="$_src/$_f"
 
@@ -1670,7 +1670,7 @@ install_files() {
                [[ -f $_tmpsrc/$_f ]] && _fsrc="file://$_tmpsrc/$_f"
 
                # Extract the set files and put the kernel files in place.
-               case $_fsrc in
+               case $_f in
                *.tgz)  $_unpriv ftp -D Installing -Vmo - "$_fsrc" |
                                tar -zxphf - -C /mnt &&
                        if [[ $_f == ?(x)base*.tgz && $MODE == install ]]; then
@@ -1678,6 +1678,11 @@ install_files() {
                                file:///mnt/var/sysmerge/${_f%%base*}etc.tgz |
                                tar -zxphf - -C /mnt
                        fi
+                       ;;
+               BUILDINFO)
+                       # Keep BUILDINFO for sysupgrade(8).
+                       $_unpriv ftp -D Installing -Vmo - \
+                               "$_fsrc" >"/mnt/var/db/installed.BUILDINFO"
                        ;;
                *)      # Make a backup of the existing ramdisk kernel in the
                        # bsd.rd only download/verify/install case.

-- 
Regards,
 Mikolaj

Reply via email to