@cryptotaxi247 / kubo / commits / 7a4c377bb

fix(keystore): avoid racy filesystem access

Instead of checking then performing a file operation, perform the file operation and check the error.

Steven Allen committed Mar 15, 2020 at 23:40 UTC 7a4c377bbb05b68e39c917c6a394885816504efa
1 file changed +10 -17
keystore/keystore.go
+10 -17
@@ -47,16 +47,13 @@ type FSKeystore struct {
47
48 // NewFSKeystore returns a new filesystem-backed keystore.
49 func NewFSKeystore(dir string) (*FSKeystore, error) {
50 - _, err := os.Stat(dir)
51 - if err != nil {
52 - if !os.IsNotExist(err) {
53 - return nil, err
54 - }
55 - if err := os.Mkdir(dir, 0700); err != nil {
56 - return nil, err
57 - }
50 + err := os.Mkdir(dir, 0700)
51 + switch {
52 + case os.IsExist(err):
53 + case err == nil:
54 + default:
55 + return nil, err
56 }
59 -
57 return &FSKeystore{dir}, nil
58 }
59
@@ -91,15 +88,11 @@ func (ks *FSKeystore) Put(name string, k ci.PrivKey) error {
88
89 kp := filepath.Join(ks.dir, name)
90
94 - _, err = os.Stat(kp)
95 - if err == nil {
96 - return ErrKeyExists
97 - } else if !os.IsNotExist(err) {
98 - return err
99 - }
100 -
101 - fi, err := os.Create(kp)
91 + fi, err := os.OpenFile(kp, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600)
92 if err != nil {
93 + if os.IsExist(err) {
94 + err = ErrKeyExists
95 + }
96 return err
97 }
98 defer fi.Close()