From 93415b198a3ef427c02893b8fdf036aa75ffe50f Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Wed, 21 Jun 2017 10:03:44 -0700 Subject: actions: error handling and API changed This commit changes the error handling for the actions package to use the error handling library github.com/pkg/errors. This means replacing "errors" with "github.com/pkg/errors", reworking some of the error values, and wrapping some errors with additional context. This commit also changes the Protector/Policy API, moving most of the package functionality into Protector or Policy methods. These types are now "locked" when they are queried from the filesystem, and Unlock() must be used to get their corresponding keys. Note that only certain operations will require unlocking the keys. Certain unnecessary functions and methods are also removed. This CL also fixes two bugs reported by Tyler Hicks in CreateConfigFile. CPU time is used instead of wall time, and kiB is used instead of kB. Change-Id: I88f45659e9fe4938d148843e3289e7b6d5b698d8 --- actions/config.go | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'actions/config.go') diff --git a/actions/config.go b/actions/config.go index 2010ef1..1d81ff9 100644 --- a/actions/config.go +++ b/actions/config.go @@ -27,6 +27,8 @@ import ( "runtime" "time" + "github.com/pkg/errors" + "golang.org/x/sys/unix" "fscrypt/crypto" @@ -68,7 +70,7 @@ func CreateConfigFile(target time.Duration, useLegacy bool) error { case os.IsExist(err): return ErrConfigFileExists case err != nil: - return util.UnderlyingError(err) + return err } defer configFile.Close() @@ -99,15 +101,14 @@ func getConfig() (*metadata.Config, error) { case os.IsNotExist(err): return nil, ErrNoConfigFile case err != nil: - return nil, util.UnderlyingError(err) + return nil, err } defer configFile.Close() log.Printf("Reading config from %q\n", ConfigFileLocation) config, err := metadata.ReadConfig(configFile) if err != nil { - log.Printf("ReadConfig() = %v", err) - return nil, ErrBadConfigFile + return nil, errors.Wrap(ErrBadConfigFile, err.Error()) } // Use system defaults if not specified @@ -128,8 +129,8 @@ func getConfig() (*metadata.Config, error) { log.Printf("Falling back to filenames mode of %q", config.Options.Filenames) } - if !config.IsValid() { - return nil, ErrBadConfigFile + if err := config.CheckValidity(); err != nil { + return nil, errors.Wrap(ErrBadConfigFile, err.Error()) } return config, nil @@ -203,8 +204,8 @@ func ramLimit() int64 { err := unix.Sysinfo(&info) // The sysinfo syscall only fails if given a bad address util.NeverError(err) - // Use half the RAM and convert to kB. - return int64(info.Totalram / 1000 / 2) + // Use half the RAM and convert to kiB. + return int64(info.Totalram / 1024 / 2) } // betweenCosts returns a cost between a and b. Specifically, it returns the @@ -222,11 +223,23 @@ func timeHashingCosts(costs *metadata.HashingCosts) (time.Duration, error) { } defer passphrase.Wipe() - start := time.Now() + // Be sure to measure CPU time, not wall time (time.Now) + begin := cpuTimeInNanoseconds() hash, err := crypto.PassphraseHash(passphrase, timingSalt, costs) if err == nil { hash.Wipe() } + end := cpuTimeInNanoseconds() - return time.Since(start), err + return time.Duration(end - begin), nil +} + +// cpuTimeInNanoseconds returns the nanosecond count based on the process's CPU usage. +// This number has no absolute meaning, only relative meaning to other calls. +func cpuTimeInNanoseconds() int64 { + var ts unix.Timespec + err := unix.ClockGettime(unix.CLOCK_PROCESS_CPUTIME_ID, &ts) + // ClockGettime fails if given a bad address or on a VERY old system. + util.NeverError(err) + return unix.TimespecToNsec(ts) } -- cgit v1.2.3