Hello,
There came up another idea/issue about the Phar extension and its
native SSL support.
As you might know or not, when building PHP:
./configure --with-openssl --enable-phar
the Phar extension will get so-called native SSL enabled through
OpenSSL directly. However, when built like this:
./configure --with-openssl=shared --enable-phar=shared
or
./configure --with-openssl=shared --enable-phar
the SSL support will depend on whether the ext/openssl is loaded and
enabled during PHP runtime. SSL support in both cases is done with
different pieces of code (one is using ext/openssl functions and the
other one - native SSL - is using OpenSSL calls directly). Also in
phpinfo output there is a bit of different info given based on the SSL
type.
On Windows there is also a slight inconsistency at the moment where
there is obsolete --enable-phar-native-ssl configure option available
which is using missing libeay32 library.
My first understanding was that native SSL is "better" as it uses
OpenSSL directly but it turned out that the code is outdated:
https://github.com/php/php-src/pull/14578
So, a new suggestion here is to remove the native SSL support in phar
extension in favor of using a PHP openssl extension's API (or better
call it function calls for the time being):
https://github.com/php/php-src/pull/15574
This would make the SSL support in phar more consistent because now
people aren't even aware of this. For example, on Alpine Linux default
packages there is openssl extension used in phar extension and on
Ubuntu's default packages there is this native SSL used.
Does anyone see any issues with removing the native SSL support in
Phar extension? Let me know. Ideally we would remove it in PHP 8.4
otherwise in the version after that...
Hello,
There came up another idea/issue about the Phar extension and its
native SSL support.As you might know or not, when building PHP:
./configure --with-openssl --enable-phar
the Phar extension will get so-called native SSL enabled through
OpenSSL directly. However, when built like this:./configure --with-openssl=shared --enable-phar=shared
or
./configure --with-openssl=shared --enable-pharthe SSL support will depend on whether the ext/openssl is loaded and
enabled during PHP runtime. SSL support in both cases is done with
different pieces of code (one is using ext/openssl functions and the
other one - native SSL - is using OpenSSL calls directly). Also in
phpinfo output there is a bit of different info given based on the SSL
type.On Windows there is also a slight inconsistency at the moment where
there is obsolete --enable-phar-native-ssl configure option available
which is using missing libeay32 library.My first understanding was that native SSL is "better" as it uses
OpenSSL directly but it turned out that the code is outdated:
https://github.com/php/php-src/pull/14578So, a new suggestion here is to remove the native SSL support in phar
extension in favor of using a PHP openssl extension's API (or better
call it function calls for the time being):
https://github.com/php/php-src/pull/15574This would make the SSL support in phar more consistent because now
people aren't even aware of this. For example, on Alpine Linux default
packages there is openssl extension used in phar extension and on
Ubuntu's default packages there is this native SSL used.Does anyone see any issues with removing the native SSL support in
Phar extension? Let me know. Ideally we would remove it in PHP 8.4
otherwise in the version after that...
Extensions referencing other extensions' functions (beyond things mediated
by the PHP runtime like streams) can be tricky depending on the dynamic
linking story.
Dynamic linkers that pull from a general symbol slurry (your typical ld.so
for instance) don't have a problem with it, but some platforms have more
strict linkage, like Windows. IIRC, things like PDO are built into the PHP
executable/library for this reason. I know AIX can actually do it both ways;
I used to build the ld.so style way (they call it "runtime linking"), but it
turns out that causes problems with different versions of symbols (i.e.
OpenSSL 1.1 and 3.0 in same address space), so I had to switch to building it
with the other dynamic linking option, which means I have to make the same
build compromises as on Windows.
As such, it might be a bit tricky for people on Windows/AIX; the easiest
solution if PHAR is using the openssl extension's symbols would be to not
build the openssl extension as shared.
(Sorry for the impromptu lesson on dynamic linking; it's complex, ugly, and I
still don't fully understand the vagaries myself. If you want more details, I
can bury my head in the documentation again. Korrine Adler has an decent
summary of the situation here 1.)
As such, it might be a bit tricky for people on Windows/AIX; the easiest
solution if PHAR is using the openssl extension's symbols would be to not
build the openssl extension as shared.
I've just checked Windows build and the PHP downloaded from PHP.net
and it seems to already use the openssl and phar extensions like this.
The ext/openssl is built as shared (the php_openssl.dll) and phar is
built into the php binary (which doesn't matter much here I think).
So I think this means one platform to worry about this issue here less.
About the AIX it's totally possible that this is still an issue. I'll
need to check it out in more detail at some point. If I understand the
issue mentioned in the blog post it is something else - two different
OpenSSL versions being linked. Which is of course bad. And this
removal is moving towards this direction also. OpenSSL being linked
only in ext/openssl. And in PHP different OpenSSL versions linked
could happen in a few other places as well - the curl, ftp and mysqlnd
extensions.
Well, this issue sounds complicated for PHP 8.4, so we can do it in
the next version then.
Dynamic linkers that pull from a general symbol slurry (your typical ld.so
for instance) don't have a problem with it, but some platforms have more
strict linkage, like Windows. IIRC, things like PDO are built into the PHP
executable/library for this reason. I know AIX can actually do it both ways;
I used to build the ld.so style way (they call it "runtime linking"), but it
turns out that causes problems with different versions of symbols (i.e.
OpenSSL 1.1 and 3.0 in same address space), so I had to switch to building it
with the other dynamic linking option, which means I have to make the same
build compromises as on Windows.
Interesting! Just a the other day I (re-?)learned that there are
usually no "import libraries" (Windows terminology) on Linux, which are
very common on Windows. Such import libraries define stubs (i.e.
wrappers) for all exported symbols; for functions, basically (pseudo-code):
the_function(a, b, c) {
module = dl_load("library.dll")
proc = dl_fetch_symbol(module, "__imp_the_function")
return proc(a, b, c)
}
Might roughly be similar on AIX with "the other dynamic linking option".
As such, it might be a bit tricky for people on Windows/AIX; the easiest
solution if PHAR is using the openssl extension's symbols would be to not
build the openssl extension as shared.
Well, that is not an option for any binaries we build and ship, since
the core is not supposed to rely on any external dependencies (that's
the reason why we still bundle libpcre2 although it is supposed to be
available almost everywhere).
Christoph
Interesting! Just a the other day I (re-?)learned that there are
usually no "import libraries" (Windows terminology) on Linux, which are
very common on Windows. Such import libraries define stubs (i.e.
wrappers) for all exported symbols; for functions, basically (pseudo-code):the_function(a, b, c) {
module = dl_load("library.dll")
proc = dl_fetch_symbol(module, "__imp_the_function")
return proc(a, b, c)
}Might roughly be similar on AIX with "the other dynamic linking option".
There isn't something like import libraries, but rather, the shared libs
are actually .a archive files that contain the .so to load at runtime
(of both bitnesses, as well as being able to do things like pack multiple
SOVERs), plus an import file that specifies the name of the library, the
symbols contained within, etc.
My impression is the runtime loader/linker option basically ignores all
of that infrastructure in favour of something that works like what
commodity Unix has, trading AIX's problems with those problems (i.e. lack
of symbol namespacing). Unfortunately, I'm in a situation where I do need
symbol namespacing, so I'm starting to deal with AIX's problems instead.
Unfortunately, I'm not David Edelsohn.
(I wish ELF-world would get symbol namespacing - it would make shipping
binaries far less spooky to debug. Windows gets this right.)
Well, that is not an option for any binaries we build and ship, since
the core is not supposed to rely on any external dependencies (that's
the reason why we still bundle libpcre2 although it is supposed to be
available almost everywhere).
I didn't know that; it's kinda confusing considering they're all in ext/,
and some vendor (i.e. gd, pcre), but others do not.
Might roughly be similar on AIX with "the other dynamic linking option".
There isn't something like import libraries, but rather, the shared libs
are actually .a archive files that contain the .so to load at runtime
(of both bitnesses, as well as being able to do things like pack multiple
SOVERs), plus an import file that specifies the name of the library, the
symbols contained within, etc.
Ah, thanks! Then this is completely different to Windows.
My impression is the runtime loader/linker option basically ignores all
of that infrastructure in favour of something that works like what
commodity Unix has, trading AIX's problems with those problems (i.e. lack
of symbol namespacing). Unfortunately, I'm in a situation where I do need
symbol namespacing, so I'm starting to deal with AIX's problems instead.
Unfortunately, I'm not David Edelsohn.
:)
Well, that is not an option for any binaries we build and ship, since
the core is not supposed to rely on any external dependencies (that's
the reason why we still bundle libpcre2 although it is supposed to be
available almost everywhere).I didn't know that; it's kinda confusing considering they're all in ext/,
and some vendor (i.e. gd, pcre), but others do not.
It's only about the mandatory extensions, i.e. those you get with
./configure --disable-all (date, hash, json, pcre, random, reflection,
spl and standard). The idea is to be able to have a minimal PHP build
without the need to install any libraries (except, of course, libc and
such).
ext/gd is a different thing; the bundled libgd is only there for BC
reasons (and should have been unbundled years ago, but hasn't due to
missing ZMM support in libgd); on most systems you usually build against
a system libgd, though.
Christoph