What's Coming in Go 1.15
lwn.net
lwn.net
Excellent! Nice to see these sorts of infrastructure enhancements.
I think the Go devs should improve in that section a bit.
Also golang.org/x/crypto is not a core library so doesn't actually fall under the compatibility guarantee but they seem to try their best not to break it.
You can use a comment of the format '//go:linkname [localname] [method]' to link some function as another one. Notably, this includes unexported private methods in the go runtime and stdlib.
I've seen code in the wild that uses this to grab go's map hash algorithm, get monotonic time, and other things.
The go authors have used this hack themselves in the stdlib often enough because the runtime doesn't expose some knob, and rather than thinking that perhaps other developers may want that knob too, they instead use such hacks, but they also don't support said hacks (because how could you, obviously keeping all private functions stable forever is silly and impossible)
However, we try to hold x/crypto itself to the same compatibility standard as the standard library, so I think simply updating x/crypto at the same time should have made it a smooth update.
So I guess YMMV...
EDIT: I'm sad folks are downvoting for asking a question...
To be fair though, that package was depending on a private API to begin with.
If you use vulnerable crypto (willing to go with old unpatched vendored code) then you don't really need crypto at all..
The code path that failed to build was still related to the included crypto (even if it was due to compiler change).
If that was their only way to fix the crypto issue, then it's totally fine, because that way they fixed it for people who did need and exercize the crypto code path -- and those take priority over people who "bundled some crypto code but didn't exercize that code path and their build still broke".
The issue is related to AVX detection in the CPU, which has the reasonable failure path of "don't build it with AVX".
> Use of package unsafe. Packages that import unsafe may depend on internal properties of the Go implementation. We reserve the right to make changes to the implementation that may break such programs.
I suspect the crypto code you vendored used unsafe somewhere within it (whether to use `//go:linkname` or for other reasons), which would except it from the go1 compatibility promise.
See:
It doesn't seem reasonable to me. When I developed my project, vendoring /x/ projects was recommended exactly due to the breakage, so now it breaks my projects because of recommendations of the golang team.
Impressive this is only landing for Windows now after PPP made a spectacle of the lack of ASLR back in 2013. http://pwning.net/2013/04/21/exploiting-a-go-binary/
Like I know it's possible with effort and maybe it was just lack of interest or adoption (like lets be fair its not a browser writing or pdf rendering engine type of language...) so while that situation was not great it never struck me as a burning problem with practical impact in the ecosystem either.
Interested in any pointers if possible.
I was briefly learning Go a while back. I'm curious how well gorotuines and channels have held up as building blocks, and how extensively they are used in real projects.
When Go has to support a large application that defines a platform in itself, the downsides of the language rise to the forefront, but that level of expression usually isn't entailed in a Unix-style CLI tool.
(Rust also has more potential for performance scaling in this space, but with the "if you have the time for that" kind of caveat.)
edit: Now that I read this over, this complaint seems a bit misplaced in this thread, but I guess I'll leave it due to its sort of relation to cli programs in go.
When you have a CLI for some network-based service, the network latency is going to be magnitudes larger than the performance differences between Go and Rust anyway. (Or at least in 99% of cases.)
[0] https://www.youtube.com/watch?v=SM3PhGGllL0&feature=youtu.be [1] https://www.ece.rice.edu/~willmann/teng_nics_overview.html
On the other, more modular side, try something like the Gorilla toolkit e.g. https://github.com/gorilla/mux/
I'll be honest, I rarely use channels other than for timeouts/deadlines.
You’re in luck! Go is unlike a lot of other languages, and that there’s usually only one way to do something, and it’s usually the right way, or at least an acceptable way.
I would suggest you just pick a part of the standard library, such as net/http and just read away since you probably have an understanding of the fundamentals.
I don't think its worth going through other go projects to learn best practices because at that level, there's not enough complexity to learn anything that isn't painfully obvious.
There aren't really a lot of design patterns or clever tricks to learn.
Go-routines are quite ubiquitous especially in server-style projects.
The one thing I wish they added though? `go new` and have it initialise a new project structure that stopped tiny package syndrome and bizarre Makefiles in repos! [1]
[0] https://docs.google.com/presentation/d/1veyF0y6Ynr6AFzd9gXi4...
Can you explain what you mean by "bizarre Makefiles"? I've never used Makefiles for my (admittedly fairly small) Go projects, because "go build" just works.
I agree on the toplevel `main.go` vs the `./cmd/myapp/main.go` style needing catering for that only comes out as the project evolves... maybe it should be a go vet addition instead :D
[0] https://www.reddit.com/r/golang/comments/ginp22/whats_coming...
This is a BIG improvement. One of the big benefits of Go is static binaries. Having the TZ data includes will make deploying even easier.
Why would I want to have to update recompile and deploy a go binary 2-10 times a year just because Morocco decided to remove DST from one of its regions?
I'd much rather the go authors not encourage me to do something dumb like encode tzdata in a nonstandard un-updateable location in my binary rather than having it in a standardized location that the OS will update for me as appropriate.
Second point:
The way many people use containers (especially when using minimal images meant to "just run a static binary") effectively boils down to the same thing: having a "un-updateable" blob that you need to rebuild in order to get an updated version thereof.
If you have an OS with a package manager, that runs without being "reimaged" for weeks, months, years, then having a process that keeps the "OS" up to date (TZ data, security updates of shared libraries, ...) is good idea.
If you have a static binary in a minimal image, running in an environment where any software update entails "re-imaging" your machine (VM, container, ...), then your process already has to consider that running the same binary for months and years without any updates is very bad idea.
Statically linking critical components like your crypto libraries already begs for a timely and automated rebuild process. The TZ data fits the same pattern as shared libraries.
There are points to be made in favour and against shared libraries. Whatever your position is on that topic, I think it can be transferred directly to TZ embedding.
The comparison isn't other compiled languages that can easily produce static binaries (like ghc/haskell, rust, c++ (with about 2000 lines of meson or cmake or makefile, ...), etc).
The comparison is other languages Go programmers might use, like python and javascript. If someone cared about having a good type system, they wouldn't be using Go, so we have to compare Go's capabilities to other languages that are targeted at people who don't want any brilliance or type-theory, but just want a "simple language" where it's accepted as part of the "programmer condition" that you write bad code and get things done.
However, in reality, it's worth pointing out that there are very few other languages that have as seamless a static linking experience as Go. Sure, it's quite possible to statically link C(++), rust, etc, but it's more involved than it is for go. Furthermore, for those languages, there's a larger library ecosystem that dynamically depends on C libraries, so i.e. in rust you may have trouble linking any crate that depends on openssl (which quite a few do transitively). Go is the only language I know of that's created an entire culture of eschewing the C ABI as much as possible, that uses linux's syscall interface even though that means there are various things that are just plain broken (like nsswitch).
So yeah, while it's true that go isn't the only language that can be statically linked, it's one of the few that focuses on it to such an (arguably unhealthy) extreme.
Making an static binary in C/C++ is a single command-line parameter in most compilers.
"It must be familiar, roughly C-like. Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical. – Rob Pike 2"
Sources:
https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Pa...
So while they learned Java, Python, JavaScript, according to Pike they are still not good enough at their skills, so they must downgrade to Go.
Even just doing a static binary for windows and osx will require some VERY complex build systems for most languages. Not with Go. It's simple.
I hope other languages put as much effort as Go has into static linked binaries.
Session ticket keys, which are a major weak link in Forward Secrecy in TLS 1.0-1.2 [0], are now rotated automatically every day, and dropped after 7 days [1]. Session keys are also dropped once they get too old [2], instead of becoming an increasingly powerful Forward Secrecy liability.
The tls.Config.VerifyConnection callback is a much more powerful and usable way to customize peer verification [3].
X.509 root CAs are now extracted on macOS by linking directly against Security.framework with some assembly glue, instead of using cgo [4]. (Warning: awakens Cthulhu.)
crypto/x509 now ignores the 20-year-deprecated Common Name field by default [5] and has a consistent rule about invalid hostnames [6].
crypto/elliptic now provides MarshalCompressed and UnmarshalCompressed for compressed point encodings [7].
The clever TLS 1.3 downgrade canary in the server random is now enforced client side [8].
PrivateKey and PublicKey types implement Equal, giving a consistent method to build type-safe interfaces for them [9].
math/big has a new Int.FillBytes method for fixed size, zero allocation byte serialization [9], which we used all over the crypto packages.
RevocationList and CreateRevocationList were added to crypto/x509 to generate spec compliant CRLs [11].
crypto/ecdsa has two new functions, SignASN1 and VerifyASN1 that operate on encoded signatures instead of big.Ints that everyone was encoding/decoding anyway [12].
Plus some performance, cosmetic, correctness, and documentation improvements! Not a bad cycle overall, even if it made sense to focus on smaller scope tasks for a while.
[0]: https://blog.filippo.io/we-need-to-talk-about-session-ticket...
[1]: https://go.googlesource.com/go/+/43f2f5024b
[2]: https://go.googlesource.com/go/+/6ea19bb668
[3]: https://go.googlesource.com/go/+/62a3f2e27c
[4]: https://go.googlesource.com/go/+/6f52790a20
[5]: https://go.googlesource.com/go/+/d65e1b2e41
[6]: https://go.googlesource.com/go/+/9d1e120c42
[7]: https://go.googlesource.com/go/+/5c13cab36b
[8]: https://go.googlesource.com/go/+/a6c6e59655
[9]: https://go.googlesource.com/go/+/b5f2c0f502
[10]: https://go.googlesource.com/go/+/c9d5f60eaa
Wooooah, that's awesome! Up to now I think only Caddy has been doing this automatically & by default, I'm happy to see the std lib able to offer this too. Maybe we can simplify some of our code base. (Although, on second thought, Caddy can rotate the keys distributed across a cluster so as to improve TLS performance behind load balancers, for example; so we might still need to use our own home-brewed rotation. Which is fine!)
> The tls.Config.VerifyConnection callback is a much more powerful and usable way to customize peer verification [3].
Also looking forward to using this in Caddy! Right now we use VerifyPeerCertificate which is... fine, and definitely better than without it, but I am sure plenty of users will be happy to have the extra flexibility and added robustness of VerifyConnection.
Everything else looks stellar too -- keep up the good work!
There is no downside to activating ASLR either, so I'm not sure why it isn't.