Go: cmd/go:cgo 白名单中缺少选项

创建于 2018-02-08  ·  138评论  ·  资料来源: golang/go

最近的 cmd/go 安全补丁 (#23672) 添加了一个允许与 cgo 一起使用的选项的白名单。 几个不同的人报告了默认情况下无法构建的包,因为他们使用了不在白名单中的选项。 此问题旨在收集所有缺失选项的列表,以便我们可以将它们添加到单个 CL 中。

FrozenDueToAge release-blocker

最有用的评论

假设每个编译器(和链接器等)选项的存在都是有原因的,并且白名单应该涵盖所有这些选项,除了那些被特别认为是危险的选项,难道不是合理的吗? 显然有数百个,白名单的维护不会很有趣,但如果那是已经决定的路径......

这可能已经在内部讨论过,但我发现补丁版本令人惊讶:我原以为违规标志首先被列入黑名单以堵塞编译器插件漏洞,并为 1.10 启用白名单系统,其列表可能已经构建在 RC 期间。 在某些构建系统中集成额外的 env vars 不太实用,我观察到这会导致人们只是恢复到 1.9.3,因此完全不受保护,我认为这完全适得其反。

什么时候充满通配符和正则表达式的白名单会变相变成黑名单?

所有138条评论

23737 报告说pkg-config -libs生成的标志正在根据编译器白名单和CGO_CFLAGS_ALLOW进行检查,而此时它们应该根据链接器白名单和CGO_LDFLAGS_ALLOW 。 有一个 CL 来解决这个问题: https :

链接器白名单应该接受.a文件,因为它已经接受.o.so等文件。 有一个 CL 来解决这个问题: https :

对 #23672 的评论列出了这些编译器选项:

-fno-rtti
-fpermissive

以及这些链接器选项:

-Wl,-framework
-Wl,--no-as-needed

23742 建议添加编译器选项-fmodules 。 clang 编译器支持许多-fmodules选项,但尚不清楚它们是否都是安全的。 特别是-fmodules-cache-path-fmodules-user-build-path似乎允许指定 clang 将用于读取模块的路径,这可能会以各种方式改变编译模式。

23743 建议添加链接器选项-Wl,--no-as-needed 。 有一个 CL: https :

23744 建议添加这些编译器选项:

-finput-charset=UTF-8
--std=c99
-pedantic-errors

有许多编译器和链接器选项可以与单破折号或双破折号一起使用。 我们应该在白名单中同样松懈。

对于正交性:我忘记了将目录添加到-framework的搜索路径的选项是否已经被覆盖。 我也忘了那是什么选项。 (我能想到的典型用例是/Library/Frameworks ,这是 Apple 放置特定于应用程序的框架的地方,默认情况下不会被搜索。)

-as-needed首先与 cgo 一起使用是否安全? 这篇博客文章(这是我能找到的“gcc as-needed”的第一个结果)说它是一个位置参数,但我不确定 cgo 是否能保证你的标志在结果命令行上的位置。

@andlabs写的很好

#cgo LDFLAGS: -Wl,--as-needed -loptlib -WL,--no-as-needed

无论如何,这个问题的主题应该是从go get使用选项是否安全。

使用时:

#cgo !windows pkg-config: --static ${SRCDIR}/vendor/libgit2/build/libgit2.pc

编译失败并显示以下消息:

invalid pkg-config package name: --static

查看代码(对于 go 1.9.4),似乎没有任何环境变量可用于将 pkg-config 参数列入白名单。

@rgburke pkg-config 输出通过与其他输出相同的FLAGS_ALLOW变量。

但是,似乎pkg-config -libs CGO_CFLAGS_ALLOW在应该检查CGO_LDFLAGS_ALLOW时检查

我们在一个闭源项目中静态链接了大量 C 库。 到目前为止,我们一直在做以下事情:

#cgo LDFLAGS:/path/to/one/liblibrary1.a
#cgo LDFLAGS:/path/to/two/liblibrary2.a
etc.

这当然现在是不允许的。 解决方法:

#cgo LDFLAGS:-L/path/to/one -llibrary1
#cgo LDFLAGS:-L/path/to/two -llibrary2

然而,其中一些目录也包含动态库,这会混淆链接器。 另一种选择是将“/”添加到https://go-review.googlesource.com/c/go/+/92855中允许的“名称”列表中,特别是第 91 行的更改是:

re(`[a-zA-Z0-9_\/].*\.(o|obj|dll|dylib|so|a)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o)

后一个选项解决了我们的问题,但我无法谈论它对安全性的影响。

@mirtchovski有一个补丁(问题是.a没有列入白名单,但其他目标文件格式是)

.a 现在被列入白名单(在那个补丁之后)所以 'libsomething.a' 可以工作,但 '/path/to/libsomething.a' 将不起作用。

@ianlancetaylor @rgburke我实际上遇到了与--static完全相同的问题,这使我陷入了#23737。 --static被拒绝,因为它似乎不是一个有效的包名 _before_ 试图执行pkg-config ,这里https://github.com/golang/go/blob/104445e3140f4468839db49a25cb0182f7923174/src/ cmd/go/internal/work/exec.go#L939 -L940。

我们内部的快速修复是将 PKG_CONFIG 指向一个简单地执行pkg-config --static "$@"的脚本。

@jeddenlea - 非常感谢! 我试图找到一种解决方法,但没有想到这一点。

我们用-msse-msse4.2

我在 cgo LDFLAGS 中使用“${SRCDIR}/file.o”遇到了这个问题。

我想争辩说我们应该允许链接器输入的纯文件名
LDFLAGS 中的文件
(至少 *.a、*.o 和 *.so)。

与 .a 和 .so 不同,理论上可以用 "-L${SRCDIR}
-lname”,添加
链接器命令的额外目标文件无法通过这种方式修复。

一种解决方法是设置 CGO_LDFLAGS_ALLOW,但这非常麻烦。
其他
另一种方法是将我的 file.o 重命名为 file.syso,但是,对于我的特定
情况,我不能使用
这个选项是因为我只在特定的构建标记是时包含那个 file.o
包括(
构建标记适用于包含#cgo LDFLAGS 前导码的文件)和
不可能
在 syso 文件名中设置任意构建标记。

如果我们忽略以前部署的 Go 版本,我们也许可以包含一个
新的
“#cgo LDLIBS”专为向链接器添加更多文件而设计
命令行。
然后我们可以对 LDLIBS 制定更严格的规则(仅文件名,没有破折号
允许在前缀中。)

我们用--std=c99

-std=c++11

我猜 -std=应该白名单?

可能在白名单上: -fopenmp

使用 Go v1.10rc2 构建 bimg 包时出错,

23:24 ~/go-test
master ms 130 % go get -v github.com/h2non/bimg
github.com/h2non/bimg (download)
github.com/h2non/bimg
go build github.com/h2non/bimg: invalid flag in pkg-config --cflags: -fopenmp

我无法将-isystem列入白名单,因为它旁边的参数(这是一条路径)将被拒绝

我们还需要使用此解决方法: https :

我们之前有:

#cgo linux LDFLAGS: ${SRCDIR}/../../../../path/to/thing/libthing_static.a

并已转移到:

#cgo linux LDFLAGS: -L${SRCDIR}/../../../../path/to/thing -lthing_static

.../path/to/thing位于${SRCDIR}

添加此注释,以便此问题包含一个带有libthing.a引用的示例,该引用需要SRCDIR扩展才能解决。

在 OSX 上,使用新铸造的 go1.9.4 及其 cgo 标志限制,我特别告诉链接器要链接什么 .a 存档:(这里 https://github.com/gijit/gi/blob/master/vendor/ github.com/glycerine/golua/lua/lua.go#L10)

~~~

cgo LDFLAGS: ${SRCDIR}/../../../LuaJIT/LuaJIT/src/libluajit.a -lm -ldl

~~~

尝试构建时产生:

~建造go build -ldflags "-X main.LastGitCommitHash=30259813c10c0f6b63768b4f35358828e2e29f0b -X main.BuildTimeStamp=2018-02-09T22:49:48+0700 -X main.NGitvest.GitX main.N.GitX. =go_version_go1.9.4_darwin/amd64" -o gi去构建 github.com/gijit/gi/vendor/github.com/glycerine/golua/lua:#cgo LDFLAGS 中的无效标志:/Users/jaten/go/src/github.com/gijit/gi/vendor/github。 com/glycerine/golua/lua/../../../LuaJIT/LuaJIT/src/libluajit.amake[2]: * [build] 错误 1make[1]: [安装] 错误 2制作:** [安装] 错误 2jaten@jatens-MacBook-Pro ~/go/src/github.com/gijit/gi (master) $~
我尝试了 -L -l 解决方法,
~~~

cgo LDFLAGS: -L${SRCDIR}/../../../LuaJIT/LuaJIT/src -lluajit -lm -ldl

~~~
但是链接器认为它可以在不同的位置使用同名的不同库,并且我得到一个运行时而不是链接时错误。

~~~
在运行时...
dyld:懒惰的符号绑定失败:找不到符号:_luajit_ctypeid
引用自:/var/folders/6s/zdc0hvvx7kqcglg5yqm3kl4r0000gn/T/go-build615587282/github.com/gijit/gi/pkg/compiler/_test/compiler.test
预期在:/usr/local/lib/libluajit-5.1.2.dylib

dyld:找不到符号:_luajit_ctypeid
引用自:/var/folders/6s/zdc0hvvx7kqcglg5yqm3kl4r0000gn/T/go-build615587282/github.com/gijit/gi/pkg/compiler/_test/compiler.test
预期在:/usr/local/lib/libluajit-5.1.2.dylib

SIGTRAP:跟踪陷阱
PC=0x7fff66ff4075 m=0 sigcode=1
cgo执行期间信号到达
~~~
/usr/local/lib/libluajit-5.1.2.dylib 不是必需的库,尽管它是动态链接的; 相反,它必须是 ${SRCDIR}/../../../LuaJIT/LuaJIT/src/libluajit.a 中指定的那个。

所以仍在寻找解决方法。

更新:看起来像将它添加到我的 makefile 中可以解决问题。
~export CGO_LDFLAGS_ALLOW="${GOPATH}/src/github.com/gijit/gi/vendor/github.com/glycerine/golua/lua/../../../LuaJIT/LuaJIT/src/libluajit.a";~

更新:谢天谢地,伊恩指出,较短的正则表达式版本可以:
~导出 CGO_LDFLAGS_ALLOW=".*.a";~

-Wl,-framework 是干什么用的? 如果那是 Apple 框架,它有一个参数,所以你可能想要 -Wl,-framework,foo。 但是如果它是 Apple 框架,那么 -framework(没有 -Wl,)也能正常工作。

在 1.10rc2 中,golang.org/x/net/internal/socket 不再为 Solaris 构建。

$ GOOS=solaris go build golang.org/x/net/ipv4
# golang.org/x/net/internal/socket
ext/src/golang.org/x/net/internal/socket/sys_solaris.go:24:3: //go:cgo_import_dynamic libc___xnet_getsockopt __xnet_getsockopt "libsocket.so" only allowed in cgo-generated code
ext/src/golang.org/x/net/internal/socket/sys_solaris.go:25:3: //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" only allowed in cgo-generated code
ext/src/golang.org/x/net/internal/socket/sys_solaris.go:26:3: //go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so" only allowed in cgo-generated code
ext/src/golang.org/x/net/internal/socket/sys_solaris.go:27:3: //go:cgo_import_dynamic libc___xnet_sendmsg __xnet_sendmsg "libsocket.so" only allowed in cgo-generated code

(这里没有发生 cgo,因为这是一个交叉构建,但我想这无关紧要。)

我无法通过指定完整路径来链接到静态 lib 文件:

#cgo LDFLAGS: /usr/local/lib/libsecp256k1.a

我看不到它的解决方法:(

@piotrnar CGO_LDFLAGS_ALLOW='.*\.a$'

@ianlancetaylor ,谢谢!

这对我有用,但是告诉所有使用我的项目的人为 go 1.9.4 做CGO_LDFLAGS_ALLOW='.*\.a$'似乎有点狡猾。

希望将来会有更好的(开箱即用)解决方案。

@piotrnar是的,这个问题的重点是收集我们需要

你也可以加上-fstack-protector吗?

谢谢 :)

请加入白名单-static-libstdc++

由于在 darwin 上通过 LDFLAGS 传递-fconstant-cfstrings ,因此软件包github.com/flynn/hid无法使用 1.9.4 构建。

请将这些链接器标志添加到白名单
-Wl,-Bstatic
-Wl,-Bdynamic
-Wl,--start-group
-Wl,--end-group

老实说:在这一点上,对我来说,一个错误选项的黑名单似乎比如此广泛的白名单更有用。

展望未来,黑名单意味着如果引入了一些新的潜在不安全的编译器选项,所有 Go 版本都将容易受到该选项的影响。 就我们完全可以防御这种攻击而言,我认为它必须是一个白名单。

引入了一些新的可能不安全的编译器选项

我仍然认为黑名单更可取。 因为它是双向的。 如果任何新的编译器选项在被列入白名单之前无法使用,那么每次任何新的 C 编译器添加一个标志时,似乎都需要一个新的 Go 版本......

@glycerine这就是我们提供环境变量作为逃生舱口的原因。 在更新白名单之前,您始终可以使用环境变量。

问题是 env 变量不适用于纯粹通过“go get”安装的项目。

另一种方法:允许顶层名为 go 的项目设置环境变量。

然后正在安装的主要“go build”项目可以将它需要的标志列入白名单,例如使用 ALLOW 正则表达式,同时仍然防止依赖项目做任意的事情。

@glycerine我不确定我是否理解它是如何工作的。 但是我建议你为那个建议单独开一个 issue,而不是在这个 issue 上讨论它,它的目的是收集需要列入白名单的选项。

现在我们决定实施白名单。 这在未来可能会改变,但这个问题不是讨论的地方(随意提交一个新的)。 我们正在尝试收集应在此处列入白名单的选项,仅此而已。

谢谢你。

#cgo CFLAGS 中的无效标志:-pipe

go build github.com/zchee/docker-machine-driver-xhyve/vendor/github.com/zchee/libhyperkit: invalid flag in #cgo CFLAGS: -fno-common

您好,请将这些标志添加到白名单中,-Wl,--enable-new-dtags

无法构建配方/qt

go build github.com/therecipe/qt/core: invalid flag in #cgo CFLAGS: -pipe

.*\.a到允许的标志会很棒。
https://github.com/golang/go/issues/23807

--mms-bitfields 似乎也是必需的。

假设每个编译器(和链接器等)选项的存在都是有原因的,并且白名单应该涵盖所有这些选项,除了那些被特别认为是危险的选项,难道不是合理的吗? 显然有数百个,白名单的维护不会很有趣,但如果那是已经决定的路径......

假设每个编译器(和链接器等)选项的存在都是有原因的,并且白名单应该涵盖所有这些选项,除了那些被特别认为是危险的选项,难道不是合理的吗? 显然有数百个,白名单的维护不会很有趣,但如果那是已经决定的路径......

这可能已经在内部讨论过,但我发现补丁版本令人惊讶:我原以为违规标志首先被列入黑名单以堵塞编译器插件漏洞,并为 1.10 启用白名单系统,其列表可能已经构建在 RC 期间。 在某些构建系统中集成额外的 env vars 不太实用,我观察到这会导致人们只是恢复到 1.9.3,因此完全不受保护,我认为这完全适得其反。

什么时候充满通配符和正则表达式的白名单会变相变成黑名单?

-flto

您能否将按字母顺序排列的“已批准”列表放在此问题的顶部以进行概述,直到下一次更新结束? 提交 CL 的人也可能对此表示赞赏。

现在(特别是因为这个问题存在)我更关心什么是从裂缝中溜走的:人们在没有事先咨询我们的情况下从他们的项目中删除了哪些构建标志,让他们误以为 cgo(以及扩展的 Go)被破坏了和马车,有回归和它的开发人员不知道他们在做什么。 :S(或者更糟的是,不知道自己在做什么,显然我的包构建错误,因为是缺少依赖项 xyz 的人!)

一些“引用此问题”链接列出了更多列入黑名单的标志,这些标志尚不属于此问题。 我还保证在顶部有一个主列表,特别是为了避免重复。 人们仍然遇到静态存档问题......

这让我想知道 gcc 和 clang 是否可以,甚至应该,提供一个选项--no-unsafe-options a) 会为我们做脏活 b) 对未来的变化有弹性 c) 不能被另一个人关闭选项(一旦它在那里,它就在那里,期间)。 或者go get是第一个也是唯一一个需要这种过滤的情况?

如果我们坚持白名单,那么我不知道为什么需要延迟等待输入。

编译器记录他们的标志。 正如上面有人所说,每个标志的存在都是有原因的。

通过等待用户对使用情况的输入进行抽样将是代表性不足、不可靠的,并且会给我们所有人带来痛苦的结果,这些人将来需要一个现在没有实现或抽样的标志。

此外,通过此过程以伪代码导出白名单似乎很简单:

列出所有支持的 C/C++ 编译器和每个编译器的版本;
对于每个编译器版本,列出其文档中可用的所有标志;
对于每个标志,决定将其放入白名单或(不可见)黑名单。

为累积的白名单上的所有标志添加白名单代码。

与将一个(或两个)易受攻击的标志列入黑名单相比,我仍然认为这很疯狂(接近于减少广告荒谬)。 但说真的,如果我们要坚持白名单,上面的算法是正确的,消除了猜测,并且可以立即执行。 也许唯一需要的额外用户输入是确定要支持的编译器/版本的范围。

这里唯一重要的选项是那些合理地放在 .go 文件中的#cgo CFLAGS#cgo LDFLAGS行上的选项,或者从对pkg-config --cflags的调用中输出的合理选项pkg-config --libs 。 这是编译器选项总数的一小部分。

你也大大低估了 gcc 和 clang 甚至有多少选项。 我怀疑它们都被记录在案,即使在源代码中——如果有些是在运行时生成的,我不会感到惊讶! 也可能存在与目标三重相关的选项......(这也是我说 gcc 和 clang 开发人员需要维护安全标志的规范列表的原因。)

不过,我不能说修补个别标志的延迟。

@anacrolix在 #23672 中,您建议我们需要将-Wl,-framework列入白名单。 但是-framework通常需要一个选项。 你能展示确切的用例吗? 谢谢。

你也大大低估了 gcc 和 clang 甚至有多少选项

@andlabs Ian 是一名 gcc 开发人员。 我相信他很清楚。

更改https://golang.org/cl/93836提到这个问题: cmd/go: add options to security whitelist

我发送了一个我认为涵盖上述所有选项的 CL: https :

如果您发现它有任何问题,或者您知道人们使用的任何选项未涵盖,请告诉我。 谢谢。

从 LLVM Go 绑定的角度来看,以下链接器选项应该在白名单中。

  • -Wl,-search_paths_first
  • -Wl,-headerpad_max_install_names

链接器选项由命令llvm-config --ldflags ,它们在输出中。

参考: https :

@magical我在那里回应@glycerine =P

如果我让你感到匆忙, @ianlancetaylor也很抱歉

@andlabs啊,对不起

@ianlancetaylor使用该 CL 我仍然无法为 Solaris 构建

$ ./bin/go version
go version devel +09dc376990 Tue Feb 13 20:58:04 2018 -0800 darwin/amd64
$ GOOS=solaris ./bin/go get -u golang.org/x/net/ipv4
# golang.org/x/net/internal/socket
../../ext/src/golang.org/x/net/internal/socket/sys_solaris.go:24:3: //go:cgo_import_dynamic libc___xnet_getsockopt __xnet_getsockopt "libsocket.so" only allowed in cgo-generated code
../../ext/src/golang.org/x/net/internal/socket/sys_solaris.go:25:3: //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" only allowed in cgo-generated code
../../ext/src/golang.org/x/net/internal/socket/sys_solaris.go:26:3: //go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so" only allowed in cgo-generated code
../../ext/src/golang.org/x/net/internal/socket/sys_solaris.go:27:3: //go:cgo_import_dynamic libc___xnet_sendmsg __xnet_sendmsg "libsocket.so" only allowed in cgo-generated code

@calmh是的。 我认为我们将不得不通过更改 golang.org/x/net 来修复该问题。 它已经依赖于许多内部细节,我认为我们需要改变它的方式。

@calmh您能否在实际的 Solaris 系统上测试https://golang.org/cl/94015

更改https://golang.org/cl/94015提到了这个问题: internal/socket: rework Solaris reliance on syscall package

@rsc @ianlancetaylor @anacrolix我想出了-Wl,-framework的来源:它来自 GLib 的 pkg-config 文件,它是 GTK+ 的依赖项。 具体来说,它包括用于国际化目的的 CoreFoundation 链接。

具体参考: https://gitlab.gnome.org/GNOME/glib/blob/master/glib-2.0.pc.in#L14其中@INTLLIBS@获得-Wl,-framework -Wl,CoreFoundationhttps://开头gitlab .gnome.org/GNOME/glib/blob/master/m4macros/glib-gettext.m4#L143

在其他各种 pkg-config 文件中还有其他-Wl,-framework实例; 有些是项目本身的一部分(如上),有些是由 Homebrew 注入的。 现在在我的系统上,我看到 libcdio 和 SDL 都使用-Wl,-framework,FrameworkName 。 (这意味着,是的, -Wl,-framework -Wl,FrameworkName-Wl,-framework,FrameworkName都可以在 pkg-config 文件中找到。请看图。)

更改https://golang.org/cl/94018提到这个问题: cmd/compile: permit go:cgo_import_dynamic anywhere

@calmhhttps://golang.org/cl/94018 中尝试不同的方法

@andlabs谢谢,已添加到 CL 93836。

我是静态链接 SDL,pgkconfig 包含-Wl,--no-undefined以及预处理器定义。

我需要你在白名单下方添加标志,以便他们可以编译使用 cgoemitter 包的项目

go build github.com/supermock/cgoemitter-demo/x:#cgo LDFLAGS 中的无效标志:-Wl,-unresolved-symbols=ignore-all

非常感谢您提前

再次更新CL。

我在https://golang.org/wiki/InvalidFlag添加了一个 wiki 页面来描述这个问题,我正在更新 CL,以便错误消息将人们指向 wiki。

更改https://golang.org/cl/94158提到这个问题: doc: add note about invalid flag errors to 1.10 release notes

invalid flag in #cgo LDFLAGS: -O3

更改https://golang.org/cl/94655提到这个问题: [release-branch.go1.10] doc: add note about invalid flag errors to 1.10 release notes

更改https://golang.org/cl/94675提到这个问题: [release-branch.go1.10] cmd/compile: permit go:cgo_import_dynamic anywhere

更改https://golang.org/cl/94676提到这个问题: [release-branch.go1.10] cmd/go: add options to security whitelist

也收到这个问题,如果可以添加以下内容

go build github.com/andlabs/ui: invalid flag in #cgo LDFLAGS: -mmacosx-version-min=10.8

@bgk- 已应用的补丁解决了这个问题。 如果现在升级到 1.10 不可行,我不得不建议等待 1.9.5 是否发生。

1.10 是否应该修复invalid pkg-config package name: --static问题? 我刚刚从自制软件中下载了最新版本,但我仍然看到它:

➜  ~ go version
go version go1.10 darwin/amd64
... 
➜  ~ go build
...
go build github.com/flier/gohs/hyperscan: invalid pkg-config package name: --static

@ptomey3见#

1.9.5 重新开放。

我会避免 XY 问题,而是完全解释我在做什么。 我正在使用-buildmode=c-shared创建一个 postgresql 扩展。

在为 postgresql 创建 C 扩展的文档中,这是构建共享对象的方式:

cc -fPIC -c foo.c
cc -shared -o foo.so foo.o

所以我在我的源代码中添加了#cgo LDFLAGS: -shared 。 直到最近(go1.10)停止构建时,它才起作用:

invalid flag in #cgo LDFLAGS: -shared

刚抓到 go 1.10,遇到了这个:

invalid flag in #cgo LDFLAGS: -Wl,-static

这是一个 gcc 链接器标志,用于强制静态链接链接行上该选项之后的任何内容。

@spackard作为记录,这不是该选项的含义。 您正在考虑-Bstatic-static选项指示链接器不搜索任何共享库以满足任何-l选项。 -static不是位置选项; 它出现在命令行的哪个位置并不重要。

@ianlancetaylor您对位置的CGO_LDFLAGS_ALLOW确实有效。

我有相同的问题

invalid flag in #cgo CFLAGS: -m32

我们用 -O3、-static-libgcc 和 -static-libstdc++ 实现了这一点

-O3:

cgo windows LDFLAGS: -O3 -L./ -lmass -static-libgcc -static-libstdc++

cgo linux LDFLAGS: -O3 -L./ -lmass -ldl -lm -lrt -static-libgcc -static-libstdc++

cgo CFLAGS:-O3

#cgo LDFLAGS 中的无效标志:-O3

-静态-libgcc:

cgo windows LDFLAGS: -L./ -lmass -static-libgcc -static-libstdc++

cgo linux LDFLAGS: -L./ -lmass -ldl -lm -lrt -static-libgcc -static-libstdc++

#cgo LDFLAGS 中的无效标志:-static-libgcc

-static-libstdc++:

cgo windows LDFLAGS: -L./ -lmass -static-libstdc++

cgo linux LDFLAGS: -L./ -lmass -ldl -lm -lrt -static-libstdc++

#cgo LDFLAGS 中的无效标志:-static-libstdc++

使用硬编码的静态白名单是一个坏主意,也许我们应该使用具有一些默认设置的配置文件,例如

$GOROOT/bin/cgo.cfg
[白名单]
布拉布拉布拉
...

所以我们可以做一些定制

@kruglinski您可以使用 CGO_CFLAGS_ALLOW 环境变量和朋友进行自定义。

@ianlancetaylor

抱歉,我只是错过了这个,:-) 很高兴知道,很多人认为!

24124 报告以下链接器选项:

-Wl,-z,relro

链接器选项-Wl,--subsystem,windows和编译器选项-mwindows都丢失了。

我正在尝试让 gomobile/gobind 生成独立绑定。 其中一些工作涉及将 CGO_*FLAGS 环境变量转换为 #cgo 指令,这会发现更多标志:

````
-isysroot(ios)
-mios-simulator-version-min=(ios)
-miphoneos-version-min=(ios)

-目标(安卓)
--sysroot(安卓)
-gcc-工具链(安卓)
````

我相信除了最后一个 -gcc-toolchain 之外的所有内容都可以安全地添加到白名单中。

在 macOS 上为Godot 游戏引擎构建Go 绑定需要以下标志,而无需CGO_LDFLAGS_ALLOW

-Wl,-undefined,dynamic_lookup

更多CFLAGS来自zchee/libhyperkit

  • -fmessage-length=152
  • -fdiagnostics-show-note-include-stack
  • -fmacro-backtrace-limit=0

v8worker在 Mac OS X 上需要-stdlib=libstdc++

CL 103156 适合 Go 1.9.5

更改https://golang.org/cl/103135提到这个问题: [release-branch.go1.9] cmd/go: add options to security whitelist

我在列表中看不到它,libtool 是否也可以列入白名单

invalid flag in #cgo LDFLAGS: -I/usr/local/share/libtool

@PassKit -I是一个 cflag(在列表中)而不是一个 ldflag,你为什么把它放在 ldflags 中?

重新开放以收集更多白名单请求。

来自#24703

CFLAGS: -fno-plt

在这一点上,我认为可以决定我们只会更新 1.9 和 1.10 发布分支,如果某些流行的包无法构建并且尚未报告不知何故。 我认为我们不需要继续向后移植每个随机选项。 我们可以将它们添加到 1.11 的小费中。 无论我们是在这个问题上还是在其他地方跟踪它们,我都不在乎。

sgtm

@AlexRouSg我的问题与这个库有关,它建议将“-I”列入白名单作为 ldflag,我目前正在将其用作解决方法。 https://github.com/miekg/pkcs11/issues/63

抱歉迟到了,但如果这些能在 1.9.5 或 1.10.2 中列入白名单就太好了

CXXFLAGS: -F/Users/user/Qt/5.10.1/clang_64/lib
CFLAGS: --sysroot=/Users/user/android-ndk-r14b/sysroot
CFLAGS: -mfloat-abi=softfp
CFLAGS: -fno-builtin-memmove
CFLAGS: -mthumb
CFLAGS: -fobjc-nonfragile-abi
CFLAGS: -fobjc-legacy-dispatch
CFLAGS: -fno-keep-inline-dllexport
CXXFLAGS: -mthreads
CFLAGS: -Wp,-D_FORTIFY_SOURCE=2
CFLAGS: --param=ssp-buffer-size=4
CFLAGS: -mfloat-abi=hard
CFLAGS: -fvisibility-inlines-hidden
CFLAGS: -mfpmath=sse
CFLAGS: -fasynchronous-unwind-tables
CFLAGS: -feliminate-unused-debug-types
CFLAGS: -marm
CFLAGS: -mabi=aapcs-linux
CFLAGS: -mthumb-interwork

LDFLAGS: -headerpad_max_install_names
LDFLAGS: -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
LDFLAGS: -Wl,-rpath,@executable_path/Frameworks
LDFLAGS: --sysroot=/Users/user/android-ndk-r14b/platforms/android-16/arch-arm/
LDFLAGS: -Wl,-rpath-link=/Users/user/Qt/5.10.1/android_armv7/lib
LDFLAGS: -Wl,--allow-shlib-undefined
LDFLAGS: -Wl,-e,_qt_main_wrapper
LDFLAGS: -Wl,-O1
LDFLAGS: -Wl,-rpath-link,/opt/Qt/5.10.0/gcc_64/lib
LDFLAGS: -Wl,-s
LDFLAGS: -Wl,-subsystem,console
LDFLAGS: -mthreads
LDFLAGS: -rdynamic
LDFLAGS: -mfloat-abi=hard

提前致谢。

@therecipe我们可以将这些添加到 1.11。 但是对于 1.9.5 或 1.10.2:哪些包需要这些?

@ianlancetaylor https://github.com/therecipe/qt的不同目标都需要这些
如果您不立即将它们全部列入白名单也没关系,但请告诉我我需要照顾哪一个。

我猜是他们自己的 Qt 包,我知道它已经足够成熟了; 我不完全确定是否(其他人需要说)。

话虽如此:

  • 一些LDFLAGS不是已经在没有-Wl,前缀的情况下列入白名单的吗?
  • -e对 Go 有影响吗?
  • -F不是已经被列入白名单了吗? 事实证明,这就是我上面提到的选项。
  • (致@therecipe)你为什么要用-Wp守卫-D -Wp ? 是否有理由定义宏但仅在预处理器中? 我不知道 Qt 在这里做了什么样的伏都教……或者这是 Qt 本身提供的推荐选项列表?
  • (致@ianlancetaylor)我可以理解不将新选项反向移植到 1.9(我对这个问题持矛盾态度,因为我没有 Go 版本使用指标),但为什么在 1.12 发布之前不使用 1.10?
  • 不管上述问题的答案如何,我想知道向后移植那里列出的 ARM ABI 选项是否值得...

@andlabs只是因为我们必须在某个时候停下来,所以为什么不现在停下来? 但是如果它看起来足够有用,我可以继续向后移植补丁。

@andlabs是的,这些都是推荐的标志。 我自己没有手动添加其中一个。
-Wp,-D_FORTIFY_SOURCE=2来自旗鱼目标 iirc,我不知道他们为什么这样做。

@therecipe在这种情况下,Qt 和 Sailfish 在哪里提出这些建议(也就是说,是否有网页或 CLI 工具可以向您提供这些建议)? 我现在很好奇。

与此同时,虽然 Go 团队解决了该列表,但我仍然想知道如果删除-Wl,前缀,您的 LDFLAGS 警告会消失多少; 试试看? 同为-Wp,的一个前缀CFLAGS 。 我不知道这是否会对构建产生不利影响,但它不应该在理想的世界中,因为这就是 LDFLAGS 的用途......(您还必须将逗号更改为空格。这些-Wx,选项基本上告诉 gcc 和 clang 将参数直接发送到链接器(或汇编器或预处理器),而不是自己处理它们;如果我猜对了,这个想法是针对 gcc 尚未提供的特定于操作系统的选项并直接叮当,但我不确定......)

@andlabs是的,Qt 的构建工具之一qmake *.pro*.spec (mkspec)、 *.conf和许多其他格式来生成常规 Makefile。 我只是给它提供一些虚拟的*.pro文件并从 Makefile 中提取标志。 这样,我真的不必自己解决依赖关系,构建过程可以更轻松地使用 3rd-party libs,我不必手动管理 c 或 ld 标志和未经测试的目标或新/旧版本的 Qt 工作大多数时候都是开箱即用的。 我只是偶尔不得不将一些会引起麻烦的标志列入黑名单,但这种情况非常罕见。

我试图找到拉入-Wp,-D_FORTIFY_SOURCE=2的旗鱼 mkspec,但它可能埋在 mersdk 左右的某个地方。 但这里是 TQtC 维护支持的官方目标列表: https :

我可以同时在绑定使用的构建工具中将它们列入白名单(包装go ),但是只想使用go build ...的普通 Go 用户迟早会提出问题.. .(至少对于桌面目标而言)

-ffast-数学

官方 SAP HANA 客户端驱动程序(基于 cgo 的共享库)附带#cgo LDFLAGS: -Wl,-rpath -Wl,\$ORIGIN ,结果为go build SAP/go-hdb/driver: invalid flag in #cgo LDFLAGS: -Wl,-rpath 。 另请参阅https://help.sap.com/viewer/0eec0d68141541d1b07893a39944924e/2.0.03/en-US/fba20e31f75c4f7ca5629083869069e5.html2driver=go 上的SAP 文档了解详细信息

@cbgo见 #23672

将标志和参数对传递给链接器的代码现在必须使用一个 -Wl 标志而不是两个:使用 #cgo LDFLAGS: -Wl,-rpath,$ORIGIN,而不是 #cgo LDFLAGS: -Wl,-rpath -Wl,$起源。

@AlexRouSg非常感谢。 我应该更仔细地阅读:-)

@PassKit你解决这个问题了吗?

@zcm211如果您在谈论https://github.com/miekg/pkcs11,他们在 2 月删除了-I...链接器标志。 如果您使用的是使用它的包,则必须设置环境变量CGO_LDFLAGS_ALLOW="-I.*"

darwin 64 位,go1.10.2,我认为.o文件已被列入 LDFLAG 的白名单,但我得到:
~jaten@jatens-MacBook-Pro ~/go/src/github.com/go-interpreter/chezgo (master) $ make runcd chez_scheme_9.5.1/c;








由于https://github.com/go-interpreter/chezgo/blob/master/embed.go#L10 中的 cgo 序言
~~~

cgo LDFLAGS: -liconv -lm -lncurses -L/usr/local/lib ./chez_scheme_9.5.1/boot/a6osx/kernel.o

~~~

@glycerine根据https://go-review.googlesource.com/c/go/+/94676他们是。 也许尝试完整路径而不是相对路径?

很好的捕获@AlexRouSg ,正如您指出的那样,接受正则表达式有问题;
~re( [a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so) ), // 直接链接器输入:xo 或 libfoo.so(但不是 -foo.o 或 @foo.o)~
src/cmd/go/internal/work/security.go#121 应该允许.o文件以.开头以支持相对路径。

毕竟,我无法预测用户的 GOPATH,或者该文件的位置将如何嵌套,因此设置绝对路径是不切实际的。

.o 文件在源目录中吗? 如果是这样,引用源目录就是${SRCDIR}提供的内容。 (我忘记了具体为什么引入这个,但不是因为这个问题。)

@andlabs即使有笨拙的解决方法,相对路径也应该是可链接的,这显然是一个错误。

是的,除了 IIRC,不能保证链接是相对于源目录的(它很可能在$WORK ,然后你的相对路径再次中断)......再次,我忘记了历史; 其他人将需要解释。

gtk4 使用 -mfpmath=sse

@ianlancetaylor不是为 cflags 和 ldflags 设置单独的白名单,而是应该只有一个列表吗? gcc/llvm 似乎并不关心您将 ldflags 混合到 cflags 中,反之亦然。 似乎有时 C 开发人员这样做会导致诸如 #25493 或https://github.com/golang/go/issues/23749#issuecomment -379969818 之类的问题

啊,我看到我们已经有票了,所以让我提一下 protobuf 中的“-D_THREAD_SAFE”,如#25493 中所述

更改https://golang.org/cl/115415提到了这个问题: cmd/go: accept more safe CFLAGS/LDFLAGS

更改https://golang.org/cl/115435提到了这个问题: [release-branch.go1.10] cmd/go: accept more safe CFLAGS/LDFLAGS

更改https://golang.org/cl/115436提到这个问题: [release-branch.go1.9] cmd/go: accept more safe CFLAGS/LDFLAGS

大家好,
当我们仍然无法使用截至 2018 年 9 月 4 日的最新版本的 Go 构建bimg时,为什么会关闭此问题?
请参阅问题: https :
自 Go 1.10 以来,我们无法构建任何导入bimg东西,并且该问题在 Go 1.11 中仍然存在
我们得到的错误信息是这样的:

# go build
go build gopkg.in/h2non/bimg.v1: invalid flag in pkg-config --libs: -Wl,--export-dynamic

有什么建议吗?

编辑:
我创建了一个新问题: https :

我相信这个白名单负责以下内容: https :

@alexflint此问题已关闭,请创建一个新问题

此页面是否有帮助?
0 / 5 - 0 等级