-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Segmentation fault on exit when using ldap_bind() #8620
Comments
Looking at the backtrace, it looks like the process segfault during curl extension shutdown calling an openssl cleanup. Could you please provide us the libcurl version, and also the openssl version you're using ? |
Sure thing!
and
And, just for good measure (in case this is some kind of openldap library thing) -
|
Ooooh! Interesting - if I take the |
This might not be a php-src issue at all, but rather a conflict between libcurl and openldap (libsasl?) Anyhow, please focus on PHP 8.0, since PHP 7.4 is no longer actively supported, so wouldn't receive regular bug fixes anyway. And a question: are you using a threaded SAPI? |
If I add As for my focus, I help to run a rather large open source project, so my users often trail on their PHP releases, often for reasons out of their own control. We're dragging them forward as fast as we can. We only just pulled our minimum PHP version up to 7.4 with our latest release :/ |
Thanks for the further info. I was looking for
Since this is a non thread-safe build, there shouldn't be any multi-threading issues. From looking at the stack backtrace, libcurl calls |
Our open-source users can't in most cases, and in the cases where they could, they wouldn't know how to do that. In probably quite a few other cases, they might actually be able to, and know how, but not be allowed by their management. Most of them are just going to use the distro's default version of PHP against their distro's default version of openssl. |
libcurl does no longer call engine_cleanup on recentish versions given that you are not using arcane openssl versions. this is not a PHP bug..you just need to build libcurl against openssl 1.1 and this will go away. |
It's honestly something I talked about with my VP of tech - custom-building our own PHP and curl and various other extensions to avoid this. He's loathe to do it because it means every point release of PHP means yet another build. But if we need to, we can do that. But what do I do for the rest of my open-source users? We guesstimate (it's impossible to know) that we have probably 10x or 100x the number of free, self-hosted, open-source users as we do hosted-by-us users. I don't think they'll have the technical acumen to be able to compile custom builds. As I mentioned before, we also have people who aren't permitted to custom-compile stuff by policy, as well. And in some cases, we have people running on shared infrastructure where they simply don't have access to be able to modify local installations of PHP. Amazon Linux is basically just a slightly tweaked version of CentOS, so this is a pretty large install base. I totally get that openssl 1.0 seems to have been a bit of a nightmare (and a nightmare you folks are trying to forget, for good reason), but I still do believe that folks doing |
Okay, I've checked our OpenSSL requirements: ≥ 1.0.1 for PHP-8.0, ≥ 1.0.2 for PHP-8.1 and master. As such, it is our liability to do something about this. The question is, though, whether we can do something about it (except for documenting this issue). @bukka, thoughts? |
I mean, I have an idea - but I suspect you're not gonna like it :) Is there a way for PHP to not clean up SSL stuff as its tearing itself down? I mean, once the binary actually terminates, isn't everything effectively gone? If it weren't, it would mean everything you control-C a PHP executable it would be leaving stuff around, which I suspect doesn't happen. Anyways, I don't know the codebase and I don't know how the internals work, but just thought I'd throw a janky idea out there... |
Previously we had a similar issue with locking callback but that was freed by PHP so we could fix it. However this seems to be issue with freeing engines which PHP does not do as you can see in https://github.com/php/php-src/blob/PHP-8.0.16/ext/openssl/openssl.c#L1346-L1352 . I checked your version of LDAP https://github.com/openldap/openldap/blob/1c9416493bd219b08d839cd9e93fc64daa89b752/libraries/libldap/tls_o.c#L226-L235 and it also does not free engines either so it is interesting that it is crashing there. I might need to do a bit of digging later to see what is going on. Currently busy with some other things so might take me a little bit of time to get to it. |
I had a proper look into this. I'm able to see the segfault on Amazon Linux 2 for all PHP version. I used remi repo for 8.1 and 8.2 as documented here: https://computingforgeeks.com/how-to-install-php-8-on-amazon-linux/ . It just requires installing
and then executing the script above with ldap_connect and ldap_bind. Considering that Amazon Linux 2 is going to supported till 2024 and there are probably lots of PHP users on it, it is something worth looking. When debugging I noticed that OpenSSL ext adds the rdrand engine so created PR #9767 with potential fix. I tried quite hard to recreate it on Amazon Linux 2 with my own compiled PHP even with shared curl and ldap but it wasn't crashing so cannot verify the fix. But I asked @remicollet to help with that so hopefully he manages to do that. |
I just pushed to the potential fix to 8.2 only for now and will verify once the next RC released and Remi's package available. If all good, then I will backport it to lower branche(s). |
So I just tested that OpenSSL change with the last RC and still see the segfault. After more debugging the added engine is not actually the issue. The problem is different. What happens is that OpenLDAP sets locking callback as can be seen in this backtrace:
Note that I use I'm not really an expert on OpenLDAP but from looking into it I haven't seen a way how to even trigger library destroy that would call I think a bug report should be opened with OpenLDAP. I will leave this issue open if OpenLDAP change is applied or if the maintainer of ldap extension ( @MCMic ) wants to consider a direct clean up of the callback. |
@uberbrady I have been thinking about this a bit more and realised that you can also fix it by prioritising ldap extension in the load process. It means if it loads before curl, then it will unload after curl so the thing that you can do is to just rename PHP ldap ext ini file. For default distro (Amazon Linux 2 in this case) packages it would be:
If you are going to use Remi repo, it would be (this is for PHP 8.2 but if you want PHP 8.1, just
I just tested it and there's no segfault if you do that. It might be worth if @remicollet could change it in the distributed packages. Not sure however how to change it for the main distro package or where to ask for it. Btw this bug impacts all distributions using OpenSSL 1.0.2 and loading ldap after curl - there's nothing Amazon Linux 2 specific here. |
It might make sense to mention that in our php.ini-(development|production) files. There is already a respective comment regarding exif and mbstring. |
Good point. How about #9995 ? |
I just merged the INI changes so now it should be considered as a bug in the distribution as well if it doesn't follow the required order (it should be a bug if distribution loads curl before ldap and uses OpenSSL 1.0.2). |
Problem is that Another workaround is to define This doesn't not affect mod_php (used by default on EL-7), but only cli. BTW, I can only reproduce with PHP 8.2 (not with older PHP version) on CentOS 7 |
Segfault with PHP 8.2.0RC7 on CentOS 7:
So caused by 1ef65c1 Notice: this is on CentOS 7 which includes fixes related to this issue, so, maybe still an issue on amzn2 which case based on EL-7, but which have diverged a lot now. |
At least, for ex with apr On CentOS 7 have apr 1.4.8-7 which includes fixes related to RTLD_DEEPBIND (reported to fix this issue, at least for mod_php), while Amzn2 have 1.7.0-9.amzn2... |
Huh,, That's ugly..indeed that's gonna be a problem .. |
On my system libldap_r is just a symlink to libldap.. isn't that the case of this problematic target ? |
Yes on recent distro
Not in this 8 years old distro. |
That CentOS 7 segfault should be fixed by 3d90a24 . It is not exactly the same thing because the order seems to be different there so it's not triggered by curl but openssl ext. Might be due to using different lib as you noted but not sure. I see segfaults for all versions there. I think Amazon Linux 2 should be still important for us to support as it's default for AWS EC2 and it's heavily used and people most likely want to run latest PHP there. At least it's default when you create EC2 instance in console so we might need to support it (meaning support OpenSSL 1.0.2) for some time - think they extended support to June 2024. |
I confirm 8.2.0RC7 with 3d90a24 doesn't raise segfault anymore (build 22 in my testing repo) on CentOS 7 |
Trying on amzn2 using https://git.remirepo.net/cgit/tools/docker.git/tree/amzn2-php82.dockerfile
|
Yes that's expected as I didn't expect to fix the amzn2 issue because the problem is not in OpenSSL extension but in OpenLDAP as I mentioned above - it basically doesn't offer any way how to clean up the locking callback that it introduces... 😞 |
For what it's worth, our amzn2 issue (running 8.0) was fixed with @bukka 's import re-ordering suggestion: #8620 (comment) Thanks for that! |
Can confirm that this resolved apache php segfaults for me too when using ldap. |
the ordering changed in 3de3e137bf7415fadcde873ca030436998f5b526 |
There is a way to affect loading order for built-in (static) extensions? |
Seems they have extended to June 2025 in the meantime.
No. |
Description
(I'd like to note that while I'm reporting this against PHP 7.4.28, I also saw the problem in PHP 8.0.16)
The following code:
Resulted in this output:
But I expected this output instead:
Removing the
ldap_bind()
statement allows the script to run without segfaulting.When run under GDB, the following backtrace occurs (PHP 7.4):
Here's the backtrace from PHP 8.0:
AWS Linux 2 Hints (if you need them, of course!)
amazon-linux-extras install php7.4
php-ldap
by doingyum install php-ldap
yum remove php-pdo php-ldap php-debuginfo php-common php-mysqlnd php-fpm php-json php-cli
thenamazon-linux-extras disable php7.4
- then you can enable php8.0.gdb
to install debuginfo; if you want symbols in your backtraces you'll want to do that.Please don't hesitate to reach out if there are any further details I can get for you. Thank you!
PHP Version
PHP 7.4.28
Operating System
Amazon Linux 2
The text was updated successfully, but these errors were encountered: