Add a flag to sort directory entries before recursing into them. Since this part of lib/ is used inside barebox as well as in scripts/bareboxenv.c, we cannot easily use stringlists from lib/, which would have made the code a bit nicer. Further, add poison.h from kernel 4.5-rc1, which was the base for importing linux headers under scripts/ in a883d9a. This is required for actually using kernel linked lists within scripts/ tools. Signed-off-by: Florian Bäuerle <florian.baeuerle@xxxxxxxxxxxx> --- include/libbb.h | 1 + lib/list_sort.c | 3 +- lib/recursive_action.c | 61 +++++++++++++++++--- scripts/bareboxenv.c | 6 ++ scripts/include/linux/list_sort.h | 1 + scripts/include/linux/poison.h | 93 ++++++++++++++++++++++++++++++- 6 files changed, 155 insertions(+), 10 deletions(-) create mode 100644 scripts/include/linux/list_sort.h diff --git a/include/libbb.h b/include/libbb.h index a362bd32d..1f6afaa27 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -17,6 +17,7 @@ enum { ACTION_FOLLOWLINKS = (1 << 1), ACTION_DEPTHFIRST = (1 << 2), /*ACTION_REVERSE = (1 << 3), - unused */ + ACTION_SORT = (1 << 4), }; int recursive_action(const char *fileName, unsigned flags, diff --git a/lib/list_sort.c b/lib/list_sort.c index b7e74f260..84c6f6465 100644 --- a/lib/list_sort.c +++ b/lib/list_sort.c @@ -1,7 +1,6 @@ #ifndef __BAREBOX__ #include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> +#define EXPORT_SYMBOL(x) #else #include <common.h> #include <malloc.h> diff --git a/lib/recursive_action.c b/lib/recursive_action.c index 345d3db0c..0d7ddbd8e 100644 --- a/lib/recursive_action.c +++ b/lib/recursive_action.c @@ -16,6 +16,14 @@ #endif +#include <linux/list.h> +#include <linux/list_sort.h> + +struct dirlist { + char *dirname; + struct list_head list; +}; + /* * Walk down all the directories under the specified * location, and do something (something specified @@ -33,6 +41,19 @@ static int true_action(const char *fileName, struct stat *statbuf, return 1; } +static int cmp_dirlist(void *priv, struct list_head *a, struct list_head *b) +{ + struct dirlist *ra, *rb; + + if (a == b) + return 0; + + ra = list_entry(a, struct dirlist, list); + rb = list_entry(b, struct dirlist, list); + + return strcmp(ra->dirname, rb->dirname); +} + /* fileAction return value of 0 on any file in directory will make * recursive_action() return 0, but it doesn't stop directory traversal * (fileAction/dirAction will be called on each file). @@ -55,9 +76,12 @@ int recursive_action(const char *fileName, { struct stat statbuf; unsigned follow; + unsigned sort; int status; DIR *dir; struct dirent *next; + struct dirlist *entry, *entry_tmp; + LIST_HEAD(dirs); if (!fileAction) fileAction = true_action; if (!dirAction) dirAction = true_action; @@ -106,20 +130,43 @@ int recursive_action(const char *fileName, /* To trigger: "find -exec rm -rf {} \;" */ goto done_nak_warn; } + sort = flags & ACTION_SORT; status = 1; while ((next = readdir(dir)) != NULL) { - char *nextFile; - - nextFile = concat_subpath_file(fileName, next->d_name); + char *nextFile = concat_subpath_file(fileName, next->d_name); if (nextFile == NULL) continue; - /* now descend into it, forcing recursion. */ - if (!recursive_action(nextFile, flags | ACTION_RECURSE, - fileAction, dirAction, userData, depth+1)) { - status = 0; + + if (sort) { + struct dirlist *e = malloc(sizeof(*e)); + e->dirname = strdup(next->d_name); + list_add(&e->list, &dirs); + } else { + /* descend into it, forcing recursion. */ + if (!recursive_action(nextFile, flags | ACTION_RECURSE, + fileAction, dirAction, userData, depth+1)) { + status = 0; + } } + free(nextFile); } + + if (sort) { + list_sort(NULL, &dirs, &cmp_dirlist); + + list_for_each_entry_safe(entry, entry_tmp, &dirs, list) + { + /* descend into it, forcing recursion. */ + if (!recursive_action(entry->dirname, flags | ACTION_RECURSE, + fileAction, dirAction, userData, depth+1)) { + status = 0; + } + + list_del(&entry->list); + free(entry->dirname); + } + } closedir(dir); if ((flags & ACTION_DEPTHFIRST) && !dirAction(fileName, &statbuf, userData, depth)) { diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c index 249e65b25..de57c2fce 100644 --- a/scripts/bareboxenv.c +++ b/scripts/bareboxenv.c @@ -34,6 +34,7 @@ #include "compiler.h" #define debug(...) +#define printk_once(...) /* Find out if the last character of a string matches the one given. * Don't underrun the buffer if the string length is 0. @@ -54,6 +55,7 @@ enum { ACTION_FOLLOWLINKS = (1 << 1), ACTION_DEPTHFIRST = (1 << 2), /*ACTION_REVERSE = (1 << 3), - unused */ + ACTION_SORT = (1 << 4), }; int recursive_action(const char *fileName, unsigned flags, @@ -95,6 +97,10 @@ static char *concat_subpath_file(const char *path, const char *f) return concat_path_file(path, f); } +#include <linux/list.h> +#include <linux/list_sort.h> +#include <linux/compiler.h> +#include "../lib/list_sort.c" #include "../lib/recursive_action.c" #include "../include/envfs.h" #include "../crypto/crc32.c" diff --git a/scripts/include/linux/list_sort.h b/scripts/include/linux/list_sort.h new file mode 100644 index 000000000..be889c9ae --- /dev/null +++ b/scripts/include/linux/list_sort.h @@ -0,0 +1 @@ +#include <../../include/linux/list_sort.h> diff --git a/scripts/include/linux/poison.h b/scripts/include/linux/poison.h index 0c27bdf14..15927ebc2 100644 --- a/scripts/include/linux/poison.h +++ b/scripts/include/linux/poison.h @@ -1 +1,92 @@ -#include "../../../include/linux/poison.h" +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_POISON_H +#define _LINUX_POISON_H + +/********** include/linux/list.h **********/ + +/* + * Architectures might want to move the poison pointer offset + * into some well-recognized area such as 0xdead000000000000, + * that is also not mappable by user-space exploits: + */ +#ifdef CONFIG_ILLEGAL_POINTER_VALUE +# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL) +#else +# define POISON_POINTER_DELTA 0 +#endif + +/* + * These are non-NULL pointers that will result in page faults + * under normal circumstances, used to verify that nobody uses + * non-initialized list entries. + */ +#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA) +#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA) + +/********** include/linux/timer.h **********/ +/* + * Magic number "tsta" to indicate a static timer initializer + * for the object debugging code. + */ +#define TIMER_ENTRY_STATIC ((void *) 0x300 + POISON_POINTER_DELTA) + +/********** mm/debug-pagealloc.c **********/ +#ifdef CONFIG_PAGE_POISONING_ZERO +#define PAGE_POISON 0x00 +#else +#define PAGE_POISON 0xaa +#endif + +/********** mm/page_alloc.c ************/ + +#define TAIL_MAPPING ((void *) 0x400 + POISON_POINTER_DELTA) + +/********** mm/slab.c **********/ +/* + * Magic nums for obj red zoning. + * Placed in the first word before and the first word after an obj. + */ +#define RED_INACTIVE 0x09F911029D74E35BULL /* when obj is inactive */ +#define RED_ACTIVE 0xD84156C5635688C0ULL /* when obj is active */ + +#define SLUB_RED_INACTIVE 0xbb +#define SLUB_RED_ACTIVE 0xcc + +/* ...and for poisoning */ +#define POISON_INUSE 0x5a /* for use-uninitialised poisoning */ +#define POISON_FREE 0x6b /* for use-after-free poisoning */ +#define POISON_END 0xa5 /* end-byte of poisoning */ + +/********** arch/$ARCH/mm/init.c **********/ +#define POISON_FREE_INITMEM 0xcc + +/********** arch/ia64/hp/common/sba_iommu.c **********/ +/* + * arch/ia64/hp/common/sba_iommu.c uses a 16-byte poison string with a + * value of "SBAIOMMU POISON\0" for spill-over poisoning. + */ + +/********** fs/jbd/journal.c **********/ +#define JBD_POISON_FREE 0x5b +#define JBD2_POISON_FREE 0x5c + +/********** drivers/base/dmapool.c **********/ +#define POOL_POISON_FREED 0xa7 /* !inuse */ +#define POOL_POISON_ALLOCATED 0xa9 /* !initted */ + +/********** drivers/atm/ **********/ +#define ATM_POISON_FREE 0x12 +#define ATM_POISON 0xdeadbeef + +/********** kernel/mutexes **********/ +#define MUTEX_DEBUG_INIT 0x11 +#define MUTEX_DEBUG_FREE 0x22 +#define MUTEX_POISON_WW_CTX ((void *) 0x500 + POISON_POINTER_DELTA) + +/********** lib/flex_array.c **********/ +#define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ + +/********** security/ **********/ +#define KEY_DESTROY 0xbd + +#endif -- 2.19.2 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox