Bug 3548 - Upgrading from openssl-3.0.8 to openssl-3.1.0 leads to version mismatch error
Summary: Upgrading from openssl-3.0.8 to openssl-3.1.0 leads to version mismatch error
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 9.1p1
Hardware: All Linux
: P5 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_9_4
  Show dependency treegraph
 
Reported: 2023-03-15 07:13 AEDT by Sam James
Modified: 2023-03-24 14:00 AEDT (History)
3 users (show)

See Also:


Attachments
Update OpenSSL version check for v3 policy. Remove <1 since we no longer support them. (1.58 KB, patch)
2023-03-15 09:39 AEDT, Darren Tucker
dtucker: ok? (djm)
djm: ok+
Details | Diff
My take (1.39 KB, patch)
2023-03-15 10:14 AEDT, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sam James 2023-03-15 07:13:28 AEDT
OpenSSL 3.0.8 and OpenSSL 3.1.0 both have the same libssl and libcrypto SONAMEs, but after upgrading from 3.0.8->3.1.0, I get:
```
$ ssh -V
OpenSSL version mismatch. Built against 30000080, you have 30100000
```

Is this intentional when the relevant OpenSSL versions are supposed to be ABI compatible?
Comment 1 Sam James 2023-03-15 07:14:42 AEDT
(This is with 9.2_p1).
Comment 2 Darren Tucker 2023-03-15 09:19:10 AEDT
(In reply to Sam James from comment #0)
> the relevant OpenSSL versions are supposed to be ABI compatible?

Looks like OpenSSL changed their compatibility guarantees between 1.1 and 3: https://www.openssl.org/policies/releasestrat.html

"As of release 3.0.0, the OpenSSL versioning scheme is changing to a more contemporary format: MAJOR.MINOR.PATCH

With this format, API/ABI compatibility will be guaranteed for the same MAJOR version number. Previously we guaranteed API/ABI compatibility across the same MAJOR.MINOR combination."

Our check only implements the latter.
Comment 3 Darren Tucker 2023-03-15 09:39:31 AEDT
Created attachment 3684 [details]
Update OpenSSL version check for v3 policy.  Remove <1 since we no longer support them.

I think this will fix it (untested).
Comment 4 Damien Miller 2023-03-15 10:14:31 AEDT
Created attachment 3685 [details]
My take

Don't we still want to prevent backsliding? The OpenSSL page says this:

"MINOR: API/ABI compatible feature releases will change this"

I could interpret this to mean that a minor release could adding API. It would still be API/ABI compatible but only in one direction.
Comment 5 Sam James 2023-03-15 10:15:18 AEDT
Ah, thanks, that makes sense. I thought I remembered 1.0 and 1.1 being incompatible so I knew something had changed, but didn't dig into what yet.

Your patch seems to work and cope with upgrading openssl.
Comment 6 Sam James 2023-03-15 10:23:16 AEDT
(In reply to Damien Miller from comment #4)
> I could interpret this to mean that a minor release could adding
> API. It would still be API/ABI compatible but only in one direction.

This is generally the case for any shared library because of symbol versioning - you often can't upgrade, build a bunch of stuff against the new version, then downgrade it. But openssh has very few dependencies and even fewer which use symbol versioning so, I guess this doesn't come up often.
Comment 7 Darren Tucker 2023-03-15 11:30:21 AEDT
Comment on attachment 3685 [details]
My take

>+        lfix = (libver & 0x0ffffff0L) >> 12;

That's going to include the patchlevel which we previously did not (but since they also say "We also allow backporting of accessor functions in these releases" was that deliberate?  if so is there any point in disallowing this here, since in that case the dynamic linking would fail anyway before we got to this check?)

If we're going to do the same checks we can use the same code.

    if (headerver < 0x3000000f) {
        mask = 0xfff0000fL; /* major,minor,status */
        hfix = (headerver & 0x000ff000) >> 12;
        lfix = (libver & 0x000ff000) >> 12;
    } else {
        mask = 0xf000000fL; /* major, status */
        hfix = (headerver & 0x0ffffff0L) >> 12;
        lfix = (libver & 0x0ffffff0L) >> 12;
    }

    if ( (headerver & mask) == (libver & mask) && lfix >= hfix)
        return 1;
    return 0;

If you ignore the patchlevel for both you could even complement the mask and use that to compute hfix and lfix once, but I think that'd be sufficiently unclear as to be not worth the couple of lines saved.
Comment 8 Darren Tucker 2023-03-15 11:42:44 AEDT
(In reply to Darren Tucker from comment #7)
> since in that case the dynamic linking would fail

actually adding accessors would be fine, only deleting them would be a problem, so I don't see any reason we'd want to include the patchlevel in the check?