From 2758c75cae2896b7f1327fe00f60a1c017c0e0d1 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 10 Dec 2016 12:59:54 +0100 Subject: ctlsock: sanitize paths before passing them to the backend You used to be able to crash gocryptfs by passing "/foo" of "foo/" to the ctlsock. Fixes https://github.com/rfjakob/gocryptfs/issues/66 --- internal/ctlsock/ctlsock_serve.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'internal/ctlsock/ctlsock_serve.go') diff --git a/internal/ctlsock/ctlsock_serve.go b/internal/ctlsock/ctlsock_serve.go index 571260d..63515c0 100644 --- a/internal/ctlsock/ctlsock_serve.go +++ b/internal/ctlsock/ctlsock_serve.go @@ -5,6 +5,7 @@ package ctlsock import ( "encoding/json" "errors" + "fmt" "io" "net" "os" @@ -35,6 +36,9 @@ type ResponseStruct struct { ErrNo int32 // ErrText is a detailed error message. ErrText string + // WarnText contains warnings that may have been encountered while + // processing the message. + WarnText string } type ctlSockHandler struct { @@ -102,14 +106,19 @@ func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) { func (ch *ctlSockHandler) handleRequest(in *RequestStruct, conn *net.UnixConn) { var err error var out ResponseStruct + var inPath, clean string if in.DecryptPath != "" && in.EncryptPath != "" { err = errors.New("Ambigous") } else if in.DecryptPath == "" && in.EncryptPath == "" { err = errors.New("No operation") } else if in.DecryptPath != "" { - out.Result, err = ch.fs.DecryptPath(in.DecryptPath) + inPath = in.DecryptPath + clean = SanitizePath(inPath) + out.Result, err = ch.fs.DecryptPath(clean) } else if in.EncryptPath != "" { - out.Result, err = ch.fs.EncryptPath(in.EncryptPath) + inPath = in.EncryptPath + clean = SanitizePath(inPath) + out.Result, err = ch.fs.EncryptPath(clean) } if err != nil { out.ErrText = err.Error() @@ -121,6 +130,9 @@ func (ch *ctlSockHandler) handleRequest(in *RequestStruct, conn *net.UnixConn) { } } } + if inPath != clean { + out.WarnText = fmt.Sprintf("Non-canonical input path %q has been interpreted as %q", inPath, clean) + } sendResponse(&out, conn) } @@ -130,6 +142,8 @@ func sendResponse(msg *ResponseStruct, conn *net.UnixConn) { tlog.Warn.Printf("ctlsock: Marshal failed: %v", err) return } + // For convenience for the user, add a newline at the end. + jsonMsg = append(jsonMsg, '\n') _, err = conn.Write(jsonMsg) if err != nil { tlog.Warn.Printf("ctlsock: Write failed: %v", err) -- cgit v1.2.3