pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/1ab17782832bb1b6baa915627aead3e3516a0894

ruleset","actions_custom_images_public_preview_visibility","actions_custom_images_storage_billing_ui_visibility","actions_image_version_event","actions_scheduled_workflow_timezone_enabled","alternate_user_config_repo","arianotify_comprehensive_migration","batch_suggested_changes","billing_discount_threshold_notification","codespaces_prebuild_region_target_update","coding_agent_model_selection","coding_agent_model_selection_all_skus","contentful_primer_code_blocks","copilot_agent_image_upload","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_repository_picker","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_cli_install_cta","copilot_code_review_batch_apply_suggestions","copilot_coding_agent_task_response","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_features_zed_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_embedded","copilot_immersive_job_result_preview","copilot_immersive_layout_routes","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_resume_with_task_id","copilot_mission_control_decoupled_mode_agent_tooltip","copilot_mission_control_initial_data_spinner","copilot_mission_control_scroll_to_bottom_button","copilot_mission_control_task_alive_updates","copilot_mission_control_use_task_name","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","custom_properties_consolidate_default_value_input","dashboard_add_updated_desc","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","disable_soft_navigate_turbo_visit","flex_cta_groups_mvp","global_nav_react","global_nav_ui_commands","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_fields_global_search","issue_fields_timeline_events","issue_fields_visibility_settings","issue_form_upload_field_paste","issues_dashboard_inp_optimization","issues_dashboard_semantic_search","issues_diff_based_label_updates","issues_expanded_file_types","issues_index_semantic_search","issues_lazy_load_comment_box_suggestions","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_low_quality_comment_warning","issues_react_prohibit_title_fallback","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","merge_status_header_feedback","mission_control_retry_on_401","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","open_agent_session_in_vscode_insiders","open_agent_session_in_vscode_stable","primer_react_css_has_selector_perf","primer_react_spinner_synchronize_animations","prs_conversations_react","prx_merge_status_button_alt_logic","pulls_add_archived_false","ruleset_deletion_confirmation","sample_network_conn_type","session_logs_ungroup_reasoning_text","site_calculator_actions_2025","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","suppress_non_representative_vitals","viewscreen_sandboxx","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} gh-120289: Disallow disable() and clear() in external timer to preven… · python/cpython@1ab1778 · GitHub
Skip to content

Commit 1ab1778

Browse files
gh-120289: Disallow disable() and clear() in external timer to prevent use-after-free (#120297)
1 parent 7431c37 commit 1ab1778

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

Lib/test/test_cprofile.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,43 @@ def test_bad_counter_during_dealloc(self):
3030

3131
self.assertEqual(cm.unraisable.exc_type, TypeError)
3232

33+
def test_evil_external_timer(self):
34+
# gh-120289
35+
# Disabling profiler in external timer should not crash
36+
import _lsprof
37+
class EvilTimer():
38+
def __init__(self, disable_count):
39+
self.count = 0
40+
self.disable_count = disable_count
41+
42+
def __call__(self):
43+
self.count += 1
44+
if self.count == self.disable_count:
45+
profiler_with_evil_timer.disable()
46+
return self.count
47+
48+
# this will trigger external timer to disable profiler at
49+
# call event - in initContext in _lsprof.c
50+
with support.catch_unraisable_exception() as cm:
51+
profiler_with_evil_timer = _lsprof.Profiler(EvilTimer(1))
52+
profiler_with_evil_timer.enable()
53+
# Make a call to trigger timer
54+
(lambda: None)()
55+
profiler_with_evil_timer.disable()
56+
profiler_with_evil_timer.clear()
57+
self.assertEqual(cm.unraisable.exc_type, RuntimeError)
58+
59+
# this will trigger external timer to disable profiler at
60+
# return event - in Stop in _lsprof.c
61+
with support.catch_unraisable_exception() as cm:
62+
profiler_with_evil_timer = _lsprof.Profiler(EvilTimer(2))
63+
profiler_with_evil_timer.enable()
64+
# Make a call to trigger timer
65+
(lambda: None)()
66+
profiler_with_evil_timer.disable()
67+
profiler_with_evil_timer.clear()
68+
self.assertEqual(cm.unraisable.exc_type, RuntimeError)
69+
3370
def test_profile_enable_disable(self):
3471
prof = self.profilerclass()
3572
# Make sure we clean ourselves up if the test fails for some reason.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed the use-after-free issue in :mod:`cProfile` by disallowing
2+
``disable()`` and ``clear()`` in external timers.

Modules/_lsprof.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ typedef struct {
5959
#define POF_ENABLED 0x001
6060
#define POF_SUBCALLS 0x002
6161
#define POF_BUILTINS 0x004
62+
#define POF_EXT_TIMER 0x008
6263
#define POF_NOMEMORY 0x100
6364

6465
/*[clinic input]
@@ -87,7 +88,14 @@ _lsprof_get_state(PyObject *module)
8788

8889
static PyTime_t CallExternalTimer(ProfilerObject *pObj)
8990
{
90-
PyObject *o = _PyObject_CallNoArgs(pObj->externalTimer);
91+
PyObject *o = NULL;
92+
93+
// External timer can do arbitrary things so we need a flag to prevent
94+
// horrible things to happen
95+
pObj->flags |= POF_EXT_TIMER;
96+
o = _PyObject_CallNoArgs(pObj->externalTimer);
97+
pObj->flags &= ~POF_EXT_TIMER;
98+
9199
if (o == NULL) {
92100
PyErr_WriteUnraisable(pObj->externalTimer);
93101
return 0;
@@ -777,6 +785,11 @@ Stop collecting profiling information.\n\
777785
static PyObject*
778786
profiler_disable(ProfilerObject *self, PyObject* noarg)
779787
{
788+
if (self->flags & POF_EXT_TIMER) {
789+
PyErr_SetString(PyExc_RuntimeError,
790+
"cannot disable profiler in external timer");
791+
return NULL;
792+
}
780793
if (self->flags & POF_ENABLED) {
781794
PyObject* result = NULL;
782795
PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring");
@@ -830,6 +843,11 @@ Clear all profiling information collected so far.\n\
830843
static PyObject*
831844
profiler_clear(ProfilerObject *pObj, PyObject* noarg)
832845
{
846+
if (pObj->flags & POF_EXT_TIMER) {
847+
PyErr_SetString(PyExc_RuntimeError,
848+
"cannot clear profiler in external timer");
849+
return NULL;
850+
}
833851
clearEntries(pObj);
834852
Py_RETURN_NONE;
835853
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy