[php-src] Issue #9961: PHP 8.1 bug, segfault executing Wordpress plugin code
| From: | PELock | Date: | Tue, 15 Nov 2022 23:44:35 +0000 |
| Subject: | [php-src] Issue #9961: PHP 8.1 bug, segfault executing Wordpress plugin code | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242829@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/9961
Author: PELock
### Description
I found segfaults in my syslog executing faulty code from php8.1 binary on Debian 11 bullseye
@oerdnj
```
PHP 8.1.12 (cli) (built: Oct 28 2022 18:32:13) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.12, Copyright (c) Zend Technologies
with Zend OPcache v8.1.12, Copyright (c), by Zend Technologies
```
SYSLOG multiple events from this one single script:
```
Nov 15 23:29:01 myserver CRON[503265]: (secnews) CMD (/usr/bin/php8.1 -d memory_limit=-1 -d
max_execution_time=0 /home/secnews/www/public_html/secnews.pl/wp-cron.php > /dev/null 2>&1
#manualny cron)
Nov 15 23:29:05 myserver kernel: [707155.142182] php-fpm8.1[454279]: segfault at 38 ip
00005566b94d5ac7 sp 00007ffd2f0cb550 error 4 in php-fpm8.1[5566b9253000+2f1000]
Nov 15 23:29:05 myserver kernel: [707155.144532] Code: d4 55 48 89 fd 53 48 89 cb 48 83 ec 58 4c 8b
77 10 64 48 8b 04 25 28 00 00 00 48 89 44 24 48 31 c0 48 85 c9 0f 84 99 01 00 00 <4c> 3b 31 0f
85 90 01 00 00 48 8b 79 08 48 85 ff >
Nov 15 23:29:05 myserver mariadbd[445538]: 2022-11-15 23:29:05 41264 [Warning] Aborted connection
41264 to db: 'secnews' user: 'secnews' host:
```
I've checked the php8.1 binary and the code sequence from the syslog
d4 55 48 89 fd 53 48
89... is ONLY found in this single routine:
```
.text:000000000036C650 public zend_std_has_property
.text:000000000036C650 zend_std_has_property proc near ; CODE XREF: sub_1283E0+9B?j
.text:000000000036C650 ; sub_1283E0+BC?p
.text:000000000036C650 ; sub_1E1D40+2F?p
.text:000000000036C650 ; sub_1E20B0+34?p
.text:000000000036C650 ; sub_1E2510+34?p
.text:000000000036C650 ; sub_1E2510+64?j
.text:000000000036C650 ; sub_1E2850+38?p
.text:000000000036C650 ; sub_1E3160+34?p
.text:000000000036C650 ; DATA XREF: LOAD:000000000000C400?o
.text:000000000036C650 ; .data.rel.ro:0000000000540F48?o
.text:000000000036C650
.text:000000000036C650 var_80 = qword ptr -80h
.text:000000000036C650 var_78 = qword ptr -78h
.text:000000000036C650 var_6C = dword ptr -6Ch
.text:000000000036C650 var_68 = byte ptr -68h
.text:000000000036C650 var_58 = qword ptr -58h
.text:000000000036C650 var_50 = dword ptr -50h
.text:000000000036C650 var_40 = qword ptr -40h
.text:000000000036C650
.text:000000000036C650 ; FUNCTION CHUNK AT .text:0000000000121A2F SIZE 00000007 BYTES
.text:000000000036C650
.text:000000000036C650 ; __unwind {
.text:000000000036C650 41 57 push r15
.text:000000000036C652 41 56 push r14
.text:000000000036C654 41 55 push r13
.text:000000000036C656 49 89 F5 mov r13, rsi
.text:000000000036C659 41 54 push r12
.text:000000000036C65B 41 89 D4 mov r12d, edx <--------------- HERE IT EXECUTES IN THE MIDDLE OF
THE OPCODE
.text:000000000036C65E 55 push rbp
.text:000000000036C65F 48 89 FD mov rbp, rdi
.text:000000000036C662 53 push rbx
.text:000000000036C663 48 89 CB mov rbx, rcx
.text:000000000036C666 48 83 EC 58 sub rsp, 58h
.text:000000000036C66A 4C 8B 77 10 mov r14, [rdi+10h]
.text:000000000036C66E 64 48 8B 04 25 28 00 00+ mov rax, fs:28h
.text:000000000036C66E 00
.text:000000000036C677 48 89 44 24 48 mov [rsp+88h+var_40], rax
```
THE PROBLEM IS ITS EXECUTING CODE FROM WITHIN THE INSTRUCTION!!! AND ITS UD# INSTRUCTION THUS
SEGFAULT
```
?.00000000`0036C65D: D4 #UD(64)
```
I suspect it could be either PHP bug, CPU bug or faulty RAM. I'm not even sure how the RIP gets
there or how to debug it further
lscpu output
```
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
Address sizes: 48 bits physical, 48 bits virtual
CPU(s): 16
On-line CPU(s) list: 0-15
Thread(s) per core: 1
Core(s) per socket: 16
Socket(s): 1
NUMA node(s): 1
Vendor ID: AuthenticAMD
CPU family: 23
Model: 1
Model name: AMD EPYC 7601 32-Core Processor
Stepping: 2
CPU MHz: 2199.998
BogoMIPS: 4401.32
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 1 MiB
L1i cache: 1 MiB
L2 cache: 8 MiB
L3 cache: 16 MiB
NUMA node0 CPU(s): 0-15
Vulnerability Itlb multihit: Not affected
Vulnerability L1tf: Not affected
Vulnerability Mds: Not affected
Vulnerability Meltdown: Not affected
Vulnerability Mmio stale data: Not affected
Vulnerability Retbleed: Mitigation; untrained return thunk; SMT disabled
Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer
sanitization
Vulnerability Spectre v2: Mitigation; Retpolines, IBPB conditional, STIBP disabled, RSB
filling, PBRSB-eIBRS Not affected
Vulnerability Srbds: Not affected
Vulnerability Tsx async abort: Not affected
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm rep_good nopl cpuid
extd_apicid tsc_known_freq pni pclmulq
dq ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt
tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm cmp_legacy cr8_legacy abm sse4a
misalignsse 3dnowprefetch osvw perfctr_core ssbd ibpb vm
mcall fsgsbase tsc_adjust bmi1 avx2 smep bmi2 rdseed adx smap
clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero xsaveerptr virt_ssbd arat arch_capabilities
```
The faulty code I believe is from Wordpress plugin TaxoPress https://wordpress.org/plugins/simple-tags/
I found it via my nginx logs:
```
2022/11/15 00:21:19 [error] 448832#448832: *895729 FastCGI sent in stderr: "PHP message: PHP
Warning: Undefined property: stdClass::$publish in
/home/secnews/www/public_html/secnews.pl/wp-content/plugins/simple-tags/inc/class.client.aut
oterms.php on line 480" while reading response header from upstream, client: xxxxxxx, server:
www.secnews.pl, request: "POST /wp-json/wp/v2/posts/3398?_locale=user HTTP/2.0", upstream:
"fastcgi://unix:/var/run/php8.1-fpm.secnews.s
ock:", host: "www.secnews.pl", referrer: "https://www.secnews.pl/wp-admin/post.php?post=3398&action=edit"
```
And the actual code from class.client.autoterms.php is
```php
$current_logs_count = wp_count_posts('taxopress_logs')->publish;
```
from
```php
public static function update_taxopress_logs( $object, $taxonomy = 'post_tag',
$options = array(), $counter = false, $action = 'save_posts', $component =
'st_autoterms', $terms_to_add = [], $status = 'failed', $status_message = >
if (get_option('taxopress_autoterms_logs_disabled')) {
return;
}
$insert_post_args = array(
'post_author' => get_current_user_id(),
'post_title' => $object->post_title,
'post_content' => $object->post_content,
'post_status' => 'publish',
'post_type' => 'taxopress_logs',
);
$post_id = wp_insert_post($insert_post_args);
update_post_meta($post_id, '_taxopress_log_post_id', $object->ID);
update_post_meta($post_id, '_taxopress_log_taxonomy', $taxonomy);
update_post_meta($post_id, '_taxopress_log_post_type',
get_post_type($object->ID));
update_post_meta($post_id, '_taxopress_log_action', $action);
update_post_meta($post_id, '_taxopress_log_component', $component);
update_post_meta($post_id, '_taxopress_log_terms', implode (", ",
$terms_to_add));
update_post_meta($post_id, '_taxopress_log_status', $status);
update_post_meta($post_id, '_taxopress_log_status_message', $status_message);
update_post_meta($post_id, '_taxopress_log_options', $options);
update_post_meta($post_id, '_taxopress_log_option_id', $options['ID']);
//for performance reason, delete only 1 posts if more than limit instead of querying all
posts
$auto_terms_logs_limit = (int)get_option('taxopress_auto_terms_logs_limit', 1000);
$current_logs_count = wp_count_posts('taxopress_logs')->publish;
<------------ BUGGY CODE
if((int)$current_logs_count > $auto_terms_logs_limit){
$posts = get_posts(array(
'post_type' => 'taxopress_logs',
'post_status' => 'publish',
'posts_per_page' => 1,
'orderby' => 'ID',
'order' => 'ASC',
'fields' => 'ids'
));
if(count($posts) > 0){
foreach($posts as $post){
wp_delete_post($post, true);
}
}
}
```
### PHP Version
PHP 8.1
### Operating System
Debian 11 bullseye