This is an automated email from the ASF dual-hosted git repository.
jimjag pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/openoffice.git
The following commit(s) were added to refs/heads/trunk by this push:
new e88c27187f Fix macOS language-pack signing, load-path check and
sysconfig data
e88c27187f is described below
commit e88c27187f2588c2cbaa28304e98e9fcf62910dc
Author: Jim Jagielski <[email protected]>
AuthorDate: Thu Sep 10 12:38:25 2026 -0400
Fix macOS language-pack signing, load-path check and sysconfig data
The load-path check matched each dylib's own @_______ ID and so rejected
every signed build; it now looks only for the CPython staging prefix.
---
main/configure.ac | 6 +--
.../extensions/source/macosx/spotlight/makefile.mk | 4 --
main/python/makefile.mk | 11 +----
main/python/prj/d.lst | 13 ++----
main/setup_native/scripts/mac_install.script | 2 +-
.../scripts/osx_install_languagepack.applescript | 6 +--
.../scripts/osx_install_patch.applescript | 7 +--
main/setup_native/source/mac/macinstall.ulf | 5 ++-
main/solenv/bin/macosx-check-load-commands.sh | 52 ++++++++++++++++++++++
main/solenv/bin/macosx-codesign.sh | 11 +----
main/solenv/bin/modules/installer/simplepackage.pm | 18 +++++---
11 files changed, 86 insertions(+), 49 deletions(-)
diff --git a/main/configure.ac b/main/configure.ac
index 8f10f97b16..ad97ff5ba8 100644
--- a/main/configure.ac
+++ b/main/configure.ac
@@ -987,9 +987,9 @@ AC_ARG_WITH(macosx-codesigning-identity,
Code-sign the macOS application bundle and disk image
while packaging, with this codesign identity
("-" for ad-hoc). Unset: package unsigned, as before.
- Traditional macOS language
packs cannot be installed
- into a signed application
because that would invalidate
- its resource seal.
+ Traditional macOS language packs cannot be installed
+ into a signed application because that would
invalidate
+ its resource seal.
Usage:
--with-macosx-codesigning-identity="Developer ID Application: ..."
],with_macosx_codesigning_identity=$withval,)
diff --git a/main/extensions/source/macosx/spotlight/makefile.mk
b/main/extensions/source/macosx/spotlight/makefile.mk
index 3df817d3ef..475a1a9f71 100644
--- a/main/extensions/source/macosx/spotlight/makefile.mk
+++ b/main/extensions/source/macosx/spotlight/makefile.mk
@@ -83,10 +83,6 @@ $(CONTENTS)$/%.plist : mdimporter/%.plist
$(MACOS)$/OOoSpotlightImporter: $(SLOFILES)
$(MKDIRHIER) $(@:d)
$(CC) -o $(MACOS)$/OOoSpotlightImporter $(SLOFILES:s/.obj/.o/)
$(EXTRA_LINKFLAGS) $(BUNDLELIBS) -bundle
-# we have to change the zlib install name, otherwise the plugin will not work
- .IF "$(SYSTEM_ZLIB)"=="NO"
- install_name_tool -change @executable_path/libz.1.dylib
@loader_path/../../../../../program/libz.1.dylib $(MACOS)$/OOoSpotlightImporter
- .ENDIF
#the resources are just copied
$(RESOURCES)$/% : mdimporter/%
diff --git a/main/python/makefile.mk b/main/python/makefile.mk
index d4e2a038c7..ad196e1455 100644
--- a/main/python/makefile.mk
+++ b/main/python/makefile.mk
@@ -117,20 +117,13 @@ CONFIGURE_ACTION += --disable-ipv6
.ENDIF
BUILD_ACTION=$(ENV_BUILD) $(GNUMAKE) -j$(EXTMAXPROCESS) && $(GNUMAKE) install
&& chmod -R ug+w $(MYCWD)/python-inst && chmod g+w Include
-.IF "$(OS)"=="LINUX"
-# CPython's sysconfig module names its generated data module after the
-# platform/ABI (e.g. _sysconfigdata__linux_x86_64-linux-gnu.py) instead of
-# the plain "_sysconfigdata.py" that main/python/prj/d.lst delivers. Rename
-# it in place so delivery finds the name it's looking for.
-BUILD_ACTION+= && for d in $(MYCWD)/python-inst/lib/python3.11
$(MYCWD)/python-inst/lib64/python3.11; do test -d "$$d" && (cd "$$d" && for f
in _sysconfigdata_*.py; do test -f "$$f" && mv -f "$$f" _sysconfigdata.py;
done); done; true
-.ENDIF
-
.IF "$(OS)"=="MACOSX"
# CPython records its temporary installation prefix in the interpreter's load
# command and the dylib ID. Both files are packaged together in program/.
-BUILD_ACTION+= && (cd $(MYCWD)/python-inst/lib/python3.11 && for f in
_sysconfigdata_*.py; do test -f "$$f" && cp -f "$$f" _sysconfigdata.py; done)
BUILD_ACTION+= && install_name_tool -id @loader_path/libpython3.11.dylib
$(MYCWD)/python-inst/lib/libpython3.11.dylib
BUILD_ACTION+= && install_name_tool -change
$(MYCWD)/python-inst/lib/libpython3.11.dylib
@executable_path/libpython3.11.dylib $(MYCWD)/python-inst/bin/python3.11
+# install_name_tool -change succeeds silently when the old name does not match.
+BUILD_ACTION+= && $(SOLARENV)$/bin$/macosx-check-load-commands.sh
$(MYCWD)/python-inst/bin/python3.11
.ENDIF
.ELSE
diff --git a/main/python/prj/d.lst b/main/python/prj/d.lst
index 09a6045ae2..3170dede93 100644
--- a/main/python/prj/d.lst
+++ b/main/python/prj/d.lst
@@ -96,17 +96,10 @@ mkdir: %_DEST%\inc%_EXT%\python\cpython
..\%__SRC%\misc\build\Python-3.11.15\Lib\xmlrpc\*
%_DEST%\lib%_EXT%\python\xmlrpc\*
..\%__SRC%\misc\build\Python-3.11.15\Lib\zoneinfo\*
%_DEST%\lib%_EXT%\python\zoneinfo\*
..\%__SRC%\misc\build\Python-3.11.15\Makefile
%_DEST%\lib%_EXT%\python\python3.11\config\Makefile
-# _sysconfigdata filename is platform-mangled (e.g.
_sysconfigdata__darwin_darwin.py on macOS,
-# _sysconfigdata__linux_x86_64-linux-gnu.py on Linux). On Linux, makefile.mk's
BUILD_ACTION
-# renames the generated file to the plain name below before delivery runs. The
source below
-# is deliberately NOT a wildcard: deliver.pl's
-# glob_line() only renames-on-copy when the destination also has a wildcard;
paired with a
-# literal destination, a wildcard source makes it treat the destination as a
directory and
-# append the matched filename onto it, producing a bogus nested path.
-..\%__SRC%\misc\build\python-inst\lib\python3.11\_sysconfigdata.py
%_DEST%\lib%_EXT%\python\_sysconfigdata.py
-# Preserve the platform-mangled module that Python's sysconfig imports. Linux
-# renames it above, so this wildcard is effective only where one remains.
+# sysconfig imports the platform-named module (e.g.
_sysconfigdata__darwin_darwin.py) by
+# that name, so it must keep it: with both sides wildcarded, deliver.pl keeps
the filename.
..\%__SRC%\misc\build\python-inst\lib\python3.11\_sysconfigdata_*.py
%_DEST%\lib%_EXT%\python\*.py
+..\%__SRC%\misc\build\python-inst\lib64\python3.11\_sysconfigdata_*.py
%_DEST%\lib%_EXT%\python\*.py
..\pyversion.mk %_DEST%\inc%_EXT%\pyversion.mk
..\pyversion_dmake.mk %_DEST%\inc%_EXT%\pyversion_dmake.mk
diff --git a/main/setup_native/scripts/mac_install.script
b/main/setup_native/scripts/mac_install.script
index 0fc219d9a1..0a8f9068c3 100644
--- a/main/setup_native/scripts/mac_install.script
+++ b/main/setup_native/scripts/mac_install.script
@@ -27,4 +27,4 @@
MY_DIR=$(dirname "$0")
-osascript "$MY_DIR/../osx_install.applescript"
+osascript "$MY_DIR/../Resources/osx_install.applescript"
diff --git a/main/setup_native/scripts/osx_install_languagepack.applescript
b/main/setup_native/scripts/osx_install_languagepack.applescript
index 17b73a8d8f..91610d5839 100644
--- a/main/setup_native/scripts/osx_install_languagepack.applescript
+++ b/main/setup_native/scripts/osx_install_languagepack.applescript
@@ -130,10 +130,10 @@ on error
return 3 --wrong target-directory
end try
--- Adding files below Contents invalidates a sealed application's resource
--- envelope. Refuse rather than silently break a Developer ID or ad-hoc seal.
+-- Adding files below Contents would break a sealed application. Test for the
seal
+-- itself: codesign --display also accepts the linker's ad-hoc signature on
arm64.
try
- do shell script "/usr/bin/codesign --display " & quoted form of (choice
as string)
+ do shell script "test -e " & quoted form of ((choice as string) &
"/Contents/_CodeSignature/CodeResources")
display dialog installSignedFailed buttons {OKLabel} default button 1
with icon 0
return 4
on error
diff --git a/main/setup_native/scripts/osx_install_patch.applescript
b/main/setup_native/scripts/osx_install_patch.applescript
index 634db8ef23..1147956ba6 100644
--- a/main/setup_native/scripts/osx_install_patch.applescript
+++ b/main/setup_native/scripts/osx_install_patch.applescript
@@ -53,7 +53,7 @@ set IdentifyQ to "[IdentifyQText]
set IdentifyYES to "[IdentifyYES]"
set IdentifyNO to "[IdentifyNO]"
set installFailed to "[InstallFailedText]"
-set installSignedFailed to "[InstallSignedFailedText]"
+set installSignedFailed to "[InstallSignedPatchFailedText]"
set installComplete to "[InstallCompleteTextPatch]"
set sourcedir to (do shell script "dirname " & quoted form of POSIX path of
(path to of me))
@@ -128,9 +128,10 @@ on error
return 3 --wrong target-directory
end try
--- A patch changes sealed bundle contents and would invalidate the application.
+-- A patch would break a sealed application. Test for the seal itself: codesign
+-- --display also accepts the linker's ad-hoc signature on arm64.
try
- do shell script "/usr/bin/codesign --display " & quoted form of (choice
as string)
+ do shell script "test -e " & quoted form of ((choice as string) &
"/Contents/_CodeSignature/CodeResources")
display dialog installSignedFailed buttons {OKLabel} default button 1
with icon 0
return 4
on error
diff --git a/main/setup_native/source/mac/macinstall.ulf
b/main/setup_native/source/mac/macinstall.ulf
index a1997f7a96..115df7368e 100644
--- a/main/setup_native/source/mac/macinstall.ulf
+++ b/main/setup_native/source/mac/macinstall.ulf
@@ -59,7 +59,10 @@ en-US = "No, abort installation"
en-US = "Installation failed."
[InstallSignedFailedText]
-en-US = "This add-on cannot modify a signed [PRODUCTNAME] application. Install
a complete language-specific application instead."
+en-US = "This language pack cannot modify a signed [PRODUCTNAME] application.
Install a complete language-specific application instead."
+
+[InstallSignedPatchFailedText]
+en-US = "This patch cannot modify a signed [PRODUCTNAME] application. Install
the complete updated application instead."
[InstallCompleteText]
en-US = "Installation of [PRODUCTNAME] language pack completed."
diff --git a/main/solenv/bin/macosx-check-load-commands.sh
b/main/solenv/bin/macosx-check-load-commands.sh
new file mode 100755
index 0000000000..5f71606388
--- /dev/null
+++ b/main/solenv/bin/macosx-check-load-commands.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+#**************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#**************************************************************
+#
+# Fail when a Mach-O under the given paths still loads from or searches the
+# CPython staging prefix, which does not exist outside the build tree.
+#
+# ./solenv/bin/macosx-check-load-commands.sh <bundle-or-file> ...
+#
+# Unresolved @_______ placeholders are not rejected: gbuild executables such as
+# uno.bin and regcomp.bin still ship them and load only via DYLD_LIBRARY_PATH.
+
+set -euo pipefail
+
+[ $# -gt 0 ] || { echo "usage: $(basename "$0") <bundle-or-file> ..." >&2;
exit 2; }
+
+machos=()
+while IFS= read -r -d '' f && IFS= read -r type; do
+ case "$type" in ": Mach-O"*) machos+=("$f") ;; esac
+done < <(find "$@" -type f -print0 | xargs -0 file --no-pad --print0 --
2>/dev/null)
+[ ${#machos[@]} -gt 0 ] || exit 0
+
+# A dylib's own ID (LC_ID_DYLIB) is never used to locate it at runtime.
+bad=$(printf '%s\0' "${machos[@]}" | xargs -0 otool -l | awk '
+ /^[^[:space:]].*:$/ { file = $0; next }
+ $1 == "cmd" { cmd = $2; next }
+ cmd != "LC_ID_DYLIB" && ($1 == "name" || $1 == "path") && /python-inst/
{
+ print file " " cmd " " $2
+ }')
+if [ -n "$bad" ]; then
+ echo "unrelocated Mach-O load commands:" >&2
+ echo "$bad" >&2
+ exit 1
+fi
diff --git a/main/solenv/bin/macosx-codesign.sh
b/main/solenv/bin/macosx-codesign.sh
index e04a973532..f331c72476 100755
--- a/main/solenv/bin/macosx-codesign.sh
+++ b/main/solenv/bin/macosx-codesign.sh
@@ -145,16 +145,7 @@ sign_app() {
;;
esac
done < <(find "$app" -type f -print0 | xargs -0 file --no-pad --print0
-- 2>/dev/null)
- if [ ${#machos[@]} -gt 0 ]; then
- local bad_load_commands
- bad_load_commands=$(printf '%s\0' "${machos[@]}" | xargs -0
otool -L 2>/dev/null |
- grep -E 'python-inst|@_______' || true)
- if [ -n "$bad_load_commands" ]; then
- echo "unrelocated Mach-O load commands in $app:" >&2
- echo "$bad_load_commands" >&2
- return 1
- fi
- fi
+ "$SRCDIR/macosx-check-load-commands.sh" "$app"
# codesign rewrites a Mach-O through a temporary file beside it, so the
# containing directory has to be writable as well.
if [ ${#machos[@]} -gt 0 ]; then
diff --git a/main/solenv/bin/modules/installer/simplepackage.pm
b/main/solenv/bin/modules/installer/simplepackage.pm
index eb0a342425..4d3da52361 100644
--- a/main/solenv/bin/modules/installer/simplepackage.pm
+++ b/main/solenv/bin/modules/installer/simplepackage.pm
@@ -471,11 +471,14 @@ sub create_package
$installer::logger::Lang->print($infoline);
}
+ # codesign treats loose files in Contents as unsigned
nested code.
+ my $resourcesfolder = $contentsfolder . "/Resources";
my $sourcefile = $appfolder . "/" . $tarballname;
- my $destfile = $contentsfolder . "/" . $tarballname;
+ my $destfile = $resourcesfolder . "/" . $tarballname;
installer::systemactions::remove_complete_directory($contentsfolder);
installer::systemactions::create_directory($contentsfolder);
+
installer::systemactions::create_directory($resourcesfolder);
installer::systemactions::copy_one_file($sourcefile,
$destfile);
unlink($sourcefile);
@@ -502,7 +505,7 @@ sub create_package
my $translationfileref =
installer::scriptitems::get_sourcepath_from_filename_and_includepath(
\$translationfilename, $includepatharrayref, 0);
if ($$translationfileref eq "") {
installer::exiter::exit_program("ERROR: Could not find Apple script translation
file $translationfilename!", "create_package"); }
- $scriptfilename = $contentsfolder . "/" .
$scriptrealfilename;
+ $scriptfilename = $resourcesfolder . "/" .
$scriptrealfilename;
my $macosfolder = $contentsfolder . "/MacOS";
installer::systemactions::create_directory($macosfolder);
$scripthelperrealfilename = $macosfolder . "/" .
$scripthelperrealfilename;
@@ -529,9 +532,7 @@ sub create_package
my $iconfile = "ooo3_installer.icns";
my $iconfileref =
installer::scriptitems::get_sourcepath_from_filename_and_includepath(
\$iconfile, $includepatharrayref, 0);
if ($$iconfileref eq "") {
installer::exiter::exit_program("ERROR: Could not find Apple script icon file
$iconfile!", "create_package"); }
- my $subdir = $contentsfolder . "/" . "Resources";
- if ( ! -d $subdir ) {
installer::systemactions::create_directory($subdir); }
- $destfile = $subdir . "/" . $iconfile;
+ $destfile = $resourcesfolder . "/" . $iconfile;
installer::systemactions::copy_one_file($$iconfileref,
$destfile);
my $infoplistfile = "Info.plist.langpack";
@@ -550,6 +551,13 @@ sub create_package
chdir $localfrom;
}
+ # A build-time load path left in a shipped Mach-O breaks at
runtime, signed or not.
+ foreach my $appdir ( glob("$localtempdir/$folder/*.app") )
+ {
+ my $checkreturn = system($ENV{'SOLARENV'} .
"/bin/macosx-check-load-commands.sh", $appdir);
+ if ( $checkreturn ) {
installer::exiter::exit_program("ERROR: Unrelocated Mach-O load commands in
$appdir!", "create_package"); }
+ }
+
# Code-sign the .app before it is sealed into the .dmg. Opt-in:
without
# MACOSX_CODESIGNING_IDENTITY the installation set is left as
it was.
if ( $ENV{'MACOSX_CODESIGNING_IDENTITY'} )