[Secure Coding] master: Add chapter on Go (13faeec)
fweimer at fedoraproject.org
fweimer at fedoraproject.org
Mon May 26 12:58:29 UTC 2014
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit 13faeec63da544dd64c453a5fd810f7b6d758dbd
Author: Florian Weimer <fweimer at redhat.com>
Date: Mon May 26 14:58:01 2014 +0200
Add chapter on Go
>---------------------------------------------------------------
defensive-coding/Makefile | 2 +-
defensive-coding/en-US/Defensive_Coding.xml | 1 +
defensive-coding/en-US/Go.xml | 90 +++++++++++++++++++++++++++
defensive-coding/src/.gitignore | 1 +
defensive-coding/src/Go-Error_Handling.go | 48 ++++++++++++++
defensive-coding/src/src.mk | 6 ++
6 files changed, 147 insertions(+), 1 deletions(-)
diff --git a/defensive-coding/Makefile b/defensive-coding/Makefile
index 6220afc..2090dad 100644
--- a/defensive-coding/Makefile
+++ b/defensive-coding/Makefile
@@ -9,7 +9,7 @@ build: build-src build-manual
build-snippets:
mkdir -p en-US/snippets
python scripts/split-snippets.py . \
- src/*.c src/*.cpp src/*.java src/*.py
+ src/*.c src/*.cpp src/*.java src/*.py src/*.go
build-manual: build-snippets
publican build --formats=html,epub,pdf --langs=en-US
diff --git a/defensive-coding/en-US/Defensive_Coding.xml b/defensive-coding/en-US/Defensive_Coding.xml
index a9baeb3..ee96c8d 100644
--- a/defensive-coding/en-US/Defensive_Coding.xml
+++ b/defensive-coding/en-US/Defensive_Coding.xml
@@ -8,6 +8,7 @@
<xi:include href="CXX.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Java.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Python.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="Go.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Vala.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
<part>
diff --git a/defensive-coding/en-US/Go.xml b/defensive-coding/en-US/Go.xml
new file mode 100644
index 0000000..0e44d5e
--- /dev/null
+++ b/defensive-coding/en-US/Go.xml
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<chapter id="chap-Defensive_Coding-Go">
+<title>The Go Programming Language</title>
+<para>
+ This chapter contains language-specific recommendations for Go.
+</para>
+<section id="chap-Defensive_Coding-Go-Memory_Safety">
+ <title>Memory safety</title>
+ <para>
+ Go provides memory safety, but only if the program is not executed
+ in parallel (that is, <envar>GOMAXPROCS</envar> is not larger than
+ <literal>1</literal>). The reason is that interface values and
+ slices consist of multiple words are not updated atomically.
+ Another thread of execution can observe an inconsistent pairing
+ between type information and stored value (for interfaces) or
+ pointer and length (for slices), and such inconsistency can lead
+ to a memory safety violation.
+ </para>
+ <para>
+ Code which does not run in parallel and does not use the
+ <literal>unsafe</literal> package (or other packages which expose
+ unsafe constructs) is memory-safe. For example, invalid casts and
+ out-of-range subscripting cause panics and run time.
+ </para>
+ <para>
+ Keep in mind that finalization can introduce parallelism because
+ finalizers are executed concurrently, potentially interleaved with
+ the rest of the program.
+ </para>
+</section>
+<section id="chap-Defensive_Coding-Go-Error_Handling">
+ <title>Error handling</title>
+ <para>
+ Only a few common operations (such as pointer dereference, integer
+ division, array subscripting) trigger exceptions in Go, called
+ <emphasis>panics</emphasis>. Most interfaces in the standard
+ library use a separate return value of type
+ <literal>error</literal> to signal error.
+ </para>
+ <para>
+ Not checking error return values can lead to incorrect operation
+ and data loss (especially in the case of writes, using interfaces
+ such as <literal>io.Writer</literal>).
+ </para>
+ <para>
+ The correct way to check error return values depends on the
+ function or method being called. In the majority of cases, the
+ first step after calling a function should be an error check
+ against the <literal>nil</literal> value, handling any encountered
+ error. See <xref
+ linkend="ex-Defensive_Coding-Go-Error_Handling-Regular"/> for
+ details.
+ </para>
+ <example id="ex-Defensive_Coding-Go-Error_Handling-Regular">
+ <title>Regular error handling in Go</title>
+ <xi:include href="snippets/Go-Error_Handling-Regular.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </example>
+ <para>
+ However, with <literal>io.Reader</literal>,
+ <literal>io.ReaderAt</literal> and related interfaces, it is
+ necessary to check for a non-zero number of read bytes first, as
+ shown in <xref
+ linkend="ex-Defensive_Coding-Go-Error_Handling-IO"/>. If this
+ pattern is not followed, data loss may occur. This is due to the
+ fact that the <literal>io.Reader</literal> interface permits
+ returning both data and an error at the same time.
+ </para>
+ <example id="ex-Defensive_Coding-Go-Error_Handling-IO">
+ <title>Read error handling in Go</title>
+ <xi:include href="snippets/Go-Error_Handling-IO.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </example>
+</section>
+<section id="chap-Defensive_Coding-Go-Garbage_Collector">
+ <title>Garbage Collector</title>
+ <para>
+ Older Go releases (before Go 1.3) use a conservative garbage
+ collector without blacklisting. This means that data blobs can
+ cause retention of unrelated data structures because the data is
+ conservatively interpreted as pointers. This phenomenon can be
+ triggered accidentally on 32-bit architectures and is more likely
+ to occur if the heap grows larger. On 64-bit architectures, it
+ may be possible to trigger it deliberately—it is unlikely to occur
+ spontaneously.
+ </para>
+</section>
+</chapter>
diff --git a/defensive-coding/src/.gitignore b/defensive-coding/src/.gitignore
index 4adbfe5..335a122 100644
--- a/defensive-coding/src/.gitignore
+++ b/defensive-coding/src/.gitignore
@@ -4,5 +4,6 @@
/TLS-Client-OpenSSL
/XML-Parser-Expat
/XML-Parser-Qt
+/Go-Error_Handling
*.class
*.o
diff --git a/defensive-coding/src/Go-Error_Handling.go b/defensive-coding/src/Go-Error_Handling.go
new file mode 100644
index 0000000..d546018
--- /dev/null
+++ b/defensive-coding/src/Go-Error_Handling.go
@@ -0,0 +1,48 @@
+package main
+
+import "io"
+
+//+ Go Error_Handling-Regular
+type Processor interface {
+ Process(buf []byte) (message string, err error)
+}
+
+type ErrorHandler interface {
+ Handle(err error)
+}
+
+func RegularError(buf []byte, processor Processor,
+ handler ErrorHandler) (message string, err error) {
+ message, err = processor.Process(buf)
+ if err != nil {
+ handler.Handle(err)
+ return "", err
+ }
+ return
+}
+//-
+
+//+ Go Error_Handling-IO
+func IOError(r io.Reader, buf []byte, processor Processor,
+ handler ErrorHandler) (message string, err error) {
+ n, err := r.Read(buf)
+ // First check for available data.
+ if n > 0 {
+ message, err = processor.Process(buf[0:n])
+ // Regular error handling.
+ if err != nil {
+ handler.Handle(err)
+ return "", err
+ }
+ }
+ // Then handle any error.
+ if err != nil {
+ handler.Handle(err)
+ return "", err
+ }
+ return
+}
+//-
+
+func main() {
+}
diff --git a/defensive-coding/src/src.mk b/defensive-coding/src/src.mk
index d47fc09..18bd592 100644
--- a/defensive-coding/src/src.mk
+++ b/defensive-coding/src/src.mk
@@ -2,10 +2,12 @@
CC = gcc
CXX = g++
+GCCGO = gccgo
CWARNFLAGS = -Wall -W -Wno-unused-parameter -Werror=implicit-function-declaration
CXXWARNFLAGS = -Wall -W
CFLAGS = -std=gnu99 -O2 $(CWARNFLAGS) -g
CXXFLAGS = -std=c++03 -O2 $(CXXWARNFLAGS) -g
+GOFLAGS = -O2 -Wall -W
LDFLAGS = -g
# List files which should only be compiled for syntax checking.
@@ -41,6 +43,7 @@ compile_and_link += XML-Parser-Expat
LIBS_XML-Parser-Expat = -lexpat
compile_and_link += XML-Parser-Qt
LIBS_XML-Parser-Qt = -lQtCore -lQtXml
+compile_and_link += Go-Error_Handling
# Define preprocessor symbols if certain functions exist.
CHECK_FUNCTION = crypto/X509_check_host/-DHAVE_X509_CHECK_HOST \
@@ -68,6 +71,9 @@ src/%.class: src/%.java
src/%: src/%.o
$(CXX) $(LDFLAGS) $^ -o $@ $(LIBS_$(notdir $@))
+src/%: src/%.go
+ $(GCCGO) $(GOFLAGS) $(LDFLAGS) -o $@ $^
+
src/TLS-Client-GNUTLS: src/tcp_connect.o
src/TLS-Client-OpenSSL: src/tcp_connect.o src/x509_check_host.o
src/TLS-Client-NSS: src/tcp_connect.o
More information about the security
mailing list