Fix crash on untrusted XMLRPC connections

Root cause: network.rpc.use_xmlrpc and network.rpc.use_jsonrpc were not
marked as untrusted-safe, but RpcManager::process() calls them before
dispatching to the protocol handler. When an untrusted request arrived,
call_command() threw untrusted_error for these gatekeepers, which escaped
the callback_interrupt_pollling callback and crashed rtorrent.

Fix: Mark network.rpc.use_xmlrpc/jsonrpc as safe (CMD2_VAR_BOOL_U).

Also harden exception safety:
- SCGI callback catch-all now sends a generic error response instead of
  re-throwing, since the callback infrastructure may not support
  exception propagation.
- xmlrpc_c.cc now has catch(std::exception&) and catch(...) safety nets
  after the specific exception handlers.
This commit is contained in:
Xirvik
2026-03-01 18:24:24 +00:00
committed by Jari Sundell
parent f767053297
commit ea16276773
3 changed files with 22 additions and 3 deletions
+12 -1
View File
@@ -3,6 +3,7 @@
#include "rpc/scgi_task.h"
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <vector>
#include <sys/types.h>
@@ -315,7 +316,17 @@ SCgiTask::receive_call(const char* buffer, uint32_t length) {
});
} catch (...) {
rpc::RpcManager::set_trusted(true);
throw;
// Send a generic error response instead of re-throwing, as the
// callback infrastructure may not support exception propagation.
const char* err_xml = "<?xml version=\"1.0\"?><methodResponse><fault><value><struct>"
"<member><name>faultCode</name><value><i8>-500</i8></value></member>"
"<member><name>faultString</name><value><string>Internal error</string></value></member>"
"</struct></value></fault></methodResponse>";
const char* err_json = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32603,\"message\":\"Internal error\"},\"id\":null}";
const char* err = (rpc_type == RpcManager::RPCType::JSON) ? err_json : err_xml;
result_callback(err, std::strlen(err));
return;
}
rpc::RpcManager::set_trusted(true);