| 1059 | } |
| 1060 | |
| 1061 | bool |
| 1062 | AbstractProcessManager::validateDebugOffsets( |
| 1063 | const Structure<py_runtime_v>& py_runtime, |
| 1064 | python_v& debug_offsets) const |
| 1065 | { |
| 1066 | // Simple sanity checks on the decoded offsets: |
| 1067 | // - No structure is larger than 1 MB |
| 1068 | // - Every field falls within its structure's size |
| 1069 | #define check_size(pystack_struct, size_offset) \ |
| 1070 | do { \ |
| 1071 | if (debug_offsets.pystack_struct.size > 1024 * 1024) { \ |
| 1072 | LOG(WARNING) << "Ignoring debug offsets because " #pystack_struct ".size (" \ |
| 1073 | << debug_offsets.pystack_struct.size << ") reported at byte offset " \ |
| 1074 | << (d_py_v->py_runtime.*size_offset).offset \ |
| 1075 | << " in detected _Py_DebugOffsets structure at " << std::hex << std::showbase \ |
| 1076 | << py_runtime.getFieldRemoteAddress(&py_runtime_v::o_dbg_off_cookie) \ |
| 1077 | << " is implausibly large"; \ |
| 1078 | return {}; \ |
| 1079 | } \ |
| 1080 | } while (0) |
| 1081 | |
| 1082 | #define check_field_bounds(structure, field) \ |
| 1083 | do { \ |
| 1084 | if (debug_offsets.structure.size < 0 \ |
| 1085 | || (size_t)debug_offsets.structure.size < debug_offsets.structure.field.offset \ |
| 1086 | || debug_offsets.structure.size - debug_offsets.structure.field.offset \ |
| 1087 | < sizeof(decltype(debug_offsets.structure.field)::Type)) \ |
| 1088 | { \ |
| 1089 | LOG(WARNING) << "Ignoring debug offsets because " #structure ".size (" \ |
| 1090 | << debug_offsets.structure.size << ") - " #structure "." #field ".offset (" \ |
| 1091 | << debug_offsets.structure.field.offset << ") < the field's size (" \ |
| 1092 | << sizeof(decltype(debug_offsets.structure.field)::Type) << ")"; \ |
| 1093 | return {}; \ |
| 1094 | } \ |
| 1095 | } while (0) |
| 1096 | |
| 1097 | check_size(py_runtime, &py_runtime_v::o_dbg_off_runtime_state_struct_size); |
| 1098 | check_field_bounds(py_runtime, o_finalizing); |
| 1099 | check_field_bounds(py_runtime, o_interp_head); |
| 1100 | |
| 1101 | check_size(py_is, &py_runtime_v::o_dbg_off_interpreter_state_struct_size); |
| 1102 | check_field_bounds(py_is, o_next); |
| 1103 | check_field_bounds(py_is, o_tstate_head); |
| 1104 | check_field_bounds(py_is, o_gc); |
| 1105 | check_field_bounds(py_is, o_modules); |
| 1106 | check_field_bounds(py_is, o_sysdict); |
| 1107 | check_field_bounds(py_is, o_builtins); |
| 1108 | check_field_bounds(py_is, o_gil_runtime_state); |
| 1109 | |
| 1110 | check_size(py_thread, &py_runtime_v::o_dbg_off_thread_state_struct_size); |
| 1111 | check_field_bounds(py_thread, o_prev); |
| 1112 | check_field_bounds(py_thread, o_next); |
| 1113 | check_field_bounds(py_thread, o_interp); |
| 1114 | check_field_bounds(py_thread, o_frame); |
| 1115 | check_field_bounds(py_thread, o_thread_id); |
| 1116 | check_field_bounds(py_thread, o_native_thread_id); |
| 1117 | |
| 1118 | check_size(py_frame, &py_runtime_v::o_dbg_off_interpreter_frame_struct_size); |
nothing calls this directly
no outgoing calls
no test coverage detected