Bug 8540 - macOS doesn't like mixing signed and unsigned bundles
Summary: macOS doesn't like mixing signed and unsigned bundles
Status: CLOSED FIXED
Alias: None
Product: ThinLinc
Classification: Unclassified
Component: Client platforms (show other bugs)
Version: trunk
Hardware: PC Unknown
: P2 Normal
Target Milestone: 4.19.0
Assignee: Pierre Ossman
URL:
Keywords: adaha_tester, prosaic
Depends on:
Blocks:
 
Reported: 2025-03-07 14:45 CET by Pierre Ossman
Modified: 2025-03-11 16:00 CET (History)
1 user (show)

See Also:
Acceptance Criteria:
MUST: * Builds generated from Jenkins should have a different CFBundleIdentifier than released versions * Builds generated by developers by hand should have a different CFBundleIdentifier than released versions * Released versions should have the same CFBundleIdentifier as previous versions SHOULD: * It should be difficult to accidentally generate an unsigned build with the same CFBundleIdentifier as the released versions * It should be difficult to accidentally generate a signed build with the same CFBundleIdentifier as any unsigned build


Attachments

Description Pierre Ossman cendio 2025-03-07 14:45:39 CET
It seems macOS can get confused if you have multiple copies of an application, where some are signed and some are not. The privilege checks will then become unreliably, sometimes denying things that seem to be approved in the system settings.

I don't think we can ever expect this to work fully, as it would be a massive security flaw if unsigned applications could piggy-back on a well known application by using the same bundle id.

We should examine if we could have different bundle ids for our unsigned and signed versions of the client.

Note that this only affects testing and development. Versions of the client released to users should always be signed.
Comment 1 Pierre Ossman cendio 2025-03-07 14:46:10 CET
Two cases where we've seen problems with this is bug 8521, and bug 4660.
Comment 2 Pierre Ossman cendio 2025-03-07 14:53:05 CET
Changing the id is trivial. The difficult part is how we make sure it is always changed back as part of the signature process.

One could have hoped that Apple would prevent us from signing anything with the wrong id. We have to specify our id on their web page when setting up certificates after all.

But I tried signing a bogus id here, and both signing and notarization went through fine.

There might be some protection once you try to run the binary. I didn't try that since I didn't want to end up wedging another id on our lab macOS system.

Fortunately, we have a support script that we always use to do signing and notarization. If we change that script to automatically restore the id, then it should be very unlikely to be overlooked.
Comment 4 Pierre Ossman cendio 2025-03-07 16:15:04 CET
There is one potential risk, and that is this note¹ from Apple:

> Local network privacy uses your main executable UUID as part of its
> implementation. If your main executable has no UUID, or shares a UUID with
> other programs, local network privacy may behave weirdly.

¹ https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy

The UUID should be different between every build, so this will rarely be an issue. But it might be a problem if someone uses a Jenkins build on a device, then signs the very same Jenkins build and uses that signed version on the same device.

Hopefully, this will not happen in practice as we currently only sign the release candidates, and we likely won't do any testing of that build before someone signs and tags it.
Comment 5 Pierre Ossman cendio 2025-03-11 09:07:35 CET
Unsigned and signed builds now use different ids, and the system seems to treat them as separate applications in the permission settings.

> MUST:
> 
>  * Builds generated from Jenkins should have a different CFBundleIdentifier than released versions

It does. We now have an extra "-unsigned" on the id.

>  * Builds generated by developers by hand should have a different CFBundleIdentifier than released versions

Same here. In fact, every build gets this extra suffix.

>  * Released versions should have the same CFBundleIdentifier as previous versions

They should, as the signing script will remove the suffix. If someone signs using some other method, then things will fail. But that is cumbersome, so very unlikely.

> SHOULD:
>
>  * It should be difficult to accidentally generate an unsigned build with the same CFBundleIdentifier as the released versions

It should, as every build will use the "-unsigned" id.

>  * It should be difficult to accidentally generate a signed build with the same CFBundleIdentifier as any unsigned build

Not perfect, as the id is changed by the signing script. But as mentioned, it is unlikely anyone will sign a bundle without using the script.
Comment 6 Adam Halim cendio 2025-03-11 16:00:49 CET
Tested client build 3835 on macOS 15 (x86), and client build of r41588.

I did not have any issues starting any of the clients on the machine.

I had a look in
> Contents/Info.plist
and could see that both jenkins build 3835 and r41588 had the
CFBundleIdentifier set to "se.cendio.tlclient-unsigned".

I then ran ctc/buildtools/bin/sign-macos-iso on both builds and could very that
the "-unsigned" string got removed by the script.

> MUST:
>  * Builds generated from Jenkins should have a different CFBundleIdentifier 
>    than released versions
Indeed, all builds automatically get "-unsigned" appended (which released versions don't have).
>  * Builds generated by developers by hand should have a different 
>    CFBundleIdentifier than released versions
Same as above.
>  * Released versions should have the same CFBundleIdentifier as previous 
>    versions
We sign our macOS ISO manually as part of our release procedure, which will remove the "-unsigned" suffix.

> SHOULD:
>  * It should be difficult to accidentally generate an unsigned build with the 
>    same CFBundleIdentifier as the released versions
Generating a build with the same CFBundleIdentifier as released version now requires deliberate extra manual steps, so this is very unlikely.
>  * It should be difficult to accidentally generate a signed build with the same 
>    CFBundleIdentifier as any unsigned build
This is not impossible, but is not something we generally do without the use of our helper script.

Commit looks good, closing.

Note You need to log in before you can comment on or make changes to this bug.