-
Notifications
You must be signed in to change notification settings - Fork 16
feat(blst): use external buffers for blst operations #358
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -136,10 +136,10 @@ pub const PublicKey = struct { | |
| pub fn toBytes(self: *const PublicKey, compress: ?js.Boolean) !js.Uint8Array { | ||
| if (try boolOrDefault(compress, true)) { | ||
| const bytes = self.raw.compress(); | ||
| return js.Uint8Array.from(bytes[0..]); | ||
| return js.Uint8Array.fromExternal(bytes[0..]); | ||
| } | ||
| const bytes = self.raw.serialize(); | ||
| return js.Uint8Array.from(bytes[0..]); | ||
| return js.Uint8Array.fromExternal(bytes[0..]); | ||
| } | ||
|
|
||
| pub fn toHex(self: *const PublicKey, compress: ?js.Boolean) !js.String { | ||
|
|
@@ -214,10 +214,10 @@ pub const Signature = struct { | |
| pub fn toBytes(self: *const Signature, compress: ?js.Boolean) !js.Uint8Array { | ||
| if (try boolOrDefault(compress, true)) { | ||
| const bytes = self.raw.compress(); | ||
| return js.Uint8Array.from(bytes[0..]); | ||
| return js.Uint8Array.fromExternal(bytes[0..]); | ||
| } | ||
| const bytes = self.raw.serialize(); | ||
| return js.Uint8Array.from(bytes[0..]); | ||
| return js.Uint8Array.fromExternal(bytes[0..]); | ||
|
Comment on lines
215
to
+220
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to |
||
| } | ||
|
|
||
| pub fn toHex(self: *const Signature, compress: ?js.Boolean) !js.String { | ||
|
|
@@ -295,9 +295,9 @@ pub const SecretKey = struct { | |
| } | ||
|
|
||
| /// Serializes the SecretKey to bytes (32 bytes). | ||
| pub fn toBytes(self: *const SecretKey) js.Uint8Array { | ||
| pub fn toBytes(self: *const SecretKey) !js.Uint8Array { | ||
| const bytes = self.raw.serialize(); | ||
| return js.Uint8Array.from(bytes[0..]); | ||
| return js.Uint8Array.fromExternal(bytes[0..]); | ||
|
Comment on lines
299
to
+300
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function also has a use-after-free vulnerability. The |
||
| } | ||
|
|
||
| pub fn toHex(self: *const SecretKey) !js.String { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation introduces a critical use-after-free vulnerability.
The
self.raw.compress()andself.raw.serialize()functions return arrays that are stored on the current function's stack. The slice passed tojs.Uint8Array.fromExternalthen points to this stack memory.When
toBytesreturns, its stack frame is deallocated, making the pointer held by the JavaScriptUint8Arrayinvalid. Any subsequent access to thisUint8Arrayin JS will read from deallocated memory, leading to undefined behavior, memory corruption, or a crash.To fix this, you must allocate the buffer on the heap. The
fromExternalfunction can then wrap this heap-allocated buffer, and its associated finalizer (which I assumezapisets up) will be responsible for freeing the memory.Here is a suggested implementation that correctly allocates memory on the heap: