From da6051ac2b79bcf397f3165c2ed8318e4c75adb1 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 27 Mar 2014 21:04:41 +0100 Subject: [PATCH] Add static_build tag which avoids user.Current() Its not safe to use os/user.Current() in a statically linked program. You will be getting warnings like: warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking We avoid this when building with -tag static_build by parsing /etc/passwd directly for the homedir. --- auth.go | 7 +------ homedir.go | 28 ++++++++++++++++++++++++++++ homedir_dynamic.go | 15 +++++++++++++++ homedir_static.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 homedir.go create mode 100644 homedir_dynamic.go create mode 100644 homedir_static.go diff --git a/auth.go b/auth.go index c5dee6af..98017b69 100644 --- a/auth.go +++ b/auth.go @@ -6,7 +6,6 @@ import ( "errors" "io" "os" - "os/user" "strconv" ) @@ -55,11 +54,7 @@ type Auth interface { func (conn *Conn) Auth(methods []Auth) error { if methods == nil { uid := strconv.Itoa(os.Getuid()) - u, err := user.Current() - if err != nil { - return err - } - methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, u.HomeDir)} + methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())} } in := bufio.NewReader(conn.transport) err := conn.transport.SendNullByte() diff --git a/homedir.go b/homedir.go new file mode 100644 index 00000000..0b745f93 --- /dev/null +++ b/homedir.go @@ -0,0 +1,28 @@ +package dbus + +import ( + "os" + "sync" +) + +var ( + homeDir string + homeDirLock sync.Mutex +) + +func getHomeDir() string { + homeDirLock.Lock() + defer homeDirLock.Unlock() + + if homeDir != "" { + return homeDir + } + + homeDir = os.Getenv("HOME") + if homeDir != "" { + return homeDir + } + + homeDir = lookupHomeDir() + return homeDir +} diff --git a/homedir_dynamic.go b/homedir_dynamic.go new file mode 100644 index 00000000..2732081e --- /dev/null +++ b/homedir_dynamic.go @@ -0,0 +1,15 @@ +// +build !static_build + +package dbus + +import ( + "os/user" +) + +func lookupHomeDir() string { + u, err := user.Current() + if err != nil { + return "/" + } + return u.HomeDir +} diff --git a/homedir_static.go b/homedir_static.go new file mode 100644 index 00000000..b9d9cb55 --- /dev/null +++ b/homedir_static.go @@ -0,0 +1,45 @@ +// +build static_build + +package dbus + +import ( + "bufio" + "os" + "strconv" + "strings" +) + +func lookupHomeDir() string { + myUid := os.Getuid() + + f, err := os.Open("/etc/passwd") + if err != nil { + return "/" + } + defer f.Close() + + s := bufio.NewScanner(f) + + for s.Scan() { + if err := s.Err(); err != nil { + break + } + + line := strings.TrimSpace(s.Text()) + if line == "" { + continue + } + + parts := strings.Split(line, ":") + + if len(parts) >= 6 { + uid, err := strconv.Atoi(parts[2]) + if err == nil && uid == myUid { + return parts[5] + } + } + } + + // Default to / if we can't get a better value + return "/" +}