Repository : http://git.fedorahosted.org/git/?p=secure-coding.git On branch : master >--------------------------------------------------------------- commit 13faeec63da544dd64c453a5fd810f7b6d758dbd Author: Florian Weimer <fweimer@xxxxxxxxxx> 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
-- security mailing list security@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/security