]> Cypherpunks repositories - gostls13.git/commitdiff
plugin: resolve random crash when calling exported functions
authorTodd Neal <todd@tneal.org>
Tue, 11 Apr 2017 23:52:05 +0000 (18:52 -0500)
committerTodd Neal <todd@tneal.org>
Wed, 12 Apr 2017 12:34:25 +0000 (12:34 +0000)
open modified the plugin symbols map while ranging over it. This is
normally harmless, except that the operations performed were not
idempotent leading to function pointers being corrupted.

Fixes #19269

Change-Id: I4b6eb1d45567161412e4a34b41f1ebf647bcc942
Reviewed-on: https://go-review.googlesource.com/40431
Run-TryBot: Todd Neal <todd@tneal.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/plugin/plugin_dlopen.go

index c5b0a4721c5a02a08fbf6aa99d7cb2973846ff4d..72e219e337ce3664203f5479f9b4ea9ac8330233 100644 (file)
@@ -82,7 +82,6 @@ func open(name string) (*Plugin, error) {
        p := &Plugin{
                pluginpath: pluginpath,
                loaded:     make(chan struct{}),
-               syms:       syms,
        }
        plugins[filepath] = p
        pluginsMu.Unlock()
@@ -97,13 +96,13 @@ func open(name string) (*Plugin, error) {
        }
 
        // Fill out the value of each plugin symbol.
+       updatedSyms := map[string]interface{}{}
        for symName, sym := range syms {
                isFunc := symName[0] == '.'
                if isFunc {
                        delete(syms, symName)
                        symName = symName[1:]
                }
-
                cname := C.CString(pluginpath + "." + symName)
                p := C.pluginLookup(h, cname, &cErr)
                C.free(unsafe.Pointer(cname))
@@ -116,8 +115,12 @@ func open(name string) (*Plugin, error) {
                } else {
                        (*valp)[1] = p
                }
-               syms[symName] = sym
+               // we can't add to syms during iteration as we'll end up processing
+               // some symbols twice with the inability to tell if the symbol is a function
+               updatedSyms[symName] = sym
        }
+       p.syms = updatedSyms
+
        close(p.loaded)
        return p, nil
 }