Description: Fix path_info_len underflow in manage-script-name with trailing-slash mountpoints
 When a request path like /footris exactly matches a mountpoint /footris/
 (after stripping the trailing slash for comparison), the manage-script-name
 code sets script_name_len to 9 (the original mountpoint length including the
 slash) but orig_path_info_len is only 8.  The subtraction
 orig_path_info_len - script_name_len = -1 wraps to 65535 when stored in the
 uint16_t path_info_len field.  Subsequent code then passes iov_len=65535 to
 PyUnicode_DecodeLatin1, which reads far past the end of the allocated buffer.
 On s390x this read crosses into an unmapped page and causes a segfault.
 .
 Fix: when orig_path_info_len is less than script_name_len (the only case
 being the exact-match-without-trailing-slash scenario described above), set
 path_info to an empty string (pointing at the end of the original path_info
 buffer) with path_info_len = 0.
Bug-Debian: https://bugs.debian.org/1133977
Author: Bastian Germann <bage@debian.org>
Forwarded: no
Last-Update: 2026-05-27
---
--- uwsgi.git.orig/core/protocol.c
+++ uwsgi.git/core/protocol.c
@@ -787,8 +787,18 @@
 				best_found = mountpoint_len;
 				wsgi_req->script_name = uwsgi_apps[i].mountpoint;
 				wsgi_req->script_name_len = uwsgi_apps[i].mountpoint_len;
-				wsgi_req->path_info = orig_path_info + wsgi_req->script_name_len;
-				wsgi_req->path_info_len = orig_path_info_len - wsgi_req->script_name_len;
+				/* When the request path equals the mountpoint without its
+				 * trailing slash (e.g. GET /footris against /footris/),
+				 * orig_path_info_len < script_name_len.  Guard against the
+				 * uint16_t underflow that would otherwise set path_info_len
+				 * to 65535 and trigger an out-of-bounds read. */
+				if (orig_path_info_len >= (int)wsgi_req->script_name_len) {
+					wsgi_req->path_info = orig_path_info + wsgi_req->script_name_len;
+					wsgi_req->path_info_len = orig_path_info_len - wsgi_req->script_name_len;
+				} else {
+					wsgi_req->path_info = orig_path_info + orig_path_info_len;
+					wsgi_req->path_info_len = 0;
+				}
 
 				wsgi_req->hvec[wsgi_req->script_name_pos].iov_base = wsgi_req->script_name;
 				wsgi_req->hvec[wsgi_req->script_name_pos].iov_len = wsgi_req->script_name_len;
