Skip to content

Fix use-after-free issue with custom functions#710

Merged
flavorjones merged 1 commit into
mainfrom
use-after-free-functions-arity
Jun 7, 2026
Merged

Fix use-after-free issue with custom functions#710
flavorjones merged 1 commit into
mainfrom
use-after-free-functions-arity

Conversation

@flavorjones
Copy link
Copy Markdown
Member

when the same function name is used with multiple arities.

ref: https://github.com/sparklemotion/sqlite3-ruby/security/advisories/GHSA-28hh-pr2h-2w89

when the same function name is used with multiple arities.

ref: GHSA-28hh-pr2h-2w89
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a potential use-after-free when defining multiple SQLite custom functions with the same name but different arities by ensuring Ruby Proc objects remain referenced for the lifetime of the SQLite3::Database instance.

Changes:

  • Retain all function blocks on the database instance (switch @functions from a name-keyed hash to an array) to prevent GC from freeing blocks still referenced by SQLite.
  • Add a regression test covering redefining a function name with a different arity and forcing GC.
  • Update create_function documentation to clarify that function blocks are kept alive for the database lifetime.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/test_database.rb Adds regression test intended to reproduce the UAF scenario after GC.
lib/sqlite3/database.rb Changes @functions storage type and documents lifetime retention of function blocks.
ext/sqlite3/database.c Pushes function blocks into @functions array to keep them referenced and GC-safe.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/test_database.rb
def test_redefine_function_with_different_arity_does_not_use_freed_block
@db.define_function("f") { |a| "orig" }
@db.define_function("f") { |a, b| "new" }
GC.start(full_mark: true, immediate_sweep: true)
@flavorjones flavorjones merged commit 2bd436d into main Jun 7, 2026
268 of 270 checks passed
@flavorjones flavorjones deleted the use-after-free-functions-arity branch June 7, 2026 16:56
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