From ae91e3d552aff4f0e74662d055dae06ea55eb6bc Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Thu, 27 Mar 2014 21:29:04 -0400 Subject: [PATCH] PR16766: kernel crash for failed-init module-notification Suppress the module_notifier callback for cases of failure of the main generated systemtap module-initialization code, which checks build-ids, privileges, etc. etc.; we don't want any module-notifier callbacks after an error. * runtime/transport/transport.c: Don't call module-notifier stuff if initialization failed. * translate.cxx (emit_module_refresh): Emit code to suppress callback payload if somehow the notifier got activated anyway. --- runtime/transport/transport.c | 20 ++++++++++++-------- translate.cxx | 11 +++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index 1800764..e4d4d8e 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -135,16 +135,20 @@ static void _stp_handle_start(struct _stp_msg_start *st) _stp_target = st->target; st->res = systemtap_module_init(); - if (st->res == 0) + if (st->res == 0) { _stp_probes_started = 1; - /* Register the module notifier. */ - if (!_stp_module_notifier_active) { - int rc = register_module_notifier(& _stp_module_notifier_nb); - if (rc == 0) - _stp_module_notifier_active = 1; - else - _stp_warn ("Cannot register module notifier (%d)\n", rc); + /* Register the module notifier ... */ + /* NB: but not if the module_init stuff + failed: something nasty has happened, and + we want no further probing started. PR16766 */ + if (!_stp_module_notifier_active) { + int rc = register_module_notifier(& _stp_module_notifier_nb); + if (rc == 0) + _stp_module_notifier_active = 1; + else + _stp_warn ("Cannot register module notifier (%d)\n", rc); + } } /* Called from the user context in response to a proc diff --git a/translate.cxx b/translate.cxx index 9903751..17dedd4 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1881,8 +1881,19 @@ c_unparser::emit_module_refresh () { o->newline() << "static void systemtap_module_refresh (void) {"; o->newline(1) << "int i=0, j=0;"; // for derived_probe_group use + + /* If we're not in STARTING/RUNNING state, don't try doing any work. + PR16766 */ + o->newline() << "int state = atomic_read (session_state());"; + o->newline() << "if (state != STAP_SESSION_RUNNING && state != STAP_SESSION_STARTING) {"; + // cannot _stp_warn etc. since we're not in probe context + o->newline(1) << "printk (KERN_ERR \"stap module notifier triggered in unexpected state %d\", state);"; + o->newline() << "return;"; + o->newline(-1) << "}"; + o->newline() << "(void) i;"; o->newline() << "(void) j;"; + vector g = all_session_groups (*session); for (unsigned i=0; i