Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
github.com/CAFxX/gcnotifier
gcnotifier provides a way to receive notifications after every run of the garbage collector (GC). Knowing when GC runs is useful to instruct your code to free additional memory resources that it may be using.
Package gcnotifier provides a way to receive notifications after every garbage collection (GC) cycle. This can be useful, in long-running programs, to instruct your code to free additional memory resources that you may be using.
A common use case for this is when you have custom data structures (e.g. buffers, rings, trees, pools, ...): instead of setting a maximum size to your data structure you can leave it unbounded and then drop all (or some) of the allocated-but-unused slots after every GC run (e.g. sync.Pool drops all allocated-but-unused objects in the pool during GC).
To minimize the load on the GC the code that runs after receiving the notification should try to avoid allocations as much as possible, or at the very least make sure that the amount of new memory allocated is significantly smaller than the amount of memory that has been "freed" by your code.
GCNotifier guarantees to send a notification after every GC cycle completes. Note that the Go runtime does not guarantee that the GC will run: specifically there is no guarantee that a GC will run before the program terminates.
The simplest use of this library is as follows:
gcn := gcnotifier.New()
for range gcn.AfterGC() {
// this code will be executed after every GC cycle
}
runtime.KeepAlive(gcn) // or store gcn somewhere to keep it alive
As written, the loop above will never terminate, so it is mostly useful if you have global caches that persist for the whole duration of the process.
Note that the AfterGC()
call is not guarantee to keep gcn
alive. gcn
and any channel
returned by AfterGC()
will automatically get closed if gcn
is garbage collected.
So if gcn
is not kept alive, the for
loop will terminate unexpectedly.
If you want to ensure the loop above terminates (e.g. because you only need the
notifications for the lifetime of a different object) you can call the
Close()
method:
gcn := gcnotifier.New()
go func() {
for range gcn.AfterGC() {
// this code will be executed after every GC cycle
// until Close() is called
}
}()
// later, or elsewhere in your code
gcn.Close() // the loop above will terminate some time after this call
Note that if a loop iteration takes longer than the interval between two GC cycles it is possible that one notification will be dropped. Followup notifications will be still received correctly.
For a more complex example of how to use it have a look at Example()
in
gcnotifier_test.go.
For details have a look at the documentation.
gcnotifier uses finalizers to know when a GC run has completed.
Finalizers are run when the garbage collector finds an unreachable block with an associated finalizer.
The SetFinalizer
documentation notes that there is no guarantee that
finalizers will run before a program exits. This doesn't mean, as
sometimes incorrectly understood, that finalizers are not guaranteed to run at
all, it just means that they are not guaranteed to run because GC itself is not
guaranteed to run in certain situations: e.g. when the runtime is shutting down.
Finalizers can also not run for other reasons (e.g. zero-sized or
package-level objects) but they don't apply to gcnotifier
because care was
taken in the implementation to avoid them.
The only other case in which a notification will not be sent by gcnotifier is if your code hasn't consumed a previously-sent notification. In all other cases if a GC cycle completes your code will receive a notification.
The test in gcnotifier_test.go generates garbage in a loop and makes sure that we receive exactly one notification for each of the first 500 GC runs. In my testing I haven't found a way yet to make gcnotifier fail to notify of a GC run short of shutting down the process or failing to receive the notification. If you manage to make it fail in any other way please file a GitHub issue.
Carlo Alberto Ferraris (@cafxx)
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.