88 "net/rpc"
99 "os"
1010 "os/signal"
11+ "path"
1112 "syscall"
1213 "time"
1314
@@ -79,14 +80,16 @@ func Run() error {
7980
8081 if * address != "" {
8182 network , addr := parseAddr (* address )
82- if err := clearAddr (network , addr ); err != nil {
83- return errors .Wrap (err , "Cannot remove existing unix socket" )
83+ cleanup , err := checkAddr (network , addr )
84+ if err != nil {
85+ return errors .Wrap (err , "cannot remove existing unix socket" )
8486 }
87+ defer cleanup ()
88+
8589 ln , err := net .Listen (network , addr )
8690 if err != nil {
87- return errors .Wrap (err , "Unable to listen" )
91+ return errors .Wrap (err , "unable to listen" )
8892 }
89- defer clearAddr (network , addr )
9093
9194 g .Add (func () error {
9295 for {
@@ -135,16 +138,6 @@ func Run() error {
135138 return g .Run ()
136139}
137140
138- func clearAddr (network string , addr string ) error {
139- if network != "unix" {
140- return nil
141- }
142- if _ , err := os .Stat (addr ); os .IsNotExist (err ) {
143- return nil
144- }
145- return os .Remove (addr )
146- }
147-
148141// Add an actor (function) to the group. Each actor must be pre-emptable by an
149142// interrupt function. That is, if interrupt is invoked, execute should return.
150143// Also, it must be safe to call interrupt even after execute has returned.
@@ -154,3 +147,47 @@ func clearAddr(network string, addr string) error {
154147func Add (execute func () error , interrupt func (error )) {
155148 g .Add (execute , interrupt )
156149}
150+
151+ func checkAddr (network , addr string ) (func (), error ) {
152+ if network != "unix" {
153+ return func () {}, nil
154+ }
155+ if _ , err := os .Stat (addr ); ! os .IsNotExist (err ) {
156+ return func () {}, os .Remove (addr )
157+ }
158+ if err := os .MkdirAll (path .Dir (addr ), os .ModePerm ); err != nil {
159+ return func () {}, err
160+ }
161+ if ok , err := isWritable (path .Dir (addr )); err != nil || ! ok {
162+ return func () {}, errors .Wrap (err , "socket directory is not writable" )
163+ }
164+ return func () { os .Remove (addr ) }, nil
165+ }
166+
167+ func isWritable (path string ) (isWritable bool , err error ) {
168+ info , err := os .Stat (path )
169+ if err != nil {
170+ return false , err
171+ }
172+
173+ if ! info .IsDir () {
174+ return false , fmt .Errorf ("%s isn't a directory" , path )
175+ }
176+
177+ // Check if the user bit is enabled in file permission
178+ if info .Mode ().Perm ()& (1 << (uint (7 ))) == 0 {
179+ return false , fmt .Errorf ("write permission bit is not set on this %s for user" , path )
180+ }
181+
182+ var stat syscall.Stat_t
183+ if err = syscall .Stat (path , & stat ); err != nil {
184+ return false , err
185+ }
186+
187+ err = nil
188+ if uint32 (os .Geteuid ()) != stat .Uid {
189+ return false , errors .Errorf ("user doesn't have permission to write to %s" , path )
190+ }
191+
192+ return true , nil
193+ }
0 commit comments