mesh-files: find writes the NUL itself, so a list or search through root runs at all (issue 1409) #668
@@ -32,6 +32,12 @@ func (r *fakeRoot) Run(bin string, args ...string) ([]byte, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.calls = append(r.calls, bin+" "+strings.Join(args, " "))
|
||||
for _, a := range append([]string{bin}, args...) {
|
||||
if strings.ContainsRune(a, 0) {
|
||||
// The kernel refuses a program argument holding a NUL byte, as exec does on a node.
|
||||
return nil, fmt.Errorf("fork/exec /usr/bin/sudo: invalid argument")
|
||||
}
|
||||
}
|
||||
if e, ok := r.fail[bin+" "+strings.Join(args, " ")]; ok {
|
||||
return nil, e
|
||||
}
|
||||
@@ -672,7 +678,7 @@ func TestTheReadsFallBackToRoot(t *testing.T) {
|
||||
t.Errorf("readlink through root: %+v %v", rl, err)
|
||||
}
|
||||
// list
|
||||
g.root.out["/usr/bin/find -H "+in+" -mindepth 1 -maxdepth 1 -printf %y\t%U\t%G\t%m\t%s\t%l\t%f\x00"] =
|
||||
g.root.out["/usr/bin/find -H "+in+" -mindepth 1 -maxdepth 1 -printf %y\t%U\t%G\t%m\t%s\t%l\t%f\\0"] =
|
||||
"f\t1000\t998\t640\t2\t\tf\x00d\t1000\t1000\t755\t4096\t\tsub dir\x00l\t1000\t1000\t777\t1\tf\tl\x00"
|
||||
ls, err := g.List(in)
|
||||
if err != nil || ls.Count != 3 {
|
||||
@@ -689,7 +695,7 @@ func TestTheReadsFallBackToRoot(t *testing.T) {
|
||||
t.Errorf("entries: %+v", ls.Entries)
|
||||
}
|
||||
// search: the files are listed by find, the secret ones skipped by name, the rest read through cat
|
||||
g.root.out["/usr/bin/find -H "+locked+" -maxdepth 5 -xdev -type f -printf %p\x00"] =
|
||||
g.root.out["/usr/bin/find -H "+locked+" -maxdepth 5 -xdev -type f -printf %p\\0"] =
|
||||
in + "/f\x00" + locked + "/.ssh/id_rsa\x00"
|
||||
g.root.cat[in+"/f"] = "one\nneedle here\n"
|
||||
g.root.reach(in + "/f")
|
||||
@@ -706,7 +712,7 @@ func TestTheReadsFallBackToRoot(t *testing.T) {
|
||||
// a secret place is listed, as root lists it, its entries marked and never their content (ADR 0394 §7); a path
|
||||
// that is not there under a directory the account may not enter is said missing (design 39 parts §15)
|
||||
secretDir := locked + "/.ssh"
|
||||
g.root.out["/usr/bin/find -H "+secretDir+" -mindepth 1 -maxdepth 1 -printf %y\t%U\t%G\t%m\t%s\t%l\t%f\x00"] =
|
||||
g.root.out["/usr/bin/find -H "+secretDir+" -mindepth 1 -maxdepth 1 -printf %y\t%U\t%G\t%m\t%s\t%l\t%f\\0"] =
|
||||
"f\t1000\t1000\t600\t9\t\tid_rsa\x00"
|
||||
if ls, err := g.List(secretDir); err != nil || ls.Secret == "" || len(ls.Entries) != 1 || ls.Entries[0].Name != "id_rsa" {
|
||||
t.Errorf("a secret place was not listed through root: %+v %v", ls, err)
|
||||
|
||||
@@ -610,7 +610,7 @@ func (r Reader) finishList(path string, all []Entry, total int, secret string) L
|
||||
// a name cannot confuse it: the fields end with a NUL, and the name is the last.
|
||||
func (r Reader) listAsRoot(path string, names accounts) ([]Entry, error) {
|
||||
out, err := r.Root.Run("/usr/bin/find", "-H", path, "-mindepth", "1", "-maxdepth", "1", "-printf",
|
||||
"%y\t%U\t%G\t%m\t%s\t%l\t%f\x00")
|
||||
"%y\t%U\t%G\t%m\t%s\t%l\t%f\\0") // find writes the NUL: an argument may not hold one
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s cannot be listed, not even through sudo: %v", path, err)
|
||||
}
|
||||
@@ -967,7 +967,7 @@ func (r Reader) Search(ask SearchAsk) (SearchAnswer, error) {
|
||||
// and searches each: the names are judged first, so no credential file is read.
|
||||
func (r Reader) searchBelowAsRoot(p string, depth int, needle string, fold bool, bound int, deadline time.Time, a *SearchAnswer) error {
|
||||
out, err := r.Root.Run("/usr/bin/find", "-H", p, "-maxdepth", strconv.Itoa(depth), "-xdev", "-type", "f",
|
||||
"-printf", "%p\x00")
|
||||
"-printf", "%p\\0") // find writes the NUL: an argument may not hold one
|
||||
if err != nil {
|
||||
a.Unreadable++
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user