Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix heap corruption when calling ub_ctx_delete in Windows #1157

Merged
merged 3 commits into from
Nov 1, 2024

Conversation

lnzhu
Copy link
Contributor

@lnzhu lnzhu commented Oct 17, 2024

ub_ctx_delete in libunbound causes heap corruption exception in Windows OS. This issue is only for Windows and discovered when using the lastest libunbound Windows library published here.

  • ub_ctx_delete stops worker thread by ub_stop_bg.
  • When the workder thread exits, tube_remove_bg_listen is called for ctx->qq_pipe and the memory of tube->ev_listen is released in ub_winsock_unregister_wsaevent but tube->ev_listen is never set to NULL.
  • After worker thread stops, tube_delete is called for tx->qq_pipe in ub_ctx_delete.
  • tube_delete calls tube_remove_bg_listen again and it tried to free tube->ev_listen again which leads to heap corruption.
  • I tested multiple older versions (back to 2019) of libunbound Windows library and they all have the same issue.
  • A cleaner way to fix this issue might be setting NULL inside ub_winsock_unregister_wsaevent but it will need to change ub_winsock_unregister_wsaevent API and pass ub_event** instead, which will bring additional changes in different places.

@gthess gthess self-assigned this Oct 18, 2024
@gthess
Copy link
Member

gthess commented Oct 18, 2024

Thanks, this looks good! But I don't think the #if defined is required. I see why you have it there, but always setting tube->ev_listen = NULL seems fine regardless if USE_MINI_EVENT is defined or not. Unless I miss something.

@lnzhu
Copy link
Contributor Author

lnzhu commented Oct 22, 2024

Thanks for reviewing! Yes, #if defined(USE_MINI_EVENT) is not strictly needed in current code. But tube->ev_listen is deleted in ub_winsock_unregister_wsaevent only if USE_MINI_EVENT is defined. I think it might be safer and future-proof to have the check before calling ub_winsock_unregister_wsaevent.

@gthess
Copy link
Member

gthess commented Oct 25, 2024

It is indeed only freed when USE_MINI_EVENT is defined.
For the other cases (when not defined, or when ub_event_pluggable.c is used) setting tube->ev_listen = NULL always after the ub_winsock_unregister_wsaevent() call conveys the correct intent that this listener event is no more.

I also prefer that all the USE_MINI_EVENT #ifdefs are handled in ub_event(_pluggable).c and not exposed in tube.c.

@lnzhu
Copy link
Contributor Author

lnzhu commented Oct 28, 2024

removed #if defined in the last commit

Copy link
Member

@gthess gthess left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this!

@gthess gthess merged commit 1c24cd7 into NLnetLabs:master Nov 1, 2024
1 check passed
gthess added a commit that referenced this pull request Nov 1, 2024
- Merge #1157 from Liang Zhu, Fix heap corruption when calling
  ub_ctx_delete in Windows.
jedisct1 added a commit to jedisct1/unbound that referenced this pull request Dec 26, 2024
* nlnet/master: (26 commits)
  - For NLnetLabs#1175, update serve-expired tests.
  - Fix NLnetLabs#1175: serve-expired does not adhere to secure-by-default   principle. The default value of serve-expired-client-timeout   is set to 1800 as suggested by RFC8767.
  - Fix comparison to help static analyzer.
  Changelog entry for NLnetLabs#1169: - Merge NLnetLabs#1169 from Sergey Kacheev, fix: lock-free counters for   auth_zone up/down queries.
  fix: lock-free counters for auth_zone up/down queries
  - Fix for NLnetLabs#1183: release nsec3 hashes per test file.
  - Fix NLnetLabs#1183: the data being used is released in method   nsec3_hash_test_entry.
  - Complete fix for max-global-quota to 200.
  - More descriptive text for 'harden-algo-downgrade'.
  - Increase the default of max-global-quota to 200 from 128 after   operational feedback. Still keeping the possible amplification   factor (CAMP related issues) in the hundreds.
  Changelog entry for: - Fix SETEX check during Redis (re)initialization.
  - Fix SETEX check during Redis (re)initialization.
  - Fix to log redis timeout error string on failure.
  - Fix for the serve expired DNSSEC information fix, it would not allow   current delegation information be updated in cache. The fix allows   current delegation and validation recursion information to be   updated, but as a consequence no longer has certain expired   information around for later dnssec valid expired responses.
  Changelog note for NLnetLabs#1167 - Merge NLnetLabs#1167: Makefile.in: fix occasional parallel build failures   around bison rule.
  Makefile.in: fix occasional parallel build failures around bison rule (NLnetLabs#1167)
  - Fix redis that during a reload it does not fail if the redis   server does not connect or does not respond. It still logs the   errors and if the server is up checks expiration features.
  - Fix redis that during a reload it does not fail if the redis   server does not connect or does not respond. It still logs the   errors and if the server is up checks expiration features.
  Changelog entry for NLnetLabs#1157: - Merge NLnetLabs#1157 from Liang Zhu, Fix heap corruption when calling   ub_ctx_delete in Windows.
  Fix heap corruption when calling ub_ctx_delete in Windows (NLnetLabs#1157)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants