diff options
author | Rob Landley <rob@landley.net> | 2015-09-12 15:46:46 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2015-09-12 15:46:46 -0500 |
commit | edae0b07db841e3bf8449d591971f04c9957ecbc (patch) | |
tree | 186c7e6504e3217ba630714b4577c23f4ac3ec94 | |
parent | e5354ca12a232b3f97726214254a868771cb70d1 (diff) | |
download | toybox-edae0b07db841e3bf8449d591971f04c9957ecbc.tar.gz |
Fix a find segfault.
Elliott Hughes found a bug https://android-review.googlesource.com/#/c/170020/
and Daniel K. Levy worked out the problem: the user/group/newer arguments
to find weren't consuming their arguments when not checking the results of
their comparison (because an earlier test had already caused their
parenthetical group to fail). This confused the argument parsing logic
and could lead to segfaults.
I applied a different fix that reorganized the existing tests instead of
adding a new test. (Looks like a big commit but it's mostly whitespace
due to extra curly brackets changing indendentation levels.)
-rwxr-xr-x | tests/find.test | 4 | ||||
-rw-r--r-- | toys/posix/find.c | 36 |
2 files changed, 24 insertions, 16 deletions
diff --git a/tests/find.test b/tests/find.test index cbbce5fd..65bbb501 100755 --- a/tests/find.test +++ b/tests/find.test @@ -39,4 +39,8 @@ testing "find -type f -a -print" \ testing "find -print -o -print" \ "find dir -type f -a \( -print -o -print \)" "dir/file\n" "" "" +# these were erroring or segfaulting: +# find -type f -user nobody -exec : \; +# find -type f -user nobody -exec : -exec : \; + rm -rf dir diff --git a/toys/posix/find.c b/toys/posix/find.c index 10585294..aca19845 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -336,26 +336,30 @@ static int do_find(struct dirtree *new) } u; } *udl; - if (!new && ss[1]) { - udl = xmalloc(sizeof(*udl)); - dlist_add_nomalloc(&TT.argdata, (void *)udl); + if (!new) { + if (ss[1]) { + udl = xmalloc(sizeof(*udl)); + dlist_add_nomalloc(&TT.argdata, (void *)udl); - if (*s == 'u') udl->u.uid = xgetpwnamid(ss[1])->pw_uid; - else if (*s == 'g') udl->u.gid = xgetgrnamid(ss[1])->gr_gid; - else { - struct stat st; + if (*s == 'u') udl->u.uid = xgetpwnamid(ss[1])->pw_uid; + else if (*s == 'g') udl->u.gid = xgetgrnamid(ss[1])->gr_gid; + else { + struct stat st; - xstat(ss[1], &st); - udl->u.tm = st.st_mtim; + xstat(ss[1], &st); + udl->u.tm = st.st_mtim; + } } - } else if (check) { + } else { udl = (void *)llist_pop(&argdata); - if (*s == 'u') test = new->st.st_uid == udl->u.uid; - else if (*s == 'g') test = new->st.st_gid == udl->u.gid; - else { - test = new->st.st_mtim.tv_sec > udl->u.tm.tv_sec; - if (new->st.st_mtim.tv_sec == udl->u.tm.tv_sec) - test = new->st.st_mtim.tv_nsec > udl->u.tm.tv_nsec; + if (check) { + if (*s == 'u') test = new->st.st_uid == udl->u.uid; + else if (*s == 'g') test = new->st.st_gid == udl->u.gid; + else { + test = new->st.st_mtim.tv_sec > udl->u.tm.tv_sec; + if (new->st.st_mtim.tv_sec == udl->u.tm.tv_sec) + test = new->st.st_mtim.tv_nsec > udl->u.tm.tv_nsec; + } } } } else if (!strcmp(s, "exec") || !strcmp("ok", s) |