From shane.880088.supw at gmail.com Sun May 1 07:03:18 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Sun, 1 May 2022 12:33:18 +0530 Subject: [PATCH v4 0/2] less: fully implement -R Message-ID: <20220501070320.25599-1-shane.880088.supw@gmail.com> Reposting without major changes because it hasn't recieved any responses in 2 weeks. The switch was half-implemented earlier and it only used to trim escape sequences. This patch series implements the feature fully i.e. makes it emit color (SGR) sequences raw, and fixes other behaviour around it. Changes from v1: - count_colctrl does better validation for SGR sequences Changes from v2: - fixed corrupted patches (accidentally edited before sending) - fix code style Changes from v3: - fixed regex in commit message From shane.880088.supw at gmail.com Sun May 1 07:03:19 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Sun, 1 May 2022 12:33:19 +0530 Subject: [PATCH v4 1/2] less: fully implement -R and print color escapes In-Reply-To: <20220501070320.25599-1-shane.880088.supw@gmail.com> References: <20220501070320.25599-1-shane.880088.supw@gmail.com> Message-ID: <20220501070320.25599-2-shane.880088.supw@gmail.com> The earlier implementation used to just strip color escapes. This makes them output 'raw', coloring the screen. Like less, it assumes that the codes don't move the cursor. Emits NORMAL at newlines, like less, to deal with malformed input. count_colctrl() counts the number of chars in the next ANSI-SGR [1] escape, essentially matching for "\033\[[0-9;]*m". Doesn't work in regex find mode, but neither does the normal escape highlighting. [1] https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters --- miscutils/less.c | 54 +++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 8a0525cb7..1e2c4c5cf 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -139,7 +139,7 @@ //usage: "\n -S Truncate long lines" //usage: ) //usage: IF_FEATURE_LESS_RAW( -//usage: "\n -R Remove color escape codes in input" +//usage: "\n -R Output 'raw' color escape codes" //usage: ) //usage: "\n -~ Suppress ~s displayed past EOF" @@ -229,9 +229,6 @@ struct globals { regex_t pattern; smallint pattern_valid; #endif -#if ENABLE_FEATURE_LESS_RAW - smallint in_escape; -#endif #if ENABLE_FEATURE_LESS_ASK_TERMINAL smallint winsize_err; #endif @@ -541,26 +538,6 @@ static void read_lines(void) *--p = '\0'; continue; } -#if ENABLE_FEATURE_LESS_RAW - if (option_mask32 & FLAG_R) { - if (c == '\033') - goto discard; - if (G.in_escape) { - if (isdigit(c) - || c == '[' - || c == ';' - || c == 'm' - ) { - discard: - G.in_escape = (c != 'm'); - readpos++; - continue; - } - /* Hmm, unexpected end of "ESC [ N ; N m" sequence */ - G.in_escape = 0; - } - } -#endif { size_t new_last_line_pos = last_line_pos + 1; if (c == '\t') { @@ -864,13 +841,34 @@ static void print_found(const char *line) void print_found(const char *line); #endif +static size_t count_colctrl(const char *str) +{ + size_t n; + if (str[1] == '[' + && (n = strspn(str+2, "0123456789;")) >= 0 // always true + && str[n+2] == 'm') + return n+3; + return 0; +} + static void print_ascii(const char *str) { char buf[width+1]; char *p; size_t n; +#if ENABLE_FEATURE_LESS_RAW + size_t esc = 0; +#endif while (*str) { +#if ENABLE_FEATURE_LESS_RAW + if (esc) { + printf("%.*s", (int) esc, str); + str += esc; + esc = 0; + continue; + } +#endif n = strcspn(str, controls); if (n) { if (!str[n]) break; @@ -886,6 +884,13 @@ static void print_ascii(const char *str) /* VT100's CSI, aka Meta-ESC. Who's inventor? */ /* I want to know who committed this sin */ *p++ = '{'; +#if ENABLE_FEATURE_LESS_RAW + else if ((option_mask32 & FLAG_R) + && *str == '\033' + && (esc = count_colctrl(str))) { + break; // flush collected control chars + } +#endif else *p++ = ctrlconv[(unsigned char)*str]; str++; @@ -894,6 +899,7 @@ static void print_ascii(const char *str) print_hilite(buf); } puts(str); + printf(NORMAL); } /* Print the buffer */ -- 2.36.0 From shane.880088.supw at gmail.com Sun May 1 07:03:20 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Sun, 1 May 2022 12:33:20 +0530 Subject: [PATCH v4 2/2] less: replace most uses of NORMAL escape with UNHIGHLIGHT In-Reply-To: <20220501070320.25599-1-shane.880088.supw@gmail.com> References: <20220501070320.25599-1-shane.880088.supw@gmail.com> Message-ID: <20220501070320.25599-3-shane.880088.supw@gmail.com> Emmitting NORMAL resets the entire SGR state of the terminal, which includes colors. We don't want that now, since those sequences can come between a colored line, and this would cut the coloring short. UNHIGHLIGHT is a dedicated code to just flip the HIGHLIGHT (invert) bit to off, and is a better complement anywhere after HIGHLIGHT. NORMAL is still used wherever appropriate, e.g. at the end of lines to reset color state. This cannot handle the case when there is a HIGHLIGHT sequence in the input itself, and any such highlighting can be cut short by less-emmitted highlight sequences. Avoiding that probably requires looking at the codes and keeping state. Testing shows that even greenwood less doesn't bother to do that. --- miscutils/less.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 1e2c4c5cf..2f618ba34 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -155,6 +155,7 @@ #define ESC "\033" /* The escape codes for highlighted and normal text */ #define HIGHLIGHT ESC"[7m" +#define UNHIGHLIGHT ESC"[27m" #define NORMAL ESC"[m" /* The escape code to home and clear to the end of screen */ #define CLEAR ESC"[H"ESC"[J" @@ -312,13 +313,13 @@ static void clear_line(void) static void print_hilite(const char *str) { - printf(HIGHLIGHT"%s"NORMAL, str); + printf(HIGHLIGHT"%s"UNHIGHLIGHT, str); } static void print_statusline(const char *str) { clear_line(); - printf(HIGHLIGHT"%.*s"NORMAL, width - 1, str); + printf(HIGHLIGHT"%.*s"UNHIGHLIGHT, width - 1, str); } /* Exit the program gracefully */ @@ -710,7 +711,7 @@ static void m_status_print(void) percent = (100 * last + num_lines/2) / num_lines; printf(" %i%%", percent <= 100 ? percent : 100); } - printf(NORMAL); + printf(UNHIGHLIGHT); } #endif @@ -740,7 +741,7 @@ static void status_print(void) if (!cur_fline) p = filename; if (num_files > 1) { - printf(HIGHLIGHT"%s (file %i of %i)"NORMAL, + printf(HIGHLIGHT"%s (file %i of %i)"UNHIGHLIGHT, p, current_file, num_files); return; } @@ -807,7 +808,7 @@ static void print_found(const char *line) /* buf[] holds quarantined version of str */ /* Each part of the line that matches has the HIGHLIGHT - * and NORMAL escape sequences placed around it. + * and UNHIGHLIGHT escape sequences placed around it. * NB: we regex against line, but insert text * from quarantined copy (buf[]) */ str = buf; @@ -816,7 +817,7 @@ static void print_found(const char *line) goto start; while (match_status == 0) { - char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, + char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"UNHIGHLIGHT, growline ? growline : "", (int)match_structs.rm_so, str, (int)(match_structs.rm_eo - match_structs.rm_so), @@ -1551,7 +1552,7 @@ static void show_flag_status(void) } clear_line(); - printf(HIGHLIGHT"The status of the flag is: %u"NORMAL, flag_val != 0); + printf(HIGHLIGHT"The status of the flag is: %u"UNHIGHLIGHT, flag_val != 0); } #endif -- 2.36.0 From farmatito at tiscali.it Sun May 1 08:05:24 2022 From: farmatito at tiscali.it (tito) Date: Sun, 1 May 2022 10:05:24 +0200 Subject: [PATCH v9] seedrng: import SeedRNG utility for kernel RNG seed files In-Reply-To: References: <20220419105005.1578598-1-Jason@zx2c4.com> <20220420155545.26ed7950@nbbrfq> Message-ID: <20220501100524.25d6f8f8@devuan> On Fri, 29 Apr 2022 18:16:41 +0200 Denys Vlasenko wrote: > On Wed, Apr 27, 2022 at 6:55 PM Jason A. Donenfeld wrote: > > On Wed, Apr 27, 2022 at 06:15:50PM +0200, Denys Vlasenko wrote: > > > Can we replace all [s]size_t's with ints/unsigneds? We do not expect > > > random pools anywhere near 4 gigabytes... > > > > Probably that's fine. Is the advantage to tossing out consistent types > > worth it though? Does this actually save space? Since [s]size_t is > > usually the word size, won't codegen not really change much? > > For example, on x86-64, 32-bit insns are often shorter. > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox Hi, shouldn't that be "was not" exceeded? - * genuine entropy: make sure disk is not full, quota was't esceeded, etc: + * genuine entropy: make sure disk is not full, quota was't exceeded, etc: Ciao, Tito From rmy at pobox.com Sun May 1 08:45:37 2022 From: rmy at pobox.com (Ron Yorston) Date: Sun, 01 May 2022 09:45:37 +0100 Subject: [PATCH] libbb: make '--help' handling more consistent Message-ID: <626e48b1.tK1V0rIBgUJEJdo0%rmy@pobox.com> Running an applet with '--help' as its only argument is treated as a special case. If additional arguments follow '--help' the behaviour is inconsistent: - applets which call single_argv() print help and do nothing else; - applets which call getopt() report "unrecognized option '--help'" and print help anyway; - expr says "expr: syntax error" and doesn't print help; - printenv silently ignores '--help', prints any other variables and doesn't print help; - realpath says "--help: No such file or directory", prints the path of any other files and doesn't print help. If the first argument is '--help' ignore any other arguments and print help. This is more consistent and most likely what the user wanted. See also commit 6bdfbc4cb (libbb: fix '--help' handling in FEATURE_SH_NOFORK=y). function old new delta show_usage_if_dash_dash_help 75 69 -6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-6) Total: -6 bytes Signed-off-by: Ron Yorston --- libbb/appletlib.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 841b3b873..d56b5b409 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -258,7 +258,6 @@ void lbb_prepare(const char *applet /* Redundant for busybox (run_applet_and_exit covers that case) * but needed for "individual applet" mode */ if (argv[1] - && !argv[2] && strcmp(argv[1], "--help") == 0 && !is_prefixed_with(applet, "busybox") ) { @@ -940,8 +939,8 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv) && applet_no != APPLET_NO_echo # endif ) { - if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) { - /* Make "foo --help" exit with 0: */ + if (argv[1] && strcmp(argv[1], "--help") == 0) { + /* Make "foo --help [...]" exit with 0: */ xfunc_error_retval = 0; bb_show_usage(); } -- 2.35.1 From Jason at zx2c4.com Sun May 1 09:42:35 2022 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Sun, 1 May 2022 11:42:35 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> Message-ID: On Sat, Apr 30, 2022 at 11:48 PM Jason A. Donenfeld wrote: > > On Sat, Apr 30, 2022 at 11:19 PM Denys Vlasenko > wrote: > > Thank you for the explanation. I re-adding the fsync > > and adding a comment. Please take a look at current git. > > Oh god, what have you done? You have butchered seedrng into garbage. I > do not agree with the changes you made. You've removed important error > handling in ways that make certain intended use cases absolutely > impossible. Please revert your changes, which you made mid-discussion > here with no agreement reached. Then you can interact on the mailing > list by sending patches and discussing them. If not -- if you want to > keep tumbling down this monstrous route that you're on -- my > participation here ends entirely, and my advice will be to avoid > busybox because its maintainer is a wreckless cowboy. > > Just from a cursory look: > > - You removed the return value check on fsync(dfd), which means the > check is worthless and introduces a security vulnerability. > - You haven't responded to my messages regarding the importance of > returning proper error codes and appear to have removed them entirely > now? > - Your comment about reads from /dev/urandom depleting the entropy > pool isn't correct. (Plus you used an inconsistent type of comment > with bad indentation. Did you even check your work?) > - You completely ignored the `MAX_SEED_LEN = 256` change from the > patch that this thread is actually about, which means there's no > resolution for that issue. Plus you didn't respond to my email where I > discussed various solutions for that matter. Did you read the patch I > sent? In the 12 hours since I sent this to you, not only have you completely failed to address any of those issues (especially the first and fourth), let alone respond to my email, but you've been busy adding another security regression. This time it takes the form of removing consistent encoding of the hash contents. A cryptographic change without any prior mailing list discussion? You truly are a monster. Please just remove seedrng from busybox. I regret ever coming anywhere near this project. You clearly will not be a responsible steward of security-related code. This is only going to lead to bad things for users down the road. Just get rid of the mess you've made, and we can part ways. Thanks, Jason From rknecht at pm.me Sun May 1 11:47:24 2022 From: rknecht at pm.me (rknecht at pm.me) Date: Sun, 01 May 2022 11:47:24 +0000 Subject: [PATCH v3] Added miscutil/tree.c In-Reply-To: <20220425194033.60db5757@devuan> References: <20220418125344.14632-1-rknecht@pm.me> <20220425194033.60db5757@devuan> Message-ID: Thanks Tito, replacing the global variable adds additional 60 bytes in the bloatcheck. The global variable avoids the stack allocation and zero initialisation. Regards, Roger ------- Original Message ------- On Monday, April 25th, 2022 at 7:40 PM, tito wrote: > > > On Mon, 25 Apr 2022 16:56:50 +0000 > rknecht at pm.me wrote: > > > Hi Tito, > > > > Thanks again for your valuable feedback for V2. I fixed your remarks in V3. > > Could you please have a look at V3? > > > > If you are ok with the changes I would like to ask you for a sign-off so that we can hopefully merge the tree tool soon. > > > Hi, > looks good to me, maybe just the global vars could be removed... > I don't think there is a need for me to sign-off as I have no superpowers, > you need just to wait for the maintainer to say the final word. > > Ciao, > Tito > > > Thanks, > > Roger > > > > ------- Original Message ------- > > On Monday, April 18th, 2022 at 2:54 PM, Roger Knecht rknecht at pm.me wrote: > > > > > Adds the tree program to list directories and files in a tree structure. > > > > > > function old new delta > > > tree_print - 388 +388 > > > .rodata 95677 95766 +89 > > > tree_main - 73 +73 > > > tree_print_prefix - 28 +28 > > > globals - 8 +8 > > > applet_main 3192 3200 +8 > > > applet_names 2747 2752 +5 > > > packed_usage 34414 34396 -18 > > > ------------------------------------------------------------------------------ > > > (add/remove: 5/0 grow/shrink: 3/1 up/down: 599/-18) Total: 581 bytes > > > > > > Signed-off-by: Roger Knecht rknecht at pm.me > > > > > > --- > > > V4 is addressing Tito's remark regarding the symlink and multiple > > > directory handling. > > > > > > Changelog: > > > > > > V3: > > > - Fixed symlink handling > > > - Handle multiple directories in command line arguments > > > - Extended tests for symlink and multiple directories > > > - Reduced size by using libbb functions > > > > > > V2: > > > - Fixed tree help text > > > - Reduced size by 644 bytes > > > > > > AUTHORS | 3 + > > > miscutils/tree.c | 135 +++++++++++++++++++++++++++++++++++++++++++ > > > testsuite/tree.tests | 97 +++++++++++++++++++++++++++++++ > > > 3 files changed, 235 insertions(+) > > > create mode 100644 miscutils/tree.c > > > create mode 100755 testsuite/tree.tests > > > > > > diff --git a/AUTHORS b/AUTHORS > > > index 5c9a634c9..9ec0e2ee4 100644 > > > --- a/AUTHORS > > > +++ b/AUTHORS > > > @@ -181,3 +181,6 @@ Jie Zhang jie.zhang at analog.com > > > > > > Maxime Coste mawww at kakoune.org > > > > > > paste implementation > > > + > > > +Roger Knecht rknecht at pm.me > > > > > > + tree > > > diff --git a/miscutils/tree.c b/miscutils/tree.c > > > new file mode 100644 > > > index 000000000..e053e8483 > > > --- /dev/null > > > +++ b/miscutils/tree.c > > > @@ -0,0 +1,135 @@ > > > +/* vi: set sw=4 ts=4: / > > > +/ > > > + * Copyright (C) 2022 Roger Knecht rknecht at pm.me > > > > > > + * > > > + * Licensed under GPLv2, see file LICENSE in this source tree. > > > + / > > > +//config:config TREE > > > +//config: bool "tree (0.6 kb)" > > > +//config: default n > > > +//config: help > > > +//config: List files and directories in a tree structure. > > > +//config: > > > + > > > +//applet:IF_TREE(APPLET(tree, BB_DIR_USR_BIN, BB_SUID_DROP)) > > > + > > > +//kbuild:lib-$(CONFIG_TREE) += tree.o > > > + > > > +//usage:#define tree_trivial_usage NOUSAGE_STR > > > +//usage:#define tree_full_usage "" > > > + > > > +#include "libbb.h" > > > + > > > +#define PREFIX_CHILD "??? " > > > +#define PREFIX_LAST_CHILD "??? " > > > +#define PREFIX_GRAND_CHILD "? " > > > +#define PREFIX_LAST_GRAND_CHILD " " > > > +#define DEFAULT_PATH "." > > > + > > > +struct directory { > > > + struct directory parent; > > > + const char* prefix; > > > +}; > > > + > > > +static struct globals { > > > + int directories; > > > + int files; > > > +} globals; > > > + > > > +static void tree_print_prefix(struct directory* directory) { > > > + if (directory) { > > > + tree_print_prefix(directory->parent); > > > > > > + fputs_stdout(directory->prefix); > > > > > > + } > > > +} > > > + > > > +static void tree_print(const char* directory_name, struct directory* directory) { > > > + struct dirent **entries, dirent; > > > + struct directory child_directory; > > > + char symlink_path; > > > + int index, size; > > > + bool is_not_last, is_file; > > > + > > > + // read directory entries > > > + size = scandir(directory_name, &entries, NULL, alphasort); > > > + > > > + if (size < 0) { > > > + fputs_stdout(directory_name); > > > + puts(" [error opening dir]"); > > > + return; > > > + } > > > + > > > + // print directory name > > > + puts(directory_name); > > > + > > > + // switch to sub directory > > > + xchdir(directory_name); > > > + > > > + child_directory.parent = directory; > > > + > > > + // print all directory entries > > > + for (index = 0; index < size; index++) { > > > + dirent = entries[index]; > > > + > > > + // filter hidden files and directories > > > + if (strncmp(dirent->d_name, ".", 1) != 0) { > > > > > > + is_file = !is_directory(dirent->d_name, 1); > > > > > > + is_not_last = (index + 1) < size; > > > + symlink_path = xmalloc_readlink(dirent->d_name); > > > > > > + > > > + // print tree line prefix > > > + tree_print_prefix(directory); > > > + > > > + if (is_not_last) { > > > + child_directory.prefix = PREFIX_GRAND_CHILD; > > > + fputs_stdout(PREFIX_CHILD); > > > + } else { > > > + child_directory.prefix = PREFIX_LAST_GRAND_CHILD; > > > + fputs_stdout(PREFIX_LAST_CHILD); > > > + } > > > + > > > + // count directories and files > > > + if (is_file) > > > + globals.files++; > > > + else > > > + globals.directories++; > > > + > > > + if (symlink_path) { > > > + // handle symlink > > > + printf("%s -> %s\n", dirent->d_name, symlink_path); > > > > > > + free(symlink_path); > > > + } else if (is_file) > > > + // handle file > > > + puts(dirent->d_name); > > > > > > + else > > > + // handle directory > > > + tree_print(dirent->d_name, &child_directory); > > > > > > + } > > > + > > > + // release directory entry > > > + free(dirent); > > > + } > > > + > > > + // release directory array > > > + free(entries); > > > + > > > + // switch to parent directory > > > + xchdir(".."); > > > +} > > > + > > > +int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > > > +int tree_main(int argc, char **argv) > > > +{ > > > + if (argc == 1) > > > + // list current working directory > > > + tree_print(DEFAULT_PATH, NULL); > > > + > > > + // list directories given as command line arguments > > > + while (*(++argv)) > > > + tree_print(*argv, NULL); > > > + > > > + // print statistic > > > + printf("\n%d directories, %d files\n", globals.directories, globals.files); > > > + > > > + return EXIT_SUCCESS; > > > +} > > > diff --git a/testsuite/tree.tests b/testsuite/tree.tests > > > new file mode 100755 > > > index 000000000..bad28d46c > > > --- /dev/null > > > +++ b/testsuite/tree.tests > > > @@ -0,0 +1,97 @@ > > > +#!/bin/sh > > > + > > > +# Copyright 2022 by Roger Knecht rknecht at pm.me > > > > > > +# Licensed under GPLv2, see file LICENSE in this source tree. > > > + > > > +. ./testing.sh -v > > > + > > > +# testing "description" "command" "result" "infile" "stdin" > > > + > > > +testing "tree error opening dir" \ > > > + "tree tree.tempdir" \ > > > + "\ > > > +tree.tempdir [error opening dir]\n\ > > > +\n\ > > > +0 directories, 0 files\n" \ > > > + "" "" > > > + > > > +mkdir -p tree2.tempdir > > > +touch tree2.tempdir/testfile > > > + > > > +testing "tree single file" \ > > > + "cd tree2.tempdir && tree" \ > > > + "\ > > > +.\n\ > > > +??? testfile\n\ > > > +\n\ > > > +0 directories, 1 files\n" \ > > > + "" "" > > > + > > > +mkdir -p tree3.tempdir/test1 \ > > > + tree3.tempdir/test2/a \ > > > + tree3.tempdir/test2/b \ > > > + tree3.tempdir/test3/c \ > > > + tree3.tempdir/test3/d > > > + > > > +touch tree3.tempdir/test2/a/testfile1 \ > > > + tree3.tempdir/test2/a/testfile2 \ > > > + tree3.tempdir/test2/a/testfile3 \ > > > + tree3.tempdir/test2/b/testfile4 \ > > > + tree3.tempdir/test3/c/testfile5 \ > > > + tree3.tempdir/test3/d/testfile6 \ > > > + tree3.tempdir/test3/d/.testfile7 > > > + > > > +(cd tree3.tempdir/test2/a && ln -s ../b/testfile4 .) > > > +(cd tree3.tempdir/test2/b && ln -s ../../test3 .) > > > + > > > +testing "tree nested directories and files" \ > > > + "cd tree3.tempdir && tree" \ > > > + "\ > > > +.\n\ > > > +??? test1\n\ > > > +??? test2\n\ > > > +? ??? a\n\ > > > +? ? ??? testfile1\n\ > > > +? ? ??? testfile2\n\ > > > +? ? ??? testfile3\n\ > > > +? ? ??? testfile4 -> ../b/testfile4\n\ > > > > > > +? ??? b\n\ > > > +? ??? test3 -> ../../test3\n\ > > > > > > +? ??? testfile4\n\ > > > +??? test3\n\ > > > + ??? c\n\ > > > + ? ??? testfile5\n\ > > > + ??? d\n\ > > > + ??? testfile6\n\ > > > +\n\ > > > +8 directories, 7 files\n" \ > > > + "" "" > > > + > > > +testing "tree multiple directories" \ > > > + "tree tree2.tempdir tree3.tempdir" \ > > > + "\ > > > +tree2.tempdir\n\ > > > +??? testfile\n\ > > > +tree3.tempdir\n\ > > > +??? test1\n\ > > > +??? test2\n\ > > > +? ??? a\n\ > > > +? ? ??? testfile1\n\ > > > +? ? ??? testfile2\n\ > > > +? ? ??? testfile3\n\ > > > +? ? ??? testfile4 -> ../b/testfile4\n\ > > > > > > +? ??? b\n\ > > > +? ??? test3 -> ../../test3\n\ > > > > > > +? ??? testfile4\n\ > > > +??? test3\n\ > > > + ??? c\n\ > > > + ? ??? testfile5\n\ > > > + ??? d\n\ > > > + ??? testfile6\n\ > > > +\n\ > > > +8 directories, 8 files\n" \ > > > + "" "" > > > + > > > +rm -rf tree.tempdir tree2.tempdir tree3.tempdir > > > + > > > +exit $FAILCOUNT > > > -- > > > 2.17.1 > > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From rknecht at pm.me Sun May 1 12:51:16 2022 From: rknecht at pm.me (Roger Knecht) Date: Sun, 01 May 2022 12:51:16 +0000 Subject: [PATCH v4] tree: new applet Message-ID: <20220501125024.1523-1-rknecht@pm.me> Add new applet which resembles the MS-DOS tree program to list directories and files in a tree structure. function old new delta tree_print - 388 +388 .rodata 95678 95767 +89 tree_main - 73 +73 tree_print_prefix - 28 +28 packed_usage 34417 34429 +12 globals - 8 +8 applet_main 3192 3200 +8 applet_names 2747 2752 +5 ------------------------------------------------------------------------------ (add/remove: 5/0 grow/shrink: 4/0 up/down: 611/0) Total: 611 bytes Signed-off-by: Roger Knecht --- Changelog: V4: - Rephrase commit message - Updated bloatcheck to latest master V3: - Fixed symlink handling - Handle multiple directories in command line arguments - Extended tests for symlink and multiple directories - Reduced size by using libbb functions V2: - Fixed tree help text - Reduced size by 644 bytes AUTHORS | 3 + miscutils/tree.c | 135 +++++++++++++++++++++++++++++++++++++++++++ testsuite/tree.tests | 97 +++++++++++++++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 miscutils/tree.c create mode 100755 testsuite/tree.tests diff --git a/AUTHORS b/AUTHORS index 5c9a634c9..9ec0e2ee4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -181,3 +181,6 @@ Jie Zhang Maxime Coste paste implementation + +Roger Knecht + tree diff --git a/miscutils/tree.c b/miscutils/tree.c new file mode 100644 index 000000000..e053e8483 --- /dev/null +++ b/miscutils/tree.c @@ -0,0 +1,135 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2022 Roger Knecht + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config TREE +//config: bool "tree (0.6 kb)" +//config: default n +//config: help +//config: List files and directories in a tree structure. +//config: + +//applet:IF_TREE(APPLET(tree, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TREE) += tree.o + +//usage:#define tree_trivial_usage NOUSAGE_STR +//usage:#define tree_full_usage "" + +#include "libbb.h" + +#define PREFIX_CHILD "??? " +#define PREFIX_LAST_CHILD "??? " +#define PREFIX_GRAND_CHILD "??? " +#define PREFIX_LAST_GRAND_CHILD " " +#define DEFAULT_PATH "." + +struct directory { + struct directory* parent; + const char* prefix; +}; + +static struct globals { + int directories; + int files; +} globals; + +static void tree_print_prefix(struct directory* directory) { + if (directory) { + tree_print_prefix(directory->parent); + fputs_stdout(directory->prefix); + } +} + +static void tree_print(const char* directory_name, struct directory* directory) { + struct dirent **entries, *dirent; + struct directory child_directory; + char* symlink_path; + int index, size; + bool is_not_last, is_file; + + // read directory entries + size = scandir(directory_name, &entries, NULL, alphasort); + + if (size < 0) { + fputs_stdout(directory_name); + puts(" [error opening dir]"); + return; + } + + // print directory name + puts(directory_name); + + // switch to sub directory + xchdir(directory_name); + + child_directory.parent = directory; + + // print all directory entries + for (index = 0; index < size; index++) { + dirent = entries[index]; + + // filter hidden files and directories + if (strncmp(dirent->d_name, ".", 1) != 0) { + is_file = !is_directory(dirent->d_name, 1); + is_not_last = (index + 1) < size; + symlink_path = xmalloc_readlink(dirent->d_name); + + // print tree line prefix + tree_print_prefix(directory); + + if (is_not_last) { + child_directory.prefix = PREFIX_GRAND_CHILD; + fputs_stdout(PREFIX_CHILD); + } else { + child_directory.prefix = PREFIX_LAST_GRAND_CHILD; + fputs_stdout(PREFIX_LAST_CHILD); + } + + // count directories and files + if (is_file) + globals.files++; + else + globals.directories++; + + if (symlink_path) { + // handle symlink + printf("%s -> %s\n", dirent->d_name, symlink_path); + free(symlink_path); + } else if (is_file) + // handle file + puts(dirent->d_name); + else + // handle directory + tree_print(dirent->d_name, &child_directory); + } + + // release directory entry + free(dirent); + } + + // release directory array + free(entries); + + // switch to parent directory + xchdir(".."); +} + +int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int tree_main(int argc, char **argv) +{ + if (argc == 1) + // list current working directory + tree_print(DEFAULT_PATH, NULL); + + // list directories given as command line arguments + while (*(++argv)) + tree_print(*argv, NULL); + + // print statistic + printf("\n%d directories, %d files\n", globals.directories, globals.files); + + return EXIT_SUCCESS; +} diff --git a/testsuite/tree.tests b/testsuite/tree.tests new file mode 100755 index 000000000..bad28d46c --- /dev/null +++ b/testsuite/tree.tests @@ -0,0 +1,97 @@ +#!/bin/sh + +# Copyright 2022 by Roger Knecht +# Licensed under GPLv2, see file LICENSE in this source tree. + +. ./testing.sh -v + +# testing "description" "command" "result" "infile" "stdin" + +testing "tree error opening dir" \ + "tree tree.tempdir" \ + "\ +tree.tempdir [error opening dir]\n\ +\n\ +0 directories, 0 files\n" \ + "" "" + +mkdir -p tree2.tempdir +touch tree2.tempdir/testfile + +testing "tree single file" \ + "cd tree2.tempdir && tree" \ + "\ +.\n\ +??? testfile\n\ +\n\ +0 directories, 1 files\n" \ + "" "" + +mkdir -p tree3.tempdir/test1 \ + tree3.tempdir/test2/a \ + tree3.tempdir/test2/b \ + tree3.tempdir/test3/c \ + tree3.tempdir/test3/d + +touch tree3.tempdir/test2/a/testfile1 \ + tree3.tempdir/test2/a/testfile2 \ + tree3.tempdir/test2/a/testfile3 \ + tree3.tempdir/test2/b/testfile4 \ + tree3.tempdir/test3/c/testfile5 \ + tree3.tempdir/test3/d/testfile6 \ + tree3.tempdir/test3/d/.testfile7 + +(cd tree3.tempdir/test2/a && ln -s ../b/testfile4 .) +(cd tree3.tempdir/test2/b && ln -s ../../test3 .) + +testing "tree nested directories and files" \ + "cd tree3.tempdir && tree" \ + "\ +.\n\ +??? test1\n\ +??? test2\n\ +??? ??? a\n\ +??? ??? ??? testfile1\n\ +??? ??? ??? testfile2\n\ +??? ??? ??? testfile3\n\ +??? ??? ??? testfile4 -> ../b/testfile4\n\ +??? ??? b\n\ +??? ??? test3 -> ../../test3\n\ +??? ??? testfile4\n\ +??? test3\n\ + ??? c\n\ + ??? ??? testfile5\n\ + ??? d\n\ + ??? testfile6\n\ +\n\ +8 directories, 7 files\n" \ + "" "" + +testing "tree multiple directories" \ + "tree tree2.tempdir tree3.tempdir" \ + "\ +tree2.tempdir\n\ +??? testfile\n\ +tree3.tempdir\n\ +??? test1\n\ +??? test2\n\ +??? ??? a\n\ +??? ??? ??? testfile1\n\ +??? ??? ??? testfile2\n\ +??? ??? ??? testfile3\n\ +??? ??? ??? testfile4 -> ../b/testfile4\n\ +??? ??? b\n\ +??? ??? test3 -> ../../test3\n\ +??? ??? testfile4\n\ +??? test3\n\ + ??? c\n\ + ??? ??? testfile5\n\ + ??? d\n\ + ??? testfile6\n\ +\n\ +8 directories, 8 files\n" \ + "" "" + +rm -rf tree.tempdir tree2.tempdir tree3.tempdir + +exit $FAILCOUNT -- 2.17.1 From David.Laight at ACULAB.COM Sun May 1 13:07:16 2022 From: David.Laight at ACULAB.COM (David Laight) Date: Sun, 1 May 2022 13:07:16 +0000 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> Message-ID: <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> From: Jason A. Donenfeld > Sent: 30 April 2022 14:48 > > Hi Denys, > > On Sat, Apr 30, 2022 at 3:12 PM Denys Vlasenko wrote: > > > + /* The fsync() here is necessary for safety here, so that power being pulled > > > + * at the wrong moment doesn't result in the seed being used twice by accident. */ > > > if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { > > > bb_perror_msg("can't%s seed", " remove"); > > > return -1; > > > > I don't understand the scenario mentioned here. > > Let's say we removed fsync() above. > > We read /var/lib/seedrng/seed.credit contents. > > We unlink() it, but this change does not go to disk yet. > > We seed the RNG. > > We recreate /var/lib/seedrng/seed.credit with new contents, > > but this change does not go to disk yet too. > > We exit. > > Only now, after we are done, RNG can be used for e.g. key generation. > > > > And only if the power gets pulled AFTER this key generation, > > and the write cached data is still not on the disk > > (for example, if you use ext4 or xfs, this won't happen since > > they synchronously wait for both O_TRUNC truncations > > and renames), the previous /var/lib/seedrng/seed.credit might > > still exist and might get reused on the next boot, > > and a new key can be generated from the same seed. > > > > Do you often pull power cords from machines you use for > > somewhat important crypto operations, such as generating keys? > > What are the chances that you also do it on a machine without RTC > > clock (which would otherwise supply randomness > > from the current time)? > > > > IOW: To me, this does not seem to be a realistic threat. > > It's a theoretical one: you can concoct a scenario where it might happen, > > but triggering it for real, even on purpose, would be difficult. > > Again, stop charging steadfastly toward creating vulnerabilities > because you don't understand things. The scenario is: > > - RNG is seeded and credited using file A. > - File A is unlinked but not fsync()d. > - TLS connection does something and a nonce is generated. > - System loses power and reboots. > - RNG is seeded and credited using same file A. > - TLS connection does something and the same nonce is generated, > resulting in catastrophic cryptographic failure. > > This is a big deal. Crediting seeds is not to be taken lightly. > Crediting file-based seeds is _only_ safe when they're never used > twice. Using the same file twice is better than having nothing at all. At least different systems use different values. Unless you have a remote 'dos' attack that can crash the system at exactly the right point in the boot sequence this is an entirely 'academic' error. What is much more likely is that the file where the entropy is saved is just a memory overlay on top of a read-only image. That is much more likely for an embedded system than any of the 'failure' cases you've considered. I also wonder how sane it is to do 'new_key = f(old_key)'. That doesn't seem significantly better than using the same key. For a really embedded system the only persistent storage could easily be a small serial EEPROM with a very limited number of write cycles. This requires special code to read/write and care to avoid hitting the write cycle count on a small number of memory cells. No amount of faffing about with filesystem accesses will help here at all. There is also the case (that on my systems at least) udev initialisation reads from /dev/[u]random well before the S20 script loads any saved entropy. I've not tried to find out what the value is used for. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) From vda.linux at googlemail.com Sun May 1 15:06:58 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 1 May 2022 17:06:58 +0200 Subject: [PATCH v9] seedrng: import SeedRNG utility for kernel RNG seed files In-Reply-To: <20220501100524.25d6f8f8@devuan> References: <20220419105005.1578598-1-Jason@zx2c4.com> <20220420155545.26ed7950@nbbrfq> <20220501100524.25d6f8f8@devuan> Message-ID: On Sun, May 1, 2022 at 10:05 AM tito wrote: > > On Fri, 29 Apr 2022 18:16:41 +0200 > Denys Vlasenko wrote: > > > On Wed, Apr 27, 2022 at 6:55 PM Jason A. Donenfeld wrote: > > > On Wed, Apr 27, 2022 at 06:15:50PM +0200, Denys Vlasenko wrote: > > > > Can we replace all [s]size_t's with ints/unsigneds? We do not expect > > > > random pools anywhere near 4 gigabytes... > > > > > > Probably that's fine. Is the advantage to tossing out consistent types > > > worth it though? Does this actually save space? Since [s]size_t is > > > usually the word size, won't codegen not really change much? > > > > For example, on x86-64, 32-bit insns are often shorter. > > _______________________________________________ > > busybox mailing list > > busybox at busybox.net > > http://lists.busybox.net/mailman/listinfo/busybox > > Hi, > shouldn't that be "was not" exceeded? > > - * genuine entropy: make sure disk is not full, quota was't esceeded, etc: > + * genuine entropy: make sure disk is not full, quota was't exceeded, etc: > Yes, a typo. Fixing... From logout at free.fr Sun May 1 16:35:00 2022 From: logout at free.fr (Emmanuel Deloget) Date: Sun, 1 May 2022 18:35:00 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: I'm not sure I have any right to jump into the conversation but here I am. Le dim. 1 mai 2022 ? 15:07, David Laight a ?crit : > > From: Jason A. Donenfeld > > Sent: 30 April 2022 14:48 > > > > Hi Denys, > > > > On Sat, Apr 30, 2022 at 3:12 PM Denys Vlasenko wrote: > > > > + /* The fsync() here is necessary for safety here, so that power being pulled > > > > + * at the wrong moment doesn't result in the seed being used twice by accident. */ > > > > if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { > > > > bb_perror_msg("can't%s seed", " remove"); > > > > return -1; > > > > > > I don't understand the scenario mentioned here. > > > Let's say we removed fsync() above. > > > We read /var/lib/seedrng/seed.credit contents. > > > We unlink() it, but this change does not go to disk yet. > > > We seed the RNG. > > > We recreate /var/lib/seedrng/seed.credit with new contents, > > > but this change does not go to disk yet too. > > > We exit. > > > Only now, after we are done, RNG can be used for e.g. key generation. > > > > > > And only if the power gets pulled AFTER this key generation, > > > and the write cached data is still not on the disk > > > (for example, if you use ext4 or xfs, this won't happen since > > > they synchronously wait for both O_TRUNC truncations > > > and renames), the previous /var/lib/seedrng/seed.credit might > > > still exist and might get reused on the next boot, > > > and a new key can be generated from the same seed. > > > > > > Do you often pull power cords from machines you use for > > > somewhat important crypto operations, such as generating keys? > > > What are the chances that you also do it on a machine without RTC > > > clock (which would otherwise supply randomness > > > from the current time)? > > > > > > IOW: To me, this does not seem to be a realistic threat. > > > It's a theoretical one: you can concoct a scenario where it might happen, > > > but triggering it for real, even on purpose, would be difficult. > > > > Again, stop charging steadfastly toward creating vulnerabilities > > because you don't understand things. The scenario is: > > > > - RNG is seeded and credited using file A. > > - File A is unlinked but not fsync()d. > > - TLS connection does something and a nonce is generated. > > - System loses power and reboots. > > - RNG is seeded and credited using same file A. > > - TLS connection does something and the same nonce is generated, > > resulting in catastrophic cryptographic failure. > > > > This is a big deal. Crediting seeds is not to be taken lightly. > > Crediting file-based seeds is _only_ safe when they're never used > > twice. > > Using the same file twice is better than having nothing at all. I beg to differ, and especially on some embedded systems where the RNG might be quite controllable by an attacker from the outside (mostly because it lacks a lot of entropy crediting inputs, which is exactly the reason why we need seedrng in the first place). This may lead to catastrophic cryptography failures down the road. > At least different systems use different values. > Unless you have a remote 'dos' attack that can crash the system > at exactly the right point in the boot sequence this is an > entirely 'academic' error. Having such a distinction is less helpful than one might think. First of all, even an 'academic' vulnerability is a vulnerability. It means that basing any embedded product on busybox's seedrng precludes said product from being acceptable for any kind of security certification program. It doesn't matter whether the vuln is exploitable or not at the time of certification - the reasoning is that it's a known vuln, and it _might_ be exploitable in the future. Official bodies might be parano?d here, but they have the last word. > What is much more likely is that the file where the entropy > is saved is just a memory overlay on top of a read-only image. > > That is much more likely for an embedded system than any of > the 'failure' cases you've considered. Given the right tools and how to use them, we developers have a duty to use them correctly. I understand that it's not always the case, but this is our responsibility - not the responsibility of the tool maker. If I design a product without (at least) one way to permanently store a seed file then I shall provide another way to seed the RNG. Fortunately, a lot of recent SoC have a hardware RNG which will participate to /dev/random early on. > I also wonder how sane it is to do 'new_key = f(old_key)'. > That doesn't seem significantly better than using the same key. f() being a hash function with a salt + a (maybe not enough) random value, I would think that new_key is going to be widely different than old_key and more or less unpredictable, which is what we want for a seed. > For a really embedded system the only persistent storage > could easily be a small serial EEPROM with a very limited > number of write cycles. > This requires special code to read/write and care to avoid > hitting the write cycle count on a small number of memory cells. > No amount of faffing about with filesystem accesses will > help here at all. As you noted by yourself, it requires special code to read/write, so unless this use-case is fully supported in busybox (with special implementation for open/read/write), I don't see why it should have an impact on the security of _all_ other devices. > There is also the case (that on my systems at least) udev > initialisation reads from /dev/[u]random well before the S20 > script loads any saved entropy. > I've not tried to find out what the value is used for. I find at least one occurrence where the goal is to create a random delay in udev-watch.c [1]. Anyway, and unless some weird security-oriented process decides to read some random bytes without checking whether the random pool in in a correct state (in which case I'm not sure you shall trust this security-oriented process in the first place) the goal of seedrng is not to protect all reads from /dev/urandom, but to make sure that we have enough entropy to do the Real Work. > > David > > - > Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK > Registration No: 1397386 (Wales) It seems to me that one might want to add a CONFIG_FAVOR_SIZE_OVER_SECURITY configuration flag. I wish to say that I'm not sure it's a good idea. Having a small busybox is a good thing, but having a too small busybox that breaks products because of bad security choices is not. Best regards, -- Emmanuel Deloget [1] https://github.com/systemd/systemd/blob/d9338387d94ad611233cf0753801eefccfda432a/src/udev/udev-watch.c#L102 From farmatito at tiscali.it Sun May 1 17:11:52 2022 From: farmatito at tiscali.it (tito) Date: Sun, 1 May 2022 19:11:52 +0200 Subject: [PATCH v4] tree: new applet In-Reply-To: <20220501125024.1523-1-rknecht@pm.me> References: <20220501125024.1523-1-rknecht@pm.me> Message-ID: <20220501191152.18d3422a@devuan> On Sun, 01 May 2022 12:51:16 +0000 Roger Knecht wrote: > Add new applet which resembles the MS-DOS tree program to list directories and files in a tree structure. > > function old new delta > tree_print - 388 +388 > .rodata 95678 95767 +89 > tree_main - 73 +73 > tree_print_prefix - 28 +28 > packed_usage 34417 34429 +12 > globals - 8 +8 > applet_main 3192 3200 +8 > applet_names 2747 2752 +5 > ------------------------------------------------------------------------------ > (add/remove: 5/0 grow/shrink: 4/0 up/down: 611/0) Total: 611 bytes > > Signed-off-by: Roger Knecht > --- > Changelog: > > V4: > - Rephrase commit message > - Updated bloatcheck to latest master > > V3: > - Fixed symlink handling > - Handle multiple directories in command line arguments > - Extended tests for symlink and multiple directories > - Reduced size by using libbb functions > > V2: > - Fixed tree help text > - Reduced size by 644 bytes > > AUTHORS | 3 + > miscutils/tree.c | 135 +++++++++++++++++++++++++++++++++++++++++++ > testsuite/tree.tests | 97 +++++++++++++++++++++++++++++++ > 3 files changed, 235 insertions(+) > create mode 100644 miscutils/tree.c > create mode 100755 testsuite/tree.tests > > diff --git a/AUTHORS b/AUTHORS > index 5c9a634c9..9ec0e2ee4 100644 > --- a/AUTHORS > +++ b/AUTHORS > @@ -181,3 +181,6 @@ Jie Zhang > > Maxime Coste > paste implementation > + > +Roger Knecht > + tree > diff --git a/miscutils/tree.c b/miscutils/tree.c > new file mode 100644 > index 000000000..e053e8483 > --- /dev/null > +++ b/miscutils/tree.c > @@ -0,0 +1,135 @@ > +/* vi: set sw=4 ts=4: */ > +/* > + * Copyright (C) 2022 Roger Knecht > + * > + * Licensed under GPLv2, see file LICENSE in this source tree. > + */ > +//config:config TREE > +//config: bool "tree (0.6 kb)" > +//config: default n > +//config: help > +//config: List files and directories in a tree structure. > +//config: > + > +//applet:IF_TREE(APPLET(tree, BB_DIR_USR_BIN, BB_SUID_DROP)) > + > +//kbuild:lib-$(CONFIG_TREE) += tree.o > + > +//usage:#define tree_trivial_usage NOUSAGE_STR > +//usage:#define tree_full_usage "" > + > +#include "libbb.h" > + > +#define PREFIX_CHILD "??? " > +#define PREFIX_LAST_CHILD "??? " > +#define PREFIX_GRAND_CHILD "??? " > +#define PREFIX_LAST_GRAND_CHILD " " > +#define DEFAULT_PATH "." > + > +struct directory { > + struct directory* parent; > + const char* prefix; > +}; > + > +static struct globals { > + int directories; > + int files; > +} globals; > + > +static void tree_print_prefix(struct directory* directory) { > + if (directory) { > + tree_print_prefix(directory->parent); > + fputs_stdout(directory->prefix); > + } > +} > + > +static void tree_print(const char* directory_name, struct directory* directory) { > + struct dirent **entries, *dirent; > + struct directory child_directory; > + char* symlink_path; > + int index, size; //> + bool is_not_last, is_file; > + > + // read directory entries > + size = scandir(directory_name, &entries, NULL, alphasort); > + > + if (size < 0) { > + fputs_stdout(directory_name); > + puts(" [error opening dir]"); > + return; > + } > + > + // print directory name > + puts(directory_name); > + > + // switch to sub directory > + xchdir(directory_name); > + > + child_directory.parent = directory; > + > + // print all directory entries > + for (index = 0; index < size; index++) { > + dirent = entries[index]; > + > + // filter hidden files and directories Hi, if (dirent->d_name[0] != '.') { > + if (strncmp(dirent->d_name, ".", 1) != 0) { twisted logic? > + is_file = !is_directory(dirent->d_name, 1); is_not_last is used only once > + is_not_last = (index + 1) < size; > + symlink_path = xmalloc_readlink(dirent->d_name); > + > + // print tree line prefix > + tree_print_prefix(directory); > + if ((index + 1) < size) { > + if (is_not_last) { > + child_directory.prefix = PREFIX_GRAND_CHILD; > + fputs_stdout(PREFIX_CHILD); > + } else { > + child_directory.prefix = PREFIX_LAST_GRAND_CHILD; > + fputs_stdout(PREFIX_LAST_CHILD); > + } > + Less lines maybe less size (untested) if (is_directory(dirent->d_name, 1)) { globals.directories++; tree_print(dirent->d_name, &child_directory); } else { globals.files++; printf((symlink) ? "%s -> %s\n" : "%s\n", dirent->d_name, symlink_path); } free(symlink_path); Ciao, Tito > + // count directories and files > + if (is_file) > + globals.files++; > + else > + globals.directories++; > + > + if (symlink_path) { > + // handle symlink > + printf("%s -> %s\n", dirent->d_name, symlink_path); > + free(symlink_path); > + } else if (is_file) > + // handle file > + puts(dirent->d_name); > + else > + // handle directory > + tree_print(dirent->d_name, &child_directory); > + } > + > + // release directory entry > + free(dirent); > + } > + > + // release directory array > + free(entries); > + > + // switch to parent directory > + xchdir(".."); > +} > + > +int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > +int tree_main(int argc, char **argv) > +{ > + if (argc == 1) > + // list current working directory > + tree_print(DEFAULT_PATH, NULL); > + > + // list directories given as command line arguments > + while (*(++argv)) > + tree_print(*argv, NULL); > + > + // print statistic > + printf("\n%d directories, %d files\n", globals.directories, globals.files); > + > + return EXIT_SUCCESS; > +} > diff --git a/testsuite/tree.tests b/testsuite/tree.tests > new file mode 100755 > index 000000000..bad28d46c > --- /dev/null > +++ b/testsuite/tree.tests > @@ -0,0 +1,97 @@ > +#!/bin/sh > + > +# Copyright 2022 by Roger Knecht > +# Licensed under GPLv2, see file LICENSE in this source tree. > + > +. ./testing.sh -v > + > +# testing "description" "command" "result" "infile" "stdin" > + > +testing "tree error opening dir" \ > + "tree tree.tempdir" \ > + "\ > +tree.tempdir [error opening dir]\n\ > +\n\ > +0 directories, 0 files\n" \ > + "" "" > + > +mkdir -p tree2.tempdir > +touch tree2.tempdir/testfile > + > +testing "tree single file" \ > + "cd tree2.tempdir && tree" \ > + "\ > +.\n\ > +??? testfile\n\ > +\n\ > +0 directories, 1 files\n" \ > + "" "" > + > +mkdir -p tree3.tempdir/test1 \ > + tree3.tempdir/test2/a \ > + tree3.tempdir/test2/b \ > + tree3.tempdir/test3/c \ > + tree3.tempdir/test3/d > + > +touch tree3.tempdir/test2/a/testfile1 \ > + tree3.tempdir/test2/a/testfile2 \ > + tree3.tempdir/test2/a/testfile3 \ > + tree3.tempdir/test2/b/testfile4 \ > + tree3.tempdir/test3/c/testfile5 \ > + tree3.tempdir/test3/d/testfile6 \ > + tree3.tempdir/test3/d/.testfile7 > + > +(cd tree3.tempdir/test2/a && ln -s ../b/testfile4 .) > +(cd tree3.tempdir/test2/b && ln -s ../../test3 .) > + > +testing "tree nested directories and files" \ > + "cd tree3.tempdir && tree" \ > + "\ > +.\n\ > +??? test1\n\ > +??? test2\n\ > +??? ??? a\n\ > +??? ??? ??? testfile1\n\ > +??? ??? ??? testfile2\n\ > +??? ??? ??? testfile3\n\ > +??? ??? ??? testfile4 -> ../b/testfile4\n\ > +??? ??? b\n\ > +??? ??? test3 -> ../../test3\n\ > +??? ??? testfile4\n\ > +??? test3\n\ > + ??? c\n\ > + ??? ??? testfile5\n\ > + ??? d\n\ > + ??? testfile6\n\ > +\n\ > +8 directories, 7 files\n" \ > + "" "" > + > +testing "tree multiple directories" \ > + "tree tree2.tempdir tree3.tempdir" \ > + "\ > +tree2.tempdir\n\ > +??? testfile\n\ > +tree3.tempdir\n\ > +??? test1\n\ > +??? test2\n\ > +??? ??? a\n\ > +??? ??? ??? testfile1\n\ > +??? ??? ??? testfile2\n\ > +??? ??? ??? testfile3\n\ > +??? ??? ??? testfile4 -> ../b/testfile4\n\ > +??? ??? b\n\ > +??? ??? test3 -> ../../test3\n\ > +??? ??? testfile4\n\ > +??? test3\n\ > + ??? c\n\ > + ??? ??? testfile5\n\ > + ??? d\n\ > + ??? testfile6\n\ > +\n\ > +8 directories, 8 files\n" \ > + "" "" > + > +rm -rf tree.tempdir tree2.tempdir tree3.tempdir > + > +exit $FAILCOUNT > -- > 2.17.1 > > From explorer09 at gmail.com Sun May 1 17:40:39 2022 From: explorer09 at gmail.com (Kang-Che Sung) Date: Mon, 2 May 2022 01:40:39 +0800 Subject: [PATCH v4] tree: new applet In-Reply-To: <20220501125024.1523-1-rknecht@pm.me> References: <20220501125024.1523-1-rknecht@pm.me> Message-ID: Hi Roger, May I suggest you add an option to draw the tree lines using ASCII characters only, and make the Unicode support optional at build time? I just feel uncomfortable when I see source code containing embedded UTF-8 characters and the strings have no ASCII alternative. The DOS tree command has the "/a" option. You know what I mean. Thank you. On Sunday, May 1, 2022, Roger Knecht wrote: > Add new applet which resembles the MS-DOS tree program to list directories and files in a tree structure. > > function old new delta > tree_print - 388 +388 > .rodata 95678 95767 +89 > tree_main - 73 +73 > tree_print_prefix - 28 +28 > packed_usage 34417 34429 +12 > globals - 8 +8 > applet_main 3192 3200 +8 > applet_names 2747 2752 +5 > ------------------------------------------------------------------------------ > (add/remove: 5/0 grow/shrink: 4/0 up/down: 611/0) Total: 611 bytes > > Signed-off-by: Roger Knecht > --- > Changelog: > > V4: > - Rephrase commit message > - Updated bloatcheck to latest master > > V3: > - Fixed symlink handling > - Handle multiple directories in command line arguments > - Extended tests for symlink and multiple directories > - Reduced size by using libbb functions > > V2: > - Fixed tree help text > - Reduced size by 644 bytes > -------------- next part -------------- An HTML attachment was scrubbed... URL: From farmatito at tiscali.it Sun May 1 17:59:45 2022 From: farmatito at tiscali.it (tito) Date: Sun, 1 May 2022 19:59:45 +0200 Subject: [PATCH v4] tree: new applet In-Reply-To: References: <20220501125024.1523-1-rknecht@pm.me> Message-ID: <20220501195945.1d888c09@devuan> On Mon, 2 May 2022 01:40:39 +0800 Kang-Che Sung wrote: > Hi Roger, > > May I suggest you add an option to draw the tree lines using ASCII > characters only, and make the Unicode support optional at build time? > > I just feel uncomfortable when I see source code containing embedded UTF-8 > characters and the strings have no ASCII alternative. > > The DOS tree command has the "/a" option. You know what I mean. > > Thank you. Hi, something like ?: #ifdef CONFIG_TREE_ASCII_ONLY #define PREFIX_CHILD "|- " #define PREFIX_LAST_CHILD "|_ " #define PREFIX_GRAND_CHILD "| " #define PREFIX_LAST_GRAND_CHILD " " #else #define PREFIX_CHILD "??? " #define PREFIX_LAST_CHILD "??? " #define PREFIX_GRAND_CHILD "??? " #define PREFIX_LAST_GRAND_CHILD " " #endif Ciao, Tito > On Sunday, May 1, 2022, Roger Knecht wrote: > > Add new applet which resembles the MS-DOS tree program to list > directories and files in a tree structure. > > > > function old new delta > > tree_print - 388 +388 > > .rodata 95678 95767 +89 > > tree_main - 73 +73 > > tree_print_prefix - 28 +28 > > packed_usage 34417 34429 +12 > > globals - 8 +8 > > applet_main 3192 3200 +8 > > applet_names 2747 2752 +5 > > > ------------------------------------------------------------------------------ > > (add/remove: 5/0 grow/shrink: 4/0 up/down: 611/0) Total: 611 > bytes > > > > Signed-off-by: Roger Knecht > > --- > > Changelog: > > > > V4: > > - Rephrase commit message > > - Updated bloatcheck to latest master > > > > V3: > > - Fixed symlink handling > > - Handle multiple directories in command line arguments > > - Extended tests for symlink and multiple directories > > - Reduced size by using libbb functions > > > > V2: > > - Fixed tree help text > > - Reduced size by 644 bytes > > From deweloper at wp.pl Sun May 1 21:16:53 2022 From: deweloper at wp.pl (Aleksander Mazur) Date: Sun, 1 May 2022 23:16:53 +0200 Subject: Let users access their home directories via ftp Message-ID: <40e6298edd4b4c3b83b7a1bbe02595da@grupawp.pl> Hi, AFAIU ftpd just shares current working directory (unless given a path), no matter who logs in. I find it useful to let ftpd chroot or cd to the home directory of a (non-root) user who logs in. Please consider attached patch. I hope it won't ruin anybody's setup. -- Aleksander Mazur -------------- next part -------------- A non-text attachment was scrubbed... Name: 006-ftpd-chroot_or_cd_to_home_dir.patch Type: text/x-patch Size: 460 bytes Desc: not available URL: From vda.linux at googlemail.com Mon May 2 01:31:09 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 May 2022 03:31:09 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: On Sun, May 1, 2022 at 6:35 PM Emmanuel Deloget wrote: > > > - RNG is seeded and credited using file A. > > > - File A is unlinked but not fsync()d. > > > - TLS connection does something and a nonce is generated. > > > - System loses power and reboots. > > > - RNG is seeded and credited using same file A. > > > - TLS connection does something and the same nonce is generated, > > > resulting in catastrophic cryptographic failure. > > > > > > This is a big deal. Crediting seeds is not to be taken lightly. > > > Crediting file-based seeds is _only_ safe when they're never used > > > twice. > > > > Using the same file twice is better than having nothing at all. > > I beg to differ, and especially on some embedded systems where the RNG > might be quite controllable by an attacker from the outside (mostly because > it lacks a lot of entropy crediting inputs, which is exactly the reason why we > need seedrng in the first place). This may lead to catastrophic cryptography > failures down the road. Did you personally encounter such a situation? I'm not implying it's not really happening, I'm interested to hear from people who met this situation in real world. From jake.burkholder2 at gmail.com Mon May 2 04:01:36 2022 From: jake.burkholder2 at gmail.com (Jacob Burkholder) Date: Sun, 1 May 2022 21:01:36 -0700 Subject: Let users access their home directories via ftp In-Reply-To: <40e6298edd4b4c3b83b7a1bbe02595da@grupawp.pl> References: <40e6298edd4b4c3b83b7a1bbe02595da@grupawp.pl> Message-ID: I use a similar patch, I added option -h to enable the functionality. On Sun, May 1, 2022 at 2:17 PM Aleksander Mazur wrote: > > Hi, > > AFAIU ftpd just shares current working directory (unless given a path), no matter who logs in. > I find it useful to let ftpd chroot or cd to the home directory of a (non-root) user who logs in. > Please consider attached patch. I hope it won't ruin anybody's setup. > > -- > Aleksander Mazur > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox -------------- next part -------------- A non-text attachment was scrubbed... Name: 0-networking-ftpd.c Type: text/x-csrc Size: 1538 bytes Desc: not available URL: From ada at thorsis.com Mon May 2 05:14:33 2022 From: ada at thorsis.com (Alexander Dahl) Date: Mon, 2 May 2022 07:14:33 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> Message-ID: Hello Denys, Am Sat, Apr 30, 2022 at 03:12:11PM +0200 schrieb Denys Vlasenko: > Do you often pull power cords from machines you use for > somewhat important crypto operations, such as generating keys? > What are the chances that you also do it on a machine without RTC > clock (which would otherwise supply randomness > from the current time)? FWIW ? busybox is often used in embedded systems, and from my personal 10y+ experience in that field, I can safely assure you: customers and users pull power chords all the time and at absolutely unpredictable times. Don't know if that's a real threat from a security point of view, but only looking at what developers do is not giving you the full picture. Greets Alex From ada at thorsis.com Mon May 2 05:15:37 2022 From: ada at thorsis.com (Alexander Dahl) Date: Mon, 2 May 2022 07:15:37 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: <20220429170447.2558932-1-Jason@zx2c4.com> References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> Message-ID: Hello Jason, Am Fri, Apr 29, 2022 at 07:04:47PM +0200 schrieb Jason A. Donenfeld: > Rather than having getrandom() be called in a loop that handles EINTR -- > which would require more code bloat -- we just limit the maximum seed > size to 256 bytes, which the kernel guarantees won't be interrupted. > Additionally document the flock() and fsync() usage so that somebody > doesn't remove it. Apparently busybox developers like to remove things > they don't understand with no regards to security implications, so Denys > suggested I leave some comments here. > > Cc: Denys Vlasenko > Cc: Bernhard Reutner-Fischer > Signed-off-by: Jason A. Donenfeld > --- > util-linux/seedrng.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/util-linux/seedrng.c b/util-linux/seedrng.c > index c42274759..5ee6197e3 100644 > --- a/util-linux/seedrng.c > +++ b/util-linux/seedrng.c > @@ -56,7 +56,7 @@ > > enum { > MIN_SEED_LEN = SHA256_OUTSIZE, > - MAX_SEED_LEN = 512 > + MAX_SEED_LEN = 256 /* Maximum size of getrandom() call without EINTR. */ > }; > > static size_t determine_optimal_seed_len(void) > @@ -142,6 +142,8 @@ static int seed_from_file_if_exists(const char *filename, int dfd, bool credit, > bb_perror_msg("can't%s seed", " read"); > return -1; > } > + /* The fsync() here is necessary for safety here, so that power being pulled > + * at the wrong moment doesn't result in the seed being used twice by accident. */ nit: "here" is used twice in the same sentence. Greets Alex > if ((unlink(filename) < 0 || fsync(dfd) < 0) && seed_len) { > bb_perror_msg("can't%s seed", " remove"); > return -1; > @@ -190,6 +192,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) > if (mkdir(seed_dir, 0700) < 0 && errno != EEXIST) > bb_perror_msg_and_die("can't %s seed directory", "create"); > dfd = open(seed_dir, O_DIRECTORY | O_RDONLY); > + /* The flock() here is absolutely necessary, as the consistency of this > + * program breaks down with concurrent uses. */ > if (dfd < 0 || flock(dfd, LOCK_EX) < 0) > bb_perror_msg_and_die("can't %s seed directory", "lock"); > xfchdir(dfd); > @@ -222,6 +226,8 @@ int seedrng_main(int argc UNUSED_PARAM, char *argv[]) > > printf("Saving %u bits of %screditable seed for next boot\n", (unsigned)new_seed_len * 8, new_seed_creditable ? "" : "non-"); > fd = open(NON_CREDITABLE_SEED_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0400); > + /* The fsync() here is necessary to ensure the data is written to disk before > + * we attempt to make it creditable. */ > if (fd < 0 || full_write(fd, new_seed, new_seed_len) != (ssize_t)new_seed_len || fsync(fd) < 0) { > bb_perror_msg("can't%s seed", " write"); > return program_ret | (1 << 4); > -- > 2.35.1 > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From logout at free.fr Mon May 2 06:25:55 2022 From: logout at free.fr (Emmanuel Deloget) Date: Mon, 2 May 2022 08:25:55 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: Le lun. 2 mai 2022 ? 03:31, Denys Vlasenko a ?crit : > > On Sun, May 1, 2022 at 6:35 PM Emmanuel Deloget wrote: > > > > - RNG is seeded and credited using file A. > > > > - File A is unlinked but not fsync()d. > > > > - TLS connection does something and a nonce is generated. > > > > - System loses power and reboots. > > > > - RNG is seeded and credited using same file A. > > > > - TLS connection does something and the same nonce is generated, > > > > resulting in catastrophic cryptographic failure. > > > > > > > > This is a big deal. Crediting seeds is not to be taken lightly. > > > > Crediting file-based seeds is _only_ safe when they're never used > > > > twice. > > > > > > Using the same file twice is better than having nothing at all. > > > > I beg to differ, and especially on some embedded systems where the RNG > > might be quite controllable by an attacker from the outside (mostly because > > it lacks a lot of entropy crediting inputs, which is exactly the reason why we > > need seedrng in the first place). This may lead to catastrophic cryptography > > failures down the road. > > Did you personally encounter such a situation? > I'm not implying it's not really happening, I'm interested to hear > from people who met this situation in real world. Hey :) We're now entering in the "cautionary tales" territory :) This happened, yes. We have not seen any exploitation of this in nature (I would guess that it was mostly because there were other lower hanging fruits; why would you attack the cryptography when you could shellshock the device? yeah, bash was here -- it was a time where ash was not deemed good enough to run the CGI scripts :) ; and that was not the worst vulnerability so in practice you wouldn't even need to use it to take full control of the device) but it was scary to see that our different devices were able to boot and generate the same SSH keys. This happened only on their first boot when the device was not connected to the LAN (and not on all devices). Blank state, 0 source of entropy. Quite a "fun" time. Best regards, -- Emmanuel Deloget From vda.linux at googlemail.com Mon May 2 09:37:17 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 May 2022 11:37:17 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: On Mon, May 2, 2022 at 8:26 AM Emmanuel Deloget wrote: > Le lun. 2 mai 2022 ? 03:31, Denys Vlasenko a ?crit : > > > I beg to differ, and especially on some embedded systems where the RNG > > > might be quite controllable by an attacker from the outside (mostly because > > > it lacks a lot of entropy crediting inputs, which is exactly the reason why we > > > need seedrng in the first place). This may lead to catastrophic cryptography > > > failures down the road. > > > > Did you personally encounter such a situation? > > I'm not implying it's not really happening, I'm interested to hear > > from people who met this situation in real world. > > Hey :) We're now entering in the "cautionary tales" territory :) > > This happened, yes. We have not seen any exploitation of this in > nature (I would guess that it was mostly because there were other > lower hanging fruits; why would you attack the cryptography when you > could shellshock the device? yeah, bash was here -- it was a time > where ash was not deemed good enough to run the CGI scripts :) ; and > that was not the worst vulnerability so in practice you wouldn't even > need to use it to take full control of the device) but it was scary to > see that our different devices were able to boot and generate the same > SSH keys. This happened only on their first boot when the device was > not connected to the LAN (and not on all devices). Blank state, 0 > source of entropy. Quite a "fun" time. If you still have a device which exhibits this behavior (seemingly totally deterministic state during each boot), can you try something like find /proc -maxdepth 1 -type f -size -8k '!' -name kmsg '!' -name sysrq-trigger | xargs md5sum and see whether any /proc files display variability? From vda.linux at googlemail.com Mon May 2 10:31:44 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 May 2022 12:31:44 +0200 Subject: add support for PATH in crontabs In-Reply-To: <20220308211254.E21A92E1177@grass.foxharp.boston.ma.us> References: <20220307174042.8EB362E00D1@grass.foxharp.boston.ma.us> <20220308211254.E21A92E1177@grass.foxharp.boston.ma.us> Message-ID: Applied, thanks. On Tue, Mar 8, 2022 at 10:13 PM Paul Fox wrote: > > peter0x44 wrote: > > > I'm afraid I can't remember how to generate the cool automatic size > > > diffs. The code change seems to add fewer than 100 bytes, but I also > > > ifdefed a very old level 5 debug loop in Parsefield(), which saved > > > over 100. So I think there's been a net shrinkage of about 30 bytes. > > > > Hi Paul, > > > > The size diffs are generated using `make bloatcheck` > > > > Thanks Peter -- That confirms what I thought: > > function old new delta > load_crontab 1043 1117 +74 > .rodata 3509 3515 +6 > bb_putchar_stderr 38 - -38 > ParseField 507 437 -70 > ------------------------------------------------------------------------------ > (add/remove: 0/1 grow/shrink: 2/1 up/down: 80/-108) Total: -28 bytes > text data bss dec hex filename > 78292 2767 1528 82587 1429b busybox_old > 78264 2767 1528 82559 1427f busybox_unstripped > > > > > =---------------------- > paul fox, pgf at foxharp.boston.ma.us (arlington, ma) > > _______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From David.Laight at ACULAB.COM Mon May 2 10:34:52 2022 From: David.Laight at ACULAB.COM (David Laight) Date: Mon, 2 May 2022 10:34:52 +0000 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> Message-ID: <9e83a7faebf2435095fce7b7ed719d44@AcuMS.aculab.com> From: Alexander Dahl > Sent: 02 May 2022 06:15 > > Am Sat, Apr 30, 2022 at 03:12:11PM +0200 schrieb Denys Vlasenko: > > Do you often pull power cords from machines you use for > > somewhat important crypto operations, such as generating keys? > > What are the chances that you also do it on a machine without RTC > > clock (which would otherwise supply randomness > > from the current time)? > > FWIW ? busybox is often used in embedded systems, and from my personal > 10y+ experience in that field, I can safely assure you: customers and > users pull power chords all the time and at absolutely unpredictable > times. Don't know if that's a real threat from a security point of > view, but only looking at what developers do is not giving you the > full picture. The start of boot sequence is usually 'safe'. Nothing external is likely to have access until towards the end of it. Someone with physical access can pull the power - but they can do all sorts of other things as well. The 'problem' is that systems with limited 'entropy' sources need to carry over some 'randomness' between boots. So you actually need to be updating the saved 'randomness' every so often during normal running. This is entirely different from initialising the PRNG which should only be done one at boot time. Now ideally the kernel would always 'stir' new entropy into whatever it had before - so even giving is a few kb of zeros wouldn't make things worse. But I suspect that hasn't been the case. Anyway while changing the saved randomness after loading the PRNG is needed in case the power is cut not long after the init scripts complete, it is much more useful to save it at the end of the scripts (eg as an S99 script) when there is a chance that some additional entropy has been accrued. Mild paranoia might be required when writing a normal file. Although I suspect the safest is just to open the existing file without O_TRUNC and rewrite exactly the same number of bytes. But what you really want to write is (probably) a combination of the old saved value, the kernel entropy pool and the kernel PRNG state. (The latter two being hashes.) But you need to do this without reloading the PRNG from the entropy pool or feeding the old saved state into the entropy pool. I don't see how seedrng helps this operation, nor whether the kernel code really lets it get suitable information. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) From Jason at zx2c4.com Mon May 2 10:53:13 2022 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 2 May 2022 12:53:13 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: On Mon, May 2, 2022 at 11:37 AM Denys Vlasenko wrote: > > On Mon, May 2, 2022 at 8:26 AM Emmanuel Deloget wrote: > > Le lun. 2 mai 2022 ? 03:31, Denys Vlasenko a ?crit : > > > > I beg to differ, and especially on some embedded systems where the RNG > > > > might be quite controllable by an attacker from the outside (mostly because > > > > it lacks a lot of entropy crediting inputs, which is exactly the reason why we > > > > need seedrng in the first place). This may lead to catastrophic cryptography > > > > failures down the road. > > > > > > Did you personally encounter such a situation? > > > I'm not implying it's not really happening, I'm interested to hear > > > from people who met this situation in real world. > > > > Hey :) We're now entering in the "cautionary tales" territory :) > > > > This happened, yes. We have not seen any exploitation of this in > > nature I've exploited nonce reuse before. It's a real thing. Also, captured, stored, and later correlated network traffic is a real thing. Stop playing fast and lose with the crypto here. And stop entertaining these discussions where you reduce the security of a thing because of random people on a mailing list spouting off nonsense. Moreover, I'm shocked that you've continued to erode the security of the software, without so much of a reply to me about it substantiating your actions. For shame. As we speak, that fsync(dfd) is still missing a check on its return value. Just remove seedrng.c from busybox. You are clearly not a competent steward of security sensitive software, and this is just going to lead to bad things. Thanks, Jason From logout at free.fr Mon May 2 11:05:59 2022 From: logout at free.fr (Emmanuel Deloget) Date: Mon, 2 May 2022 13:05:59 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: Hi, Le lun. 2 mai 2022 ? 11:37, Denys Vlasenko a ?crit : > > On Mon, May 2, 2022 at 8:26 AM Emmanuel Deloget wrote: > > Le lun. 2 mai 2022 ? 03:31, Denys Vlasenko a ?crit : > > > > I beg to differ, and especially on some embedded systems where the RNG > > > > might be quite controllable by an attacker from the outside (mostly because > > > > it lacks a lot of entropy crediting inputs, which is exactly the reason why we > > > > need seedrng in the first place). This may lead to catastrophic cryptography > > > > failures down the road. > > > > > > Did you personally encounter such a situation? > > > I'm not implying it's not really happening, I'm interested to hear > > > from people who met this situation in real world. > > > > Hey :) We're now entering in the "cautionary tales" territory :) > > > > This happened, yes. We have not seen any exploitation of this in > > nature (I would guess that it was mostly because there were other > > lower hanging fruits; why would you attack the cryptography when you > > could shellshock the device? yeah, bash was here -- it was a time > > where ash was not deemed good enough to run the CGI scripts :) ; and > > that was not the worst vulnerability so in practice you wouldn't even > > need to use it to take full control of the device) but it was scary to > > see that our different devices were able to boot and generate the same > > SSH keys. This happened only on their first boot when the device was > > not connected to the LAN (and not on all devices). Blank state, 0 > > source of entropy. Quite a "fun" time. > > If you still have a device which exhibits this behavior (seemingly > totally deterministic state during each boot), can you try something like > > | xargs md5sum > > and see whether any /proc files display variability? Unfortunately, I no longer have access to these devices. Not many were sold, and I hope that none is still in activity today (although I think that a former colleague told me that some of them are no later than last year but I could be wrong). This was an old device (development started in 2004, production stopped in 2009 IIRC). Best regards, -- Emmanuel Deloget From vda.linux at googlemail.com Mon May 2 12:26:43 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 May 2022 14:26:43 +0200 Subject: [PATCH] tsort: new applet In-Reply-To: <788o3p8p-r677-sn2n-3p33-n33so48o97rs@nqncgvir-ragrecevfrf.pbz> References: <82qrn0s-8q67-6r98-rqs-r4376r59r88n@nqncgvir-ragrecevfrf.pbz> <20220220171141.714e853a@devuan> <788o3p8p-r677-sn2n-3p33-n33so48o97rs@nqncgvir-ragrecevfrf.pbz> Message-ID: applied, thank you On Mon, Feb 21, 2022 at 12:59 AM David Leonard wrote: > > Thanks. Patch fixed, attached. > > By the way, is this the right default for config? > > +//config: default n > > David > > On Sun, 20 Feb 2022, tito wrote: > > > some minor fixes inline. > ... > > + /* binry search for name */ > > > > Typo binry -> binary > ... > > +#ifndef TINY > > > > bb_error_msg("cycle at %s", G.nodes[i]->name); > > > > + fprintf(stderr, "tsort: cycle at %s\n", G.nodes[i]->name); > > +#endif_______________________________________________ > busybox mailing list > busybox at busybox.net > http://lists.busybox.net/mailman/listinfo/busybox From vda.linux at googlemail.com Mon May 2 12:48:53 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 May 2022 14:48:53 +0200 Subject: /sbin/init overrides HOME and TERM env vars In-Reply-To: <128771cb-a5ed-f6c6-9774-e4617528d7a5@wp.pl> References: <17861c38-3c89-16a5-b713-f621617a3d2f@wp.pl> <128771cb-a5ed-f6c6-9774-e4617528d7a5@wp.pl> Message-ID: On Sat, Mar 12, 2022 at 11:20 AM jkm <8192 at wp.pl> wrote: > > Looking at the kernel code in init/main.c, it does look like HOME=/ > > TERM=linux is hard coded in the kernel with no way to override this from > > the command line. > > I guess you are wrong. > HOME and TERM env vars can be overriden with boot params. > > Anyway, if HOME=/ is hardcoded in the kernel then what is the reason for > setting it in init command for the second time? > > putenv((char *) "HOME=/"); > > > Did you check if you can actually set this to something else? > > Yes, I did. I removed setting of HOME="/" from init. From vda.linux at googlemail.com Mon May 2 13:22:39 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Mon, 2 May 2022 15:22:39 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: On Sun, May 1, 2022 at 3:07 PM David Laight wrote: > Using the same file twice is better than having nothing at all. > At least different systems use different values. > Unless you have a remote 'dos' attack that can crash the system > at exactly the right point in the boot sequence this is an > entirely 'academic' error. > > What is much more likely is that the file where the entropy > is saved is just a memory overlay on top of a read-only image. > > That is much more likely for an embedded system than any of > the 'failure' cases you've considered. > > I also wonder how sane it is to do 'new_key = f(old_key)'. > That doesn't seem significantly better than using the same key. > > For a really embedded system the only persistent storage > could easily be a small serial EEPROM with a very limited > number of write cycles. > This requires special code to read/write and care to avoid > hitting the write cycle count on a small number of memory cells. > No amount of faffing about with filesystem accesses will > help here at all. Exactly why I want to hear about real-world cases where it was demonstrably difficult to initialize RNG properly. Need to separate fiction and exaggerations from reality. > There is also the case (that on my systems at least) udev > initialisation reads from /dev/[u]random well before the S20 > script loads any saved entropy. > I've not tried to find out what the value is used for. From rep.dot.nop at gmail.com Mon May 2 13:54:56 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Mon, 2 May 2022 15:54:56 +0200 Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> Message-ID: <20220502155456.0e5c1f81@nbbrfq> On Sun, 1 May 2022 18:35:00 +0200 Emmanuel Deloget wrote: > > There is also the case (that on my systems at least) udev > > initialisation reads from /dev/[u]random well before the S20 > > script loads any saved entropy. > > I've not tried to find out what the value is used for. > > I find at least one occurrence where the goal is to create a > random delay in udev-watch.c [1]. Yes, but that spot does seem to have a fallback. But why is the seeding being run only at S20, way after udev? seedrng would not _have_ to rely on /dev/{,u}random being there, we could as well mknod our own node(s) and could hence run way earlier, i assume. Would that help? We'd probably have less jitter accumulated if fewer other stuff did run before us, but still. thanks, From mconrad at intellitree.com Mon May 2 14:34:25 2022 From: mconrad at intellitree.com (Michael Conrad) Date: Mon, 02 May 2022 14:34:25 +0000 (UTC) Subject: [PATCH v2] seedrng: limit poolsize to 256 bytes and document flock() and fsync() usage In-Reply-To: <20220502155456.0e5c1f81@nbbrfq> References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> <20220502155456.0e5c1f81@nbbrfq> Message-ID: <8422eb03-2f9e-b38e-9eac-30c85afa983a@intellitree.com> On 5/2/22 09:54, Bernhard Reutner-Fischer wrote: >>> There is also the case (that on my systems at least) udev >>> initialisation reads from /dev/[u]random well before the S20 >>> script loads any saved entropy. >>> I've not tried to find out what the value is used for. >> I find at least one occurrence where the goal is to create a >> random delay in udev-watch.c [1]. > Yes, but that spot does seem to have a fallback. > > But why is the seeding being run only at S20, way after udev? It needs to be at least late enough for the persistent storage to be mounted, which probably isn't the root filesystem at boot. udev probably needs to run first to find the device nodes for the persistent storage. From rep.dot.nop at gmail.com Mon May 2 15:06:18 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Mon, 02 May 2022 17:06:18 +0200 Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_v2=5D_seedrng=3A_limit_poolsize_to_256?= =?US-ASCII?Q?_bytes_and_document_flock=28=29_and_fsync=28=29_usage?= In-Reply-To: <8422eb03-2f9e-b38e-9eac-30c85afa983a@intellitree.com> References: <20220429124812.2404785-1-Jason@zx2c4.com> <20220429170447.2558932-1-Jason@zx2c4.com> <896ddb59678249669fcec905f639f1a8@AcuMS.aculab.com> <20220502155456.0e5c1f81@nbbrfq> <8422eb03-2f9e-b38e-9eac-30c85afa983a@intellitree.com> Message-ID: <1CD42062-EFF3-4FBD-92CF-8C3E6D837281@gmail.com> On 2 May 2022 16:34:25 CEST, Michael Conrad wrote: >On 5/2/22 09:54, Bernhard Reutner-Fischer wrote: >> But why is the seeding being run only at S20, way after udev? > >It needs to be at least late enough for the persistent storage to be mounted, which probably isn't the root filesystem at boot. udev probably needs to run first to find the device nodes for the persistent storage. Ah, of course! thanks, From rknecht at pm.me Mon May 2 20:48:01 2022 From: rknecht at pm.me (rknecht at pm.me) Date: Mon, 02 May 2022 20:48:01 +0000 Subject: [PATCH v4] tree: new applet In-Reply-To: <20220501191152.18d3422a@devuan> References: <20220501125024.1523-1-rknecht@pm.me> <20220501191152.18d3422a@devuan> Message-ID: > Hi, > if (dirent->d_name[0] != '.') { > > > + if (strncmp(dirent->d_name, ".", 1) != 0) { > > > twisted logic? Will fix > > > + is_file = !is_directory(dirent->d_name, 1); > > > is_not_last is used only once Will fix > Less lines maybe less size (untested) > > if (is_directory(dirent->d_name, 1)) { > > globals.directories++; > tree_print(dirent->d_name, &child_directory); > > } else { > globals.files++; > printf((symlink) ? "%s -> %s\n" : "%s\n", dirent->d_name, symlink_path); > > } > free(symlink_path); This changes the output and fails the tests. Thanks, Roger From rknecht at pm.me Mon May 2 21:15:48 2022 From: rknecht at pm.me (rknecht at pm.me) Date: Mon, 02 May 2022 21:15:48 +0000 Subject: [PATCH v4] tree: new applet In-Reply-To: <20220501195945.1d888c09@devuan> References: <20220501125024.1523-1-rknecht@pm.me> <20220501195945.1d888c09@devuan> Message-ID: > On Mon, 2 May 2022 01:40:39 +0800 > Kang-Che Sung explorer09 at gmail.com wrote: > > > Hi Roger, > > > > May I suggest you add an option to draw the tree lines using ASCII > > characters only, and make the Unicode support optional at build time? > > > > I just feel uncomfortable when I see source code containing embedded UTF-8 > > characters and the strings have no ASCII alternative. > > > > The DOS tree command has the "/a" option. You know what I mean. > > > > Thank you. > > > Hi, > something like ?: > > #ifdef CONFIG_TREE_ASCII_ONLY > #define PREFIX_CHILD "|- " > #define PREFIX_LAST_CHILD "|_ " > #define PREFIX_GRAND_CHILD "| " > #define PREFIX_LAST_GRAND_CHILD " " > #else > #define PREFIX_CHILD "??? " > #define PREFIX_LAST_CHILD "??? " > #define PREFIX_GRAND_CHILD "? " > #define PREFIX_LAST_GRAND_CHILD " " > #endif > Agree, I even think the default should be ASCII only with an build option for the unicode tree. The ASCII only mode reduces also the binary size. Thanks, Roger From vda.linux at googlemail.com Mon May 2 22:53:32 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Tue, 3 May 2022 00:53:32 +0200 Subject: [PATCH] cpio: code shrink In-Reply-To: <62050bc7.8NfDUxqWvOb54tXW%rmy@pobox.com> References: <62050bc7.8NfDUxqWvOb54tXW%rmy@pobox.com> Message-ID: On Thu, Feb 10, 2022 at 2:13 PM Ron Yorston wrote: > Use a generic llist_t to store the names of hardlinked files. > > function old new delta > cpio_o 1140 1122 -18 > > Signed-off-by: Ron Yorston > --- > archival/cpio.c | 18 ++++-------------- > 1 file changed, 4 insertions(+), 14 deletions(-) > > diff --git a/archival/cpio.c b/archival/cpio.c > index 7149782d7..836609fc3 100644 > --- a/archival/cpio.c > +++ b/archival/cpio.c > @@ -223,13 +223,9 @@ static off_t cpio_pad4(off_t size) > * It's ok to exit instead of return. */ > static NOINLINE int cpio_o(void) > { > - struct name_s { > - struct name_s *next; > - char name[1]; > - }; > struct inodes_s { > struct inodes_s *next; > - struct name_s *names; > + llist_t *names; > struct stat st; > #if ENABLE_FEATURE_CPIO_RENUMBER_INODES > ino_t mapped_inode; > @@ -277,7 +273,6 @@ static NOINLINE int cpio_o(void) > > /* Store hardlinks for later processing, dont output them */ > if (!S_ISDIR(st.st_mode) && st.st_nlink > 1) { > - struct name_s *n; > struct inodes_s *l; > > /* Do we have this hardlink remembered? */ > @@ -302,11 +297,7 @@ static NOINLINE int cpio_o(void) > l = l->next; > } > /* Add new name to "l->names" list */ > - n = xmalloc(sizeof(*n) + strlen(name)); > - strcpy(n->name, name); > - n->next = l->names; > - l->names = n; > - > + llist_add_to(&l->names, xstrdup(name)); This is less space-efficient. Old code uses one allocation, new one uses two. We can potentially have a lot of hardlinks... From ahe at helmcke.name Tue May 3 11:58:44 2022 From: ahe at helmcke.name (Andreas Helmcke) Date: Tue, 3 May 2022 13:58:44 +0200 Subject: [PATCH] pw_encrypt: Add option to enable bcrypt support In-Reply-To: <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> References: <78ce2003-fab6-d3b7-05f6-619fdf331071@Z5T1.com> <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> Message-ID: <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> Adds an option to the Login/Password Management Utilities menu to enable bcrypt support in passwd and chpasswd. Add support for bcrypt to BusyBox chpasswd & passwd. Based on patch proposed by Scott Court. Changes to the orignal patch: - added config option for bcrypt cost - made code changes fully dependend on config option - changed algorithm tag to $2b$ - help texts added for bcrypt option Signed-off-by: Andreas Helmcke --- include/libbb.h | 5 +++++ include/usage.src.h | 5 +++++ libbb/pw_encrypt.c | 18 ++++++++++++++++++ loginutils/Config.src | 22 ++++++++++++++++++++++ loginutils/chpasswd.c | 3 ++- 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/include/libbb.h b/include/libbb.h index 6aeec249d..c6f769082 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1776,8 +1776,13 @@ extern int obscure(const char *old, const char *newval, const struct passwd *pwd * (otherwise we risk having same salt generated) */ extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC; +#if ENABLE_USE_BCRYPT +/* "$NX$10$" + bcrypt_salt_24_bytes + NUL */ +#define MAX_PW_SALT_LEN (7 + 24 + 1) +#else /* "$N$" + sha_salt_16_bytes + NUL */ #define MAX_PW_SALT_LEN (3 + 16 + 1) +#endif extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC; diff --git a/include/usage.src.h b/include/usage.src.h index 5d2038834..d8a679ab3 100644 --- a/include/usage.src.h +++ b/include/usage.src.h @@ -18,8 +18,13 @@ #define scripted_full_usage "" #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA +#if ENABLE_USE_BCRYPT +# define CRYPT_METHODS_HELP_STR "des,md5,sha256/512,bcrypt" \ + " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" +#else # define CRYPT_METHODS_HELP_STR "des,md5,sha256/512" \ " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" +#endif #else # define CRYPT_METHODS_HELP_STR "des,md5" \ " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 3463fd95b..2da4ab1d0 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -70,6 +70,24 @@ char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); len = 16/2; } +#endif +#if ENABLE_USE_BCRYPT + if ((algo[0]|0x20) == 'b') { /* bcrypt */ + int cost = 0; +#if ENABLE_FEATURE_BCRYPT_COST + cost = (CONFIG_FEATURE_BCRYPT_COST); +#endif + if (cost < 0 || cost > 31) + cost = 10; + + salt[1] = '2'; + salt[2] = 'b'; + *salt_ptr++ = '$'; + *salt_ptr++ = (cost / 10) + '0'; + *salt_ptr++ = (cost % 10) + '0'; + *salt_ptr++ = '$'; + len = 24/2; + } #endif } crypt_make_salt(salt_ptr, len); diff --git a/loginutils/Config.src b/loginutils/Config.src index cbb09646b..cdcd7132f 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src @@ -91,6 +91,28 @@ config USE_BB_CRYPT_SHA With this option off, login will fail password check for any user which has password encrypted with these algorithms. +config USE_BCRYPT + bool "Enable the bcrypt crypt function" + default n + depends on !USE_BB_CRYPT + help + Enable this if you have passwords starting with $2a$, $2y$ or + $2b$ in your /etc/passwd or /etc/shadow files. These passwords + are hashed using the bcrypt algorithm. Requires the use of a C + library that supports bcrypt. + +config FEATURE_BCRYPT_COST + int "bcrypt cost" + range 4 31 + default 10 + depends on USE_BCRYPT + help + Cost paramter for the bcrypt hashing algorithm. + Specifies the number of rounds to use. Must be between 4 and 31, + inclusive. This value is logarithmic, the actual number of + iterations used will be 2**rounds ? increasing the rounds by +1 + will double the amount of time taken. + INSERT endmenu diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index a032abbed..74673fa6f 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -17,7 +17,8 @@ //config: default "des" //config: depends on PASSWD || CRYPTPW || CHPASSWD //config: help -//config: Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". +//config: Possible choices are "d[es]", "m[d5]", "s[ha256]", +//config: "sha512" or "b[crypt]" (when enabled). //applet:IF_CHPASSWD(APPLET(chpasswd, BB_DIR_USR_SBIN, BB_SUID_DROP)) -- 2.34.1 From cand at gmx.com Tue May 3 12:23:27 2022 From: cand at gmx.com (Lauri Kasanen) Date: Tue, 3 May 2022 15:23:27 +0300 Subject: [PATCH] pw_encrypt: Add option to enable bcrypt support In-Reply-To: <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> References: <78ce2003-fab6-d3b7-05f6-619fdf331071@Z5T1.com> <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> Message-ID: <20220503152327.d4462b1de8d8c64317263624@gmx.com> On Tue, 3 May 2022 13:58:44 +0200 Andreas Helmcke wrote: > diff --git a/loginutils/Config.src b/loginutils/Config.src > index cbb09646b..cdcd7132f 100644 > --- a/loginutils/Config.src > +++ b/loginutils/Config.src > @@ -91,6 +91,28 @@ config USE_BB_CRYPT_SHA > With this option off, login will fail password check for any > user which has password encrypted with these algorithms. > > +config USE_BCRYPT > + bool "Enable the bcrypt crypt function" > + default n > + depends on !USE_BB_CRYPT > + help > + Enable this if you have passwords starting with $2a$, $2y$ or > + $2b$ in your /etc/passwd or /etc/shadow files. These passwords > + are hashed using the bcrypt algorithm. Requires the use of a C > + library that supports bcrypt. The manpage says 2a is blowfish, which this patch wouldn't enable. I'd also like a compile-time check for the libc support, something like #if GLIBC && GLIBC_VERSION < blah #error Your libc doesn't support bcrypt #endif - Lauri From logout at free.fr Tue May 3 12:51:06 2022 From: logout at free.fr (Emmanuel Deloget) Date: Tue, 3 May 2022 14:51:06 +0200 Subject: [PATCH] pw_encrypt: Add option to enable bcrypt support In-Reply-To: <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> References: <78ce2003-fab6-d3b7-05f6-619fdf331071@Z5T1.com> <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> Message-ID: Hello, Le mar. 3 mai 2022 ? 13:58, Andreas Helmcke a ?crit : > > Adds an option to the Login/Password Management Utilities menu to enable > bcrypt support in passwd and chpasswd. > > Add support for bcrypt to BusyBox chpasswd & passwd. > > Based on patch proposed by Scott Court. > > Changes to the orignal patch: > - added config option for bcrypt cost > - made code changes fully dependend on config option > - changed algorithm tag to $2b$ > - help texts added for bcrypt option > > Signed-off-by: Andreas Helmcke > --- > include/libbb.h | 5 +++++ > include/usage.src.h | 5 +++++ > libbb/pw_encrypt.c | 18 ++++++++++++++++++ > loginutils/Config.src | 22 ++++++++++++++++++++++ > loginutils/chpasswd.c | 3 ++- > 5 files changed, 52 insertions(+), 1 deletion(-) > > diff --git a/include/libbb.h b/include/libbb.h > index 6aeec249d..c6f769082 100644 > --- a/include/libbb.h > +++ b/include/libbb.h > @@ -1776,8 +1776,13 @@ extern int obscure(const char *old, const char > *newval, const struct passwd *pwd > * (otherwise we risk having same salt generated) > */ > extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC; > +#if ENABLE_USE_BCRYPT > +/* "$NX$10$" + bcrypt_salt_24_bytes + NUL */ > +#define MAX_PW_SALT_LEN (7 + 24 + 1) > +#else > /* "$N$" + sha_salt_16_bytes + NUL */ > #define MAX_PW_SALT_LEN (3 + 16 + 1) > +#endif > extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char > *algo) FAST_FUNC; > > > diff --git a/include/usage.src.h b/include/usage.src.h > index 5d2038834..d8a679ab3 100644 > --- a/include/usage.src.h > +++ b/include/usage.src.h > @@ -18,8 +18,13 @@ > #define scripted_full_usage "" > > #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA > +#if ENABLE_USE_BCRYPT > +# define CRYPT_METHODS_HELP_STR "des,md5,sha256/512,bcrypt" \ > + " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" > +#else > # define CRYPT_METHODS_HELP_STR "des,md5,sha256/512" \ > " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" > +#endif > #else > # define CRYPT_METHODS_HELP_STR "des,md5" \ > " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" > diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c > index 3463fd95b..2da4ab1d0 100644 > --- a/libbb/pw_encrypt.c > +++ b/libbb/pw_encrypt.c > @@ -70,6 +70,24 @@ char* FAST_FUNC crypt_make_pw_salt(char > salt[MAX_PW_SALT_LEN], const char *algo) > salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); > len = 16/2; > } > +#endif > +#if ENABLE_USE_BCRYPT > + if ((algo[0]|0x20) == 'b') { /* bcrypt */ > + int cost = 0; > +#if ENABLE_FEATURE_BCRYPT_COST It seems to me that if ENABLE_USE_BCRYPT is set, then the bcrypt cost is always there. Am I missing something? > + cost = (CONFIG_FEATURE_BCRYPT_COST); > +#endif > + if (cost < 0 || cost > 31) This allows values (1, 2, 3) that are outside the range of the values specified in the config text. BTW, if the values outside [4, 31] are invalid, maybe a compile-time error would be a good thing? (this is actually a real question, not a code change suggestion). That would make the code a bit smaller as you could confidently and directly use (CONFIG_FEATURE_BCRYPT_COST / 10) and (CONFIG_FEATURE_BCRYPT_COST % 10) in the code below (no need to set a cost variable). > + cost = 10; > + > + salt[1] = '2'; > + salt[2] = 'b'; > + *salt_ptr++ = '$'; > + *salt_ptr++ = (cost / 10) + '0'; > + *salt_ptr++ = (cost % 10) + '0'; > + *salt_ptr++ = '$'; > + len = 24/2; > + } > #endif > } > crypt_make_salt(salt_ptr, len); > diff --git a/loginutils/Config.src b/loginutils/Config.src > index cbb09646b..cdcd7132f 100644 > --- a/loginutils/Config.src > +++ b/loginutils/Config.src > @@ -91,6 +91,28 @@ config USE_BB_CRYPT_SHA > With this option off, login will fail password check for any > user which has password encrypted with these algorithms. > > +config USE_BCRYPT > + bool "Enable the bcrypt crypt function" > + default n > + depends on !USE_BB_CRYPT > + help > + Enable this if you have passwords starting with $2a$, $2y$ or > + $2b$ in your /etc/passwd or /etc/shadow files. These passwords > + are hashed using the bcrypt algorithm. Requires the use of a C > + library that supports bcrypt. > + > +config FEATURE_BCRYPT_COST > + int "bcrypt cost" > + range 4 31 > + default 10 > + depends on USE_BCRYPT > + help > + Cost paramter for the bcrypt hashing algorithm. typo: parameter > + Specifies the number of rounds to use. Must be between 4 and 31, > + inclusive. This value is logarithmic, the actual number of > + iterations used will be 2**rounds ? increasing the rounds by +1 > + will double the amount of time taken. > + > INSERT > > endmenu > diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c > index a032abbed..74673fa6f 100644 > --- a/loginutils/chpasswd.c > +++ b/loginutils/chpasswd.c > @@ -17,7 +17,8 @@ > //config: default "des" > //config: depends on PASSWD || CRYPTPW || CHPASSWD > //config: help > -//config: Possible choices are "d[es]", "m[d5]", "s[ha256]" or > "sha512". > +//config: Possible choices are "d[es]", "m[d5]", "s[ha256]", > +//config: "sha512" or "b[crypt]" (when enabled). > //applet:IF_CHPASSWD(APPLET(chpasswd, BB_DIR_USR_SBIN, BB_SUID_DROP)) > > -- > 2.34.1 Best regards, -- Emmanuel Deloget From ahe at helmcke.name Tue May 3 13:47:18 2022 From: ahe at helmcke.name (Andreas Helmcke) Date: Tue, 3 May 2022 15:47:18 +0200 Subject: [PATCH] pw_encrypt: Add option to enable bcrypt support In-Reply-To: <20220503152327.d4462b1de8d8c64317263624@gmx.com> References: <78ce2003-fab6-d3b7-05f6-619fdf331071@Z5T1.com> <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> <20220503152327.d4462b1de8d8c64317263624@gmx.com> Message-ID: <08ae3602-b9ad-9edb-5af5-89069e7ee7b5@helmcke.name> Am 03.05.22 um 14:23 schrieb Lauri Kasanen: > On Tue, 3 May 2022 13:58:44 +0200 > Andreas Helmcke wrote: > > >> diff --git a/loginutils/Config.src b/loginutils/Config.src >> index cbb09646b..cdcd7132f 100644 >> --- a/loginutils/Config.src >> +++ b/loginutils/Config.src >> @@ -91,6 +91,28 @@ config USE_BB_CRYPT_SHA >> With this option off, login will fail password check for any >> user which has password encrypted with these algorithms. >> >> +config USE_BCRYPT >> + bool "Enable the bcrypt crypt function" >> + default n >> + depends on !USE_BB_CRYPT >> + help >> + Enable this if you have passwords starting with $2a$, $2y$ or >> + $2b$ in your /etc/passwd or /etc/shadow files. These passwords >> + are hashed using the bcrypt algorithm. Requires the use of a C >> + library that supports bcrypt. > > The manpage says 2a is blowfish, which this patch wouldn't enable. This is depends on the used library. The patch has two parts: 1. allow the use of longer salt strings for the password functions (in libbb/pw_encrypt.c) 2. enable the use of bcrypt in BusyBox passwd and chpasswd Part 1 allows the use of any password hash algorithm, supported by the used libcrypt, for checking password hashes in the passwd (or shadow) file. As long as the starting part of the hash (tag and salt) is no longer than 31 bytes. Part 2 allows to generate bcrypt hashes with BusyBox password commands. Maybe this would be a better and less confusing help text: Enable this if you use newer password hashes like bcrypt. E.g. if you have passwords starting with $2a$, $2y$ or $2b$ in your /etc/passwd or /etc/shadow files. Requires the use of a C library that supports these hashes. > I'd also like a compile-time check for the libc support, something like > #if GLIBC && GLIBC_VERSION < blah > #error Your libc doesn't support bcrypt > #endif Would be nice, but i have no idea how to do this. Your suggestions only covers glibc and in my case i use this patch together with libxcrypt, so this would not help there. From ahe at helmcke.name Tue May 3 15:13:04 2022 From: ahe at helmcke.name (Andreas Helmcke) Date: Tue, 3 May 2022 17:13:04 +0200 Subject: [PATCH] pw_encrypt: Add option to enable bcrypt support In-Reply-To: References: <78ce2003-fab6-d3b7-05f6-619fdf331071@Z5T1.com> <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> Message-ID: <2c462ffa-9cfd-4cc2-5b72-ec253a57d60c@helmcke.name> Am 03.05.22 um 14:51 schrieb Emmanuel Deloget: > Le mar. 3 mai 2022 ? 13:58, Andreas Helmcke a ?crit : >> >> diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c >> index 3463fd95b..2da4ab1d0 100644 >> --- a/libbb/pw_encrypt.c >> +++ b/libbb/pw_encrypt.c >> @@ -70,6 +70,24 @@ char* FAST_FUNC crypt_make_pw_salt(char >> salt[MAX_PW_SALT_LEN], const char *algo) >> salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); >> len = 16/2; >> } >> +#endif >> +#if ENABLE_USE_BCRYPT >> + if ((algo[0]|0x20) == 'b') { /* bcrypt */ >> + int cost = 0; >> +#if ENABLE_FEATURE_BCRYPT_COST > > It seems to me that if ENABLE_USE_BCRYPT is set, then the bcrypt cost > is always there. Am I missing something? > >> + cost = (CONFIG_FEATURE_BCRYPT_COST); >> +#endif >> + if (cost < 0 || cost > 31) > > This allows values (1, 2, 3) that are outside the range of the values > specified in the config text. > > BTW, if the values outside [4, 31] are invalid, maybe a compile-time > error would be a good thing? (this is actually a real question, not a > code change suggestion). That would make the code a bit smaller as you > could confidently and directly use (CONFIG_FEATURE_BCRYPT_COST / 10) > and (CONFIG_FEATURE_BCRYPT_COST % 10) in the code below (no need to > set a cost variable). Good idea. My intention was to try to avoid compile time errors, but a clear error while compiling is better than some unexpected effects later. >> +config FEATURE_BCRYPT_COST >> + int "bcrypt cost" >> + range 4 31 >> + default 10 >> + depends on USE_BCRYPT >> + help >> + Cost paramter for the bcrypt hashing algorithm. > > typo: parameter Changed, thanks. From ahe at helmcke.name Tue May 3 15:21:38 2022 From: ahe at helmcke.name (Andreas Helmcke) Date: Tue, 3 May 2022 17:21:38 +0200 Subject: [PATCH] pw_encrypt: Add option to enable bcrypt support In-Reply-To: <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> References: <78ce2003-fab6-d3b7-05f6-619fdf331071@Z5T1.com> <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> Message-ID: Adds an option to the Login/Password Management Utilities menu to enable bcrypt support in passwd and chpasswd. Add support for bcrypt to BusyBox chpasswd & passwd. Signed-off-by: Andreas Helmcke --- Changes v1->v2: - better help texts (hopefully) - check FEATURE_BCRYPT_COST parameter at compile time. Based on patch proposed by Scott Court. Changes to the orignal patch: - added config option for bcrypt cost - made code changes fully dependend on config option - changed algorithm tag to $2b$ - help texts added for bcrypt option include/libbb.h | 5 +++++ include/usage.src.h | 5 +++++ libbb/pw_encrypt.c | 14 ++++++++++++++ loginutils/Config.src | 23 +++++++++++++++++++++++ loginutils/chpasswd.c | 3 ++- 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/libbb.h b/include/libbb.h index 6aeec249d..c6f769082 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1776,8 +1776,13 @@ extern int obscure(const char *old, const char *newval, const struct passwd *pwd * (otherwise we risk having same salt generated) */ extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC; +#if ENABLE_USE_BCRYPT +/* "$NX$10$" + bcrypt_salt_24_bytes + NUL */ +#define MAX_PW_SALT_LEN (7 + 24 + 1) +#else /* "$N$" + sha_salt_16_bytes + NUL */ #define MAX_PW_SALT_LEN (3 + 16 + 1) +#endif extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC; diff --git a/include/usage.src.h b/include/usage.src.h index 5d2038834..d8a679ab3 100644 --- a/include/usage.src.h +++ b/include/usage.src.h @@ -18,8 +18,13 @@ #define scripted_full_usage "" #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA +#if ENABLE_USE_BCRYPT +# define CRYPT_METHODS_HELP_STR "des,md5,sha256/512,bcrypt" \ + " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" +#else # define CRYPT_METHODS_HELP_STR "des,md5,sha256/512" \ " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" +#endif #else # define CRYPT_METHODS_HELP_STR "des,md5" \ " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 3463fd95b..5b71a54a5 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -70,6 +70,20 @@ char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); len = 16/2; } +#endif +#if ENABLE_USE_BCRYPT +#if !ENABLE_FEATURE_BCRYPT_COST || CONFIG_FEATURE_BCRYPT_COST < 4 || CONFIG_FEATURE_BCRYPT_COST > 31 +#error Bad FEATURE_BCRYPT_COST in .config +#endif + if ((algo[0]|0x20) == 'b') { /* bcrypt */ + salt[1] = '2'; + salt[2] = 'b'; + *salt_ptr++ = '$'; + *salt_ptr++ = ((CONFIG_FEATURE_BCRYPT_COST) / 10) + '0'; + *salt_ptr++ = ((CONFIG_FEATURE_BCRYPT_COST) % 10) + '0'; + *salt_ptr++ = '$'; + len = 24/2; + } #endif } crypt_make_salt(salt_ptr, len); diff --git a/loginutils/Config.src b/loginutils/Config.src index cbb09646b..cdf36a55f 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src @@ -91,6 +91,29 @@ config USE_BB_CRYPT_SHA With this option off, login will fail password check for any user which has password encrypted with these algorithms. +config USE_BCRYPT + bool "Enable bcrypt and other password hashes." + default n + depends on !USE_BB_CRYPT + help + Enable this if you use newer password hashes like bcrypt. E.g. + if you have passwords starting with $2a$, $2y$ or $2b$ in your + /etc/passwd or /etc/shadow files. Requires the use of a C + library that supports these hashes. + Adds support for bcrypt to passwd, cryptpw and chpasswd. + +config FEATURE_BCRYPT_COST + int "bcrypt cost" + range 4 31 + default 10 + depends on USE_BCRYPT + help + Cost parameter for the bcrypt hashing algorithm. + Specifies the number of rounds to use. Must be between 4 and 31, + inclusive. This value is logarithmic, the actual number of + iterations used will be 2**rounds ? increasing the rounds by +1 + will double the amount of time taken. + INSERT endmenu diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index a032abbed..74673fa6f 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -17,7 +17,8 @@ //config: default "des" //config: depends on PASSWD || CRYPTPW || CHPASSWD //config: help -//config: Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". +//config: Possible choices are "d[es]", "m[d5]", "s[ha256]", +//config: "sha512" or "b[crypt]" (when enabled). //applet:IF_CHPASSWD(APPLET(chpasswd, BB_DIR_USR_SBIN, BB_SUID_DROP)) -- 2.34.1 From timo.teras at iki.fi Wed May 4 16:52:48 2022 From: timo.teras at iki.fi (=?UTF-8?q?Timo=20Ter=C3=A4s?=) Date: Wed, 4 May 2022 19:52:48 +0300 Subject: [PATCH 1/2] getty: keep IUTF8 Message-ID: <20220504165250.28079-1-timo.teras@iki.fi> IUTF8 is needed to handle line editing correctly in utf-8 mode. On virtual terminals kernel sets this flag automatically if utf8 mode is active (the default). This is also what util-linux agetty does. Signed-off-by: Timo Ter?s --- loginutils/getty.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/loginutils/getty.c b/loginutils/getty.c index cd6378d80..890826a57 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -49,6 +49,9 @@ #ifndef IUCLC # define IUCLC 0 #endif +#ifndef IUTF8 +# define IUTF8 0 +#endif #ifndef LOGIN_PROCESS # undef ENABLE_FEATURE_UTMP @@ -310,7 +313,7 @@ static void init_tty_attrs(int speed) if (option_mask32 & F_RTSCTS) G.tty_attrs.c_cflag |= CRTSCTS; /* flow control using RTS/CTS pins */ #endif - G.tty_attrs.c_iflag = 0; + G.tty_attrs.c_iflag &= IUTF8; G.tty_attrs.c_lflag = 0; /* non-raw output; add CR to each NL */ G.tty_attrs.c_oflag = OPOST | ONLCR; -- 2.36.0 From timo.teras at iki.fi Wed May 4 16:52:49 2022 From: timo.teras at iki.fi (=?UTF-8?q?Timo=20Ter=C3=A4s?=) Date: Wed, 4 May 2022 19:52:49 +0300 Subject: [PATCH 2/2] reset: keep IUTF8 In-Reply-To: <20220504165250.28079-1-timo.teras@iki.fi> References: <20220504165250.28079-1-timo.teras@iki.fi> Message-ID: <20220504165250.28079-2-timo.teras@iki.fi> IUTF8 is needed to handle line editing correctly in utf-8 mode. On virtual terminals kernel sets this flag automatically if utf8 mode is active (the default). Unfortunately the "stty sane" will remove this flag by documentation, so add support to keep it enabled if it was set. Signed-off-by: Timo Ter?s --- console-tools/reset.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/console-tools/reset.c b/console-tools/reset.c index cc04e4fcc..456efac4a 100644 --- a/console-tools/reset.c +++ b/console-tools/reset.c @@ -27,17 +27,31 @@ #include "libbb.h" +#ifndef IUTF8 +# define IUTF8 0 +#endif + #define ESC "\033" #if ENABLE_STTY int stty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; #endif +static int is_utf8(void) +{ +#if IUTF8 + struct termios mode; + if (tcgetattr(STDIN_FILENO, &mode) == 0) + return mode.c_iflag & IUTF8; +#endif + return 0; +} + int reset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int reset_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { - static const char *const args[] ALIGN_PTR = { - "stty", "sane", NULL + static const char * args[] ALIGN_PTR = { + "stty", "sane", "iutf8", NULL }; /* no options, no getopt */ @@ -53,11 +67,13 @@ int reset_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) printf(ESC"c" ESC"(B" ESC"[m" ESC"[J" ESC"[?25h"); /* http://bugs.busybox.net/view.php?id=1414: * people want it to reset echo etc: */ + #if ENABLE_STTY - return stty_main(2, (char**)args); + return stty_main(is_utf8() ? 3 : 2, (char**)args); #else /* Make sure stdout gets drained before we execvp */ fflush_all(); + if (!is_utf8()) args[2] = NULL; execvp("stty", (char**)args); #endif } -- 2.36.0 From ahe at helmcke.name Fri May 6 08:01:57 2022 From: ahe at helmcke.name (Andreas Helmcke) Date: Fri, 6 May 2022 10:01:57 +0200 Subject: [PATCH v3] pw_encrypt: Add option to enable bcrypt support In-Reply-To: References: <78ce2003-fab6-d3b7-05f6-619fdf331071@Z5T1.com> <2250d85c-419e-933e-cef6-764791bd24e9@dinapo.li> <8f7fc9b5-4171-4e7a-e89d-97e22d864779@helmcke.name> Message-ID: <0d194913-e463-8d26-42c8-d012858f36c3@helmcke.name> Adds an option to the Login/Password Management Utilities menu to enable bcrypt support in passwd and chpasswd. Add support for bcrypt to BusyBox chpasswd & passwd. Co-authored-by: Andreas Helmcke Signed-off-by: Andreas Helmcke Original-work-by: Scott Court --- Changes v2->v3: - Updated commit message to give credits to original author. Changes v1->v2: - better help texts (hopefully) - check FEATURE_BCRYPT_COST parameter at compile time. Based on patch proposed by Scott Court. Changes to the orignal patch: - added config option for bcrypt cost - made code changes fully dependend on config option - changed algorithm tag to $2b$ - help texts added for bcrypt option include/libbb.h | 5 +++++ include/usage.src.h | 5 +++++ libbb/pw_encrypt.c | 14 ++++++++++++++ loginutils/Config.src | 23 +++++++++++++++++++++++ loginutils/chpasswd.c | 3 ++- 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/libbb.h b/include/libbb.h index 6aeec249d..c6f769082 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1776,8 +1776,13 @@ extern int obscure(const char *old, const char *newval, const struct passwd *pwd * (otherwise we risk having same salt generated) */ extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC; +#if ENABLE_USE_BCRYPT +/* "$NX$10$" + bcrypt_salt_24_bytes + NUL */ +#define MAX_PW_SALT_LEN (7 + 24 + 1) +#else /* "$N$" + sha_salt_16_bytes + NUL */ #define MAX_PW_SALT_LEN (3 + 16 + 1) +#endif extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC; diff --git a/include/usage.src.h b/include/usage.src.h index 5d2038834..d8a679ab3 100644 --- a/include/usage.src.h +++ b/include/usage.src.h @@ -18,8 +18,13 @@ #define scripted_full_usage "" #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA +#if ENABLE_USE_BCRYPT +# define CRYPT_METHODS_HELP_STR "des,md5,sha256/512,bcrypt" \ + " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" +#else # define CRYPT_METHODS_HELP_STR "des,md5,sha256/512" \ " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" +#endif #else # define CRYPT_METHODS_HELP_STR "des,md5" \ " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 3463fd95b..5b71a54a5 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -70,6 +70,20 @@ char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); len = 16/2; } +#endif +#if ENABLE_USE_BCRYPT +#if !ENABLE_FEATURE_BCRYPT_COST || CONFIG_FEATURE_BCRYPT_COST < 4 || CONFIG_FEATURE_BCRYPT_COST > 31 +#error Bad FEATURE_BCRYPT_COST in .config +#endif + if ((algo[0]|0x20) == 'b') { /* bcrypt */ + salt[1] = '2'; + salt[2] = 'b'; + *salt_ptr++ = '$'; + *salt_ptr++ = ((CONFIG_FEATURE_BCRYPT_COST) / 10) + '0'; + *salt_ptr++ = ((CONFIG_FEATURE_BCRYPT_COST) % 10) + '0'; + *salt_ptr++ = '$'; + len = 24/2; + } #endif } crypt_make_salt(salt_ptr, len); diff --git a/loginutils/Config.src b/loginutils/Config.src index cbb09646b..cdf36a55f 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src @@ -91,6 +91,29 @@ config USE_BB_CRYPT_SHA With this option off, login will fail password check for any user which has password encrypted with these algorithms. +config USE_BCRYPT + bool "Enable bcrypt and other password hashes." + default n + depends on !USE_BB_CRYPT + help + Enable this if you use newer password hashes like bcrypt. E.g. + if you have passwords starting with $2a$, $2y$ or $2b$ in your + /etc/passwd or /etc/shadow files. Requires the use of a C + library that supports these hashes. + Adds support for bcrypt to passwd, cryptpw and chpasswd. + +config FEATURE_BCRYPT_COST + int "bcrypt cost" + range 4 31 + default 10 + depends on USE_BCRYPT + help + Cost parameter for the bcrypt hashing algorithm. + Specifies the number of rounds to use. Must be between 4 and 31, + inclusive. This value is logarithmic, the actual number of + iterations used will be 2**rounds ? increasing the rounds by +1 + will double the amount of time taken. + INSERT endmenu diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index a032abbed..74673fa6f 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -17,7 +17,8 @@ //config: default "des" //config: depends on PASSWD || CRYPTPW || CHPASSWD //config: help -//config: Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". +//config: Possible choices are "d[es]", "m[d5]", "s[ha256]", +//config: "sha512" or "b[crypt]" (when enabled). //applet:IF_CHPASSWD(APPLET(chpasswd, BB_DIR_USR_SBIN, BB_SUID_DROP)) -- 2.34.1 From earthquake.de at freenet.de Fri May 6 14:19:03 2022 From: earthquake.de at freenet.de (Earthquake) Date: Fri, 6 May 2022 16:19:03 +0200 Subject: buildroot host builds with g++ Message-ID: <80d6f58b-a36e-6148-c6b6-37a29d3244e5@freenet.de> Hi, building package for the host, ends with: g++: error: /usr/bin/g++": No such file or directory Building the same package for the target works.... Package mk for host build calls generic-package and host-generic-package. Best regards, Alex From peter at korsgaard.com Fri May 6 15:23:22 2022 From: peter at korsgaard.com (Peter Korsgaard) Date: Fri, 06 May 2022 17:23:22 +0200 Subject: buildroot host builds with g++ In-Reply-To: <80d6f58b-a36e-6148-c6b6-37a29d3244e5@freenet.de> (Earthquake's message of "Fri, 6 May 2022 16:19:03 +0200") References: <80d6f58b-a36e-6148-c6b6-37a29d3244e5@freenet.de> Message-ID: <874k221y8l.fsf@dell.be.48ers.dk> >>>>> "Earthquake" == Earthquake writes: > Hi, > building package for the host, ends with: > g++: error: /usr/bin/g++": No such file or directory > Building the same package for the target works.... > Package mk for host build calls generic-package and host-generic-package. This sounds like a Buildroot question rather than a Busybox one, so please followup on the Buildroot list (buildroot at buildroot.org). With that said, if your package is written in C++ and you try to build it for the host, then you need a C++ compiler on your host, but please provide some more details about what exactly you are trying to do. -- Bye, Peter Korsgaard From stokito at gmail.com Sun May 8 17:13:53 2022 From: stokito at gmail.com (Sergey Ponomarev) Date: Sun, 8 May 2022 20:13:53 +0300 Subject: [PATCH 1/2] wget: Use HEAD for --spider Message-ID: <20220508171354.56073-1-stokito@gmail.com> From: Jake In GNU wget the --spider[1] first issues a HEAD request[2], then if HEAD fails, issues a GET request[3]. In BusyBox wget, only a GET request is sent. All webservers including BB httpd and uhttpd supports the HEAD. The patch changes GET to HEAD e.g. get the file size only without downloading first. This is still not totally compatible with GNU wget because it does not retry with GET if HEAD fails. Potentially someone may use the --spider to call a GET only API, so they may be affected. But this is incorrect usage while others may expect that the spider uses HEAD and don't expect a download. For testing use a CGI script /www/cgi-bin/echo.sh: #!/bin/sh CONTENT=$(cat -) printf "Content-Length: ${#CONTENT}\r\n" printf "Content-Type: text/html\r\n" printf "REQUEST_METHOD: $REQUEST_METHOD\r\n" printf "CONTENT_TYPE: $CONTENT_TYPE\r\n" printf "CONTENT_LENGTH: $CONTENT_LENGTH\r\n" printf "\r\n" printf "$CONTENT" Then call it: $ busybox wget -O - -S -q --spider? http://localhost:8080/cgi-bin/echo.sh HTTP/1.0 200 OK Content-Length: 0 Content-Type: text/html REQUEST_METHOD: HEAD CONTENT_TYPE: CONTENT_LENGTH: When both post-data and spider options then gnu wget behaves confusing[4]. It sets Content-Type: application/x-www-form-urlencoded as for post-data but anyway sends a HEAD request: $ wget -O - -S -q --post-data="trololo" --spider? http://localhost:8080/cgi-bin/echo.shest.sh HTTP/1.0 200 OK Content-Length: 7 Content-Type: text/html REQUEST_METHOD: HEAD CONTENT_TYPE: application/x-www-form-urlencoded CONTENT_LENGTH: Instead, this version will send the request as POST but still skip it's response body: $ busybox wget -O - -S -q --post-data="trololo" --spider? http://localhost:8080/cgi-bin/echo.sh HTTP/1.0 200 OK Content-Length: 7 Content-Type: text/html REQUEST_METHOD: POST CONTENT_TYPE: application/x-www-form-urlencoded CONTENT_LENGTH: 7 This would be useful for heavy API calls but we have to wait what GNU wget author will say. We may change this behaviour later. [1] https://www.gnu.org/software/wget/manual/wget.html#index-spider [2] https://httpwg.org/specs/rfc7231.html#HEAD [3] https://git.savannah.gnu.org/cgit/wget.git/tree/src/http.c#n4304 [4] https://savannah.gnu.org/bugs/index.php?56808 function???????????????????????????????????????????? old???? new?? delta wget_main?????????????????????????????????????????? 2797??? 2824???? +27 .rodata??????????????????????????????????????????? 10213?? 10217????? +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 31/0)?????????????? Total: 31 bytes text??? data???? bss???? dec???? hex filename 177416??? 3971??? 1688? 183075?? 2cb23 busybox_old 177447??? 3971??? 1688? 183106?? 2cb42 busybox_unstripped Signed-off-by: Sergey Ponomarev --- networking/wget.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index 9ec0e67b9..0006f8807 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -242,6 +242,7 @@ static const char wget_user_headers[] ALIGN1 = /* Globals */ struct globals { + const char *method; off_t content_len; /* Content-length of the file */ off_t beg_range; /* Range at which continue begins */ #if ENABLE_FEATURE_WGET_STATUSBAR @@ -1220,12 +1221,13 @@ static void download_one_url(const char *url) #endif /* Send HTTP request */ if (use_proxy) { - SENDFMT(sfp, "GET %s://%s/%s HTTP/1.1\r\n", + SENDFMT(sfp, "%s %s://%s/%s HTTP/1.1\r\n", + G.method, target.protocol, target.host, target.path); } else { SENDFMT(sfp, "%s /%s HTTP/1.1\r\n", - (option_mask32 & WGET_OPT_POST) ? "POST" : "GET", + G.method, target.path); } if (!USR_HEADER_HOST) @@ -1582,6 +1584,15 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") #endif argv += optind; + if (option_mask32 & WGET_OPT_POST) { + G.method = "POST"; + } else if (option_mask32 & WGET_OPT_SPIDER) { + /* Note: GNU wget --spider sends a HEAD and if it failed repeats with a GET */ + G.method = "HEAD"; + } else { + G.method = "GET"; + } + #if ENABLE_FEATURE_WGET_LONG_OPTIONS if (headers_llist) { int size = 0; -- 2.34.1 From stokito at gmail.com Sun May 8 17:13:54 2022 From: stokito at gmail.com (Sergey Ponomarev) Date: Sun, 8 May 2022 20:13:54 +0300 Subject: [PATCH 2/2] wget: Support of --method, --body-data and --body-file In-Reply-To: <20220508171354.56073-1-stokito@gmail.com> References: <20220508171354.56073-1-stokito@gmail.com> Message-ID: <20220508171354.56073-2-stokito@gmail.com> The --method allows to execute PUT,DELETE,OPTIONS. Usage sample: $ busybox wget -O - -S -q --method=PUT \ --body-data="trololo" \ --header="Content-Type: text/plain" \ http://localhost:8080/cgi-bin/echo.sh HTTP/1.1 200 OK Content-Length: 7 Content-Type: text/html REQUEST_METHOD: PUT CONTENT_TYPE: text/plain CONTENT_LENGTH: trololo To avoid clashes with the --post-data/file options the --body-data/file must be used. But internally they stored to the same post_data and post_data fields. The GNU wget does similar. GNU wget shows an error on mutual usage of the options and we can do this too: if (option_mask32 & WGET_OPT_METHOD) { // the G.method already was populated from getopt() if (option_mask32 & WGET_OPT_POST) { bb_simple_error_msg_and_die("--method expects data through --body-data/file\n"); } But this bloats 331 bytes so let's just skip the error message. function old new delta static.wget_longopts 185 218 +33 packed_usage 2310 2331 +21 wget_main 2824 2841 +17 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 71/0) Total: 71 bytes text data bss dec hex filename 177452 3971 1688 183111 2cb47 busybox_old 177523 3971 1688 183182 2cb8e busybox_unstripped Signed-off-by: Sergey Ponomarev --- networking/wget.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index 0006f8807..9e7e16484 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -136,7 +136,9 @@ //usage:#define wget_trivial_usage //usage: IF_FEATURE_WGET_LONG_OPTIONS( //usage: "[-cqS] [--spider] [-O FILE] [-o LOGFILE] [--header STR]\n" -//usage: " [--post-data STR | --post-file FILE] [-Y on/off]\n" +//usage: " [--post-data=STR | --post-file=FILE]\n" +//usage: " [--method=METHOD] [--body-data=STR | --body-file=FILE]\n" +//usage: " [-Y on/off]\n" /* Since we ignore these opts, we don't show them in --help */ /* //usage: " [--no-cache] [--passive-ftp] [-t TRIES]" */ /* //usage: " [-nv] [-nc] [-nH] [-np]" */ @@ -303,6 +305,9 @@ enum { WGET_OPT_SPIDER = (1 << 13) * ENABLE_FEATURE_WGET_LONG_OPTIONS, WGET_OPT_NO_CHECK_CERT = (1 << 14) * ENABLE_FEATURE_WGET_LONG_OPTIONS, WGET_OPT_POST_FILE = (1 << 15) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + WGET_OPT_METHOD = (1 << 16) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + WGET_OPT_BODY_DATA = (1 << 17) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + WGET_OPT_BODY_FILE = (1 << 18) * ENABLE_FEATURE_WGET_LONG_OPTIONS, /* hijack this bit for other than opts purposes: */ WGET_NO_FTRUNCATE = (1 << 31) }; @@ -1260,7 +1265,7 @@ static void download_one_url(const char *url) fputs(G.extra_headers, sfp); } - if (option_mask32 & WGET_OPT_POST_FILE) { + if (option_mask32 & WGET_OPT_POST_FILE || option_mask32 & WGET_OPT_BODY_FILE) { int fd = xopen_stdin(G.post_file); G.post_data = xmalloc_read(fd, NULL); close(fd); @@ -1515,6 +1520,9 @@ IF_DESKTOP( "tries\0" Required_argument "t") "spider\0" No_argument "\xfd" "no-check-certificate\0" No_argument "\xfc" "post-file\0" Required_argument "\xfb" + "method\0" Required_argument "\xf1" + "body-data\0" Required_argument "\xf2" + "body-file\0" Required_argument "\xf3" /* Ignored (we always use PASV): */ IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") /* Ignored (we don't support caching) */ @@ -1571,6 +1579,9 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_file) + IF_FEATURE_WGET_LONG_OPTIONS(, &G.method) + IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) // body-data will be stored to post_data + IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_file) // body-file will be stored to post_file ); #if 0 /* option bits debug */ if (option_mask32 & WGET_OPT_RETRIES) bb_error_msg("-t NUM"); @@ -1580,11 +1591,16 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider"); if (option_mask32 & WGET_OPT_NO_CHECK_CERT) bb_error_msg("--no-check-certificate"); if (option_mask32 & WGET_OPT_POST_FILE) bb_error_msg("--post-file"); + if (option_mask32 & WGET_OPT_METHOD) bb_error_msg("--method"); + if (option_mask32 & WGET_OPT_BODY_DATA) bb_error_msg("--body-data"); + if (option_mask32 & WGET_OPT_BODY_FILE) bb_error_msg("--body-file"); exit(0); #endif argv += optind; - if (option_mask32 & WGET_OPT_POST) { + if (option_mask32 & WGET_OPT_METHOD) { + // the G.method already was populated from getopt() + } else if (option_mask32 & WGET_OPT_POST) { G.method = "POST"; } else if (option_mask32 & WGET_OPT_SPIDER) { /* Note: GNU wget --spider sends a HEAD and if it failed repeats with a GET */ -- 2.34.1 From stokito at gmail.com Sun May 8 20:15:18 2022 From: stokito at gmail.com (Sergey Ponomarev) Date: Sun, 8 May 2022 23:15:18 +0300 Subject: [PATCH] wget: Support --user and --password options Message-ID: <20220508201518.124970-1-stokito@gmail.com> GNU wget and OpenWrt uclient allows to pass user/pass via dedicated options. For BB wget we must adjust a URL. The patch adds the options to improve compatibility and experience. function old new delta usage_messages 3914 3977 +63 parse_url 347 397 +50 static.wget_longopts 185 203 +18 wget_main 2680 2693 +13 retrieve_file_data 623 629 +6 get_sanitized_hdr 176 179 +3 fgets_trim_sanitize 166 169 +3 base64enc 56 59 +3 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 8/0 up/down: 159/0) Total: 159 bytes text data bss dec hex filename 164088 3747 1688 169523 29633 busybox_old 164247 3747 1688 169682 296d2 busybox_unstripped Signed-off-by: Sergey Ponomarev --- networking/wget.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/networking/wget.c b/networking/wget.c index 36461e489..797c66b47 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -152,6 +152,10 @@ //usage: "\n --header STR Add STR (of form 'header: value') to headers" //usage: "\n --post-data STR Send STR using POST method" //usage: "\n --post-file FILE Send FILE using POST method" +//usage: IF_FEATURE_WGET_AUTHENTICATION( +//usage: "\n --user=USER User (Basic Auth / FTP)" +//usage: "\n --password=PASS Password" +//usage: ) //usage: IF_FEATURE_WGET_OPENSSL( //usage: "\n --no-check-certificate Don't validate the server's certificate" //usage: ) @@ -255,6 +259,10 @@ struct globals { char *post_file; char *extra_headers; unsigned char user_headers; /* Headers mentioned by the user */ +#if ENABLE_FEATURE_WGET_AUTHENTICATION + char *user; + char *password; +#endif #endif char *fname_out; /* where to direct output (-O) */ char *fname_log; /* where to direct log (-o) */ @@ -302,6 +310,8 @@ enum { WGET_OPT_SPIDER = (1 << 13) * ENABLE_FEATURE_WGET_LONG_OPTIONS, WGET_OPT_NO_CHECK_CERT = (1 << 14) * ENABLE_FEATURE_WGET_LONG_OPTIONS, WGET_OPT_POST_FILE = (1 << 15) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + WGET_OPT_USER = (1 << 16) * ENABLE_FEATURE_WGET_LONG_OPTIONS, + WGET_OPT_PASSWORD = (1 << 17) * ENABLE_FEATURE_WGET_LONG_OPTIONS, /* hijack this bit for other than opts purposes: */ WGET_NO_FTRUNCATE = (1 << 31) }; @@ -617,6 +627,11 @@ static void parse_url(const char *src_url, struct host_info *h) h->user = xstrdup(percent_decode_in_place(h->host, /*strict:*/ 0)); h->host = sp + 1; } +#if ENABLE_FEATURE_WGET_LONG_OPTIONS && ENABLE_FEATURE_WGET_AUTHENTICATION + if (h->user == NULL && G.user != NULL && G.password != NULL) { + h->user = xasprintf("%s:%s", G.user, G.password); + } +#endif /* else: h->user remains NULL, or as set by original request * before redirect (if we are here after a redirect). */ @@ -1521,6 +1536,9 @@ IF_DESKTOP( "no-verbose\0" No_argument "\xf0") IF_DESKTOP( "no-clobber\0" No_argument "\xf0") IF_DESKTOP( "no-host-directories\0" No_argument "\xf0") IF_DESKTOP( "no-parent\0" No_argument "\xf0") +IF_FEATURE_WGET_AUTHENTICATION( + "user\0" Required_argument "\xf1" + "password\0" Required_argument "\xf2") ; # define GETOPT32 getopt32long # define LONGOPTS ,wget_longopts @@ -1569,6 +1587,8 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_file) + IF_FEATURE_WGET_LONG_OPTIONS(IF_FEATURE_WGET_AUTHENTICATION(, &G.user)) + IF_FEATURE_WGET_LONG_OPTIONS(IF_FEATURE_WGET_AUTHENTICATION(, &G.password)) ); #if 0 /* option bits debug */ if (option_mask32 & WGET_OPT_RETRIES) bb_error_msg("-t NUM"); -- 2.34.1 From mlichvar at redhat.com Mon May 9 13:05:44 2022 From: mlichvar at redhat.com (Miroslav Lichvar) Date: Mon, 9 May 2022 15:05:44 +0200 Subject: [PATCH] ntpd: make NTP client Y2036-ready Message-ID: <20220509130544.2038763-1-mlichvar@redhat.com> The 32-bit integer part of the NTP timestamp overflows in year 2036, which starts the second NTP era. Modify the timestamp conversion to shift values between 1900-1970 (in the first era) to the second era to enable the client to synchronize correctly until year 2106 (assuming 64-bit time_t). Signed-off-by: Miroslav Lichvar --- networking/ntpd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/networking/ntpd.c b/networking/ntpd.c index 204e1d7c2..d0c61b4bb 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -565,6 +565,9 @@ lfp_to_d(l_fixedpt_t lfp) lfp.int_partl = ntohl(lfp.int_partl); lfp.fractionl = ntohl(lfp.fractionl); ret = (double)lfp.int_partl + ((double)lfp.fractionl / UINT_MAX); + /* Shift timestamps before 1970 to the second NTP era (2036-2106) */ + if (lfp.int_partl < OFFSET_1900_1970) + ret += (double)UINT_MAX + 1.0; return ret; } static NOINLINE double -- 2.35.1 From explorer09 at gmail.com Mon May 9 16:50:11 2022 From: explorer09 at gmail.com (Kang-Che Sung) Date: Tue, 10 May 2022 00:50:11 +0800 Subject: [PATCH] ntpd: make NTP client Y2036-ready In-Reply-To: <20220509130544.2038763-1-mlichvar@redhat.com> References: <20220509130544.2038763-1-mlichvar@redhat.com> Message-ID: On Monday, May 9, 2022, Miroslav Lichvar wrote: > The 32-bit integer part of the NTP timestamp overflows in year 2036, > which starts the second NTP era. > > Modify the timestamp conversion to shift values between 1900-1970 (in > the first era) to the second era to enable the client to synchronize > correctly until year 2106 (assuming 64-bit time_t). > > Signed-off-by: Miroslav Lichvar Is this the right fix where there is no check on the era number? -------------- next part -------------- An HTML attachment was scrubbed... URL: From mlichvar at redhat.com Mon May 9 17:14:19 2022 From: mlichvar at redhat.com (Miroslav Lichvar) Date: Mon, 9 May 2022 19:14:19 +0200 Subject: [PATCH] ntpd: make NTP client Y2036-ready In-Reply-To: References: <20220509130544.2038763-1-mlichvar@redhat.com> Message-ID: On Tue, May 10, 2022 at 12:50:11AM +0800, Kang-Che Sung wrote: > On Monday, May 9, 2022, Miroslav Lichvar wrote: > > The 32-bit integer part of the NTP timestamp overflows in year 2036, > > which starts the second NTP era. > > > > Modify the timestamp conversion to shift values between 1900-1970 (in > > the first era) to the second era to enable the client to synchronize > > correctly until year 2106 (assuming 64-bit time_t). > > > > Signed-off-by: Miroslav Lichvar > > Is this the right fix where there is no check on the era number? What exactly would you want to check? The era number is not needed in the conversion until it's exchanged in the protocol (as was proposed for NTPv5). For now, it can only cover an interval of 2**32 seconds convering some part of two adjacent eras. -- Miroslav Lichvar From ben at bvnf.space Tue May 10 13:30:07 2022 From: ben at bvnf.space (Ben Fuller) Date: Tue, 10 May 2022 14:30:07 +0100 Subject: [PATCH] su: support numeric UIDs with a -n flag Message-ID: <20220510133007.n7igtreurt6fdwoh@t480> Signed-off-by: Ben Fuller --- Hi, I want to be able to use UIDs rather than usernames in order to handle cases where some POSIX tools truncate usernames at 8 characters. This patch adds a `-n` flag to su, which causes it to interpret the given USER as a numeric UID rather than a username. POSIX defines uid_t as an integer type without specifying if it is signed, but most libcs (at least musl and glibc) have uid_t as unsigned. Therefore, I used bb_strtou to parse the UID and account for overflow. Thanks, Ben loginutils/su.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/loginutils/su.c b/loginutils/su.c index 6efe1981a..b93801413 100644 --- a/loginutils/su.c +++ b/loginutils/su.c @@ -35,10 +35,11 @@ //kbuild:lib-$(CONFIG_SU) += su.o //usage:#define su_trivial_usage -//usage: "[-lmp] [-s SH] [-] [USER [FILE ARGS | -c 'CMD' [ARG0 ARGS]]]" +//usage: "[-lnmp] [-s SH] [-] [USER [FILE ARGS | -c 'CMD' [ARG0 ARGS]]]" //usage:#define su_full_usage "\n\n" //usage: "Run shell under USER (by default, root)\n" //usage: "\n -,-l Clear environment, go to home dir, run shell as login shell" +//usage: "\n -n Interpret USER as numeric ID" //usage: "\n -p,-m Do not set new $HOME, $SHELL, $USER, $LOGNAME" //usage: "\n -c CMD Command to pass to 'sh -c'" //usage: "\n -s SH Shell to use instead of user's default" @@ -69,6 +70,7 @@ static int restricted_shell(const char *shell) #define SU_OPT_mp (3) #define SU_OPT_l (4) +#define SU_OPT_n (32) int su_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int su_main(int argc UNUSED_PARAM, char **argv) @@ -91,7 +93,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) * ARGS starting with dash will be treated as su options, * not passed to shell. (Tested on util-linux 2.28). */ - flags = getopt32(argv, "mplc:s:", &opt_command, &opt_shell); + flags = getopt32(argv, "mplc:s:n", &opt_command, &opt_shell); argv += optind; if (argv[0] && LONE_DASH(argv[0])) { @@ -103,6 +105,8 @@ int su_main(int argc UNUSED_PARAM, char **argv) if (argv[0]) { opt_username = argv[0]; argv++; + } else if (flags & SU_OPT_n) { + opt_username = "0"; } tty = xmalloc_ttyname(STDIN_FILENO); @@ -126,7 +130,16 @@ int su_main(int argc UNUSED_PARAM, char **argv) openlog(applet_name, 0, LOG_AUTH); } - pw = xgetpwnam(opt_username); + if (flags & SU_OPT_n) { + unsigned long uid; + errno = 0; + uid = bb_strtou(opt_username, NULL, 10); + if (errno == ERANGE || uid == ULLONG_MAX || uid > UINT_MAX - 1) + bb_error_msg_and_die("invalid uid %s", opt_username); + pw = xgetpwuid((uid_t)uid); + } else { + pw = xgetpwnam(opt_username); + } r = 1; if (cur_uid != 0) -- 2.36.1 From mjt at tls.msk.ru Tue May 10 13:53:14 2022 From: mjt at tls.msk.ru (Michael Tokarev) Date: Tue, 10 May 2022 16:53:14 +0300 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: <20220510133007.n7igtreurt6fdwoh@t480> References: <20220510133007.n7igtreurt6fdwoh@t480> Message-ID: <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> 10.05.2022 16:30, Ben Fuller wrote: > Signed-off-by: Ben Fuller > --- > Hi, > > I want to be able to use UIDs rather than usernames in order to handle > cases where some POSIX tools truncate usernames at 8 characters. This > patch adds a `-n` flag to su, which causes it to interpret the given > USER as a numeric UID rather than a username. Do you really want su there? Maybe setpriv will better suit your needs? Thanks, /mjt From mjt at tls.msk.ru Tue May 10 14:06:35 2022 From: mjt at tls.msk.ru (Michael Tokarev) Date: Tue, 10 May 2022 17:06:35 +0300 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> Message-ID: 10.05.2022 16:53, Michael Tokarev wrote: .. > Do you really want su there? Maybe setpriv will better suit your needs? Grrr, and setpriv in busybox does not support user/group settings at all... ;) Why I asked: it is uncommon for su to accept numeric UIDs, - be it busybox or anything else. Also, su interface is quite strange in the arguments handling. /mjt From ben at bvnf.space Tue May 10 14:23:12 2022 From: ben at bvnf.space (Ben Fuller) Date: Tue, 10 May 2022 15:23:12 +0100 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> Message-ID: <20220510142312.jdbxo4gqvzzfdinc@t480> On Tue, May 10, 2022 at 05:06:35PM +0300, Michael Tokarev wrote: > 10.05.2022 16:53, Michael Tokarev wrote: > .. > > Do you really want su there? Maybe setpriv will better suit your needs? > > Grrr, and setpriv in busybox does not support user/group settings at all... ;) Ah, that's why I didn't notice setpriv. > Why I asked: it is uncommon for su to accept numeric UIDs, - be it busybox > or anything else. Also, su interface is quite strange in the arguments > handling. You're right. I am a part of a community distro which uses busybox by default, and we need something to be able to change privileges to an arbitrary user, but it is not portable to expect a tool to print all of a username longer than 8 characters. Using the UID is more reliable. There is no standard for su, but my hope with this patch is for there to be one more tool with which our problem can be solved; it's nice to have more options. Ben From shane.880088.supw at gmail.com Tue May 10 15:08:08 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 20:38:08 +0530 Subject: [PATCH v4r 0/2] less: fully implement -R Message-ID: <20220510150810.10594-1-shane.880088.supw@gmail.com> Reposting. Added signed-off line. The switch was half-implemented earlier and it only used to trim escape sequences. This patch series implements the feature fully i.e. makes it emit color (SGR) sequences raw, and fixes other behaviour around it. Bloatcheck: function old new delta buffer_print 734 926 +192 .rodata 100509 100539 +30 packed_usage 34508 34506 -2 read_lines 896 810 -86 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/2 up/down: 222/-88) Total: 134 bytes text data bss dec hex filename 1043376 16435 1816 1061627 1032fb busybox_old 1043510 16435 1816 1061761 103381 busybox_unstripped Changes from v1: - count_colctrl does better validation for SGR sequences Changes from v2: - fixed corrupted patches (accidentally edited before sending) - fix code style Changes from v3: - fixed regex in commit message From shane.880088.supw at gmail.com Tue May 10 15:08:09 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 20:38:09 +0530 Subject: [PATCH v4r 1/2] less: fully implement -R and print color escapes In-Reply-To: <20220510150810.10594-1-shane.880088.supw@gmail.com> References: <20220510150810.10594-1-shane.880088.supw@gmail.com> Message-ID: <20220510150810.10594-2-shane.880088.supw@gmail.com> The earlier implementation used to just strip color escapes. This makes them output 'raw', coloring the screen. Like less, it assumes that the codes don't move the cursor. Emits NORMAL at newlines, like less, to deal with malformed input. count_colctrl() counts the number of chars in the next ANSI-SGR [1] escape, essentially matching for "\033\[[0-9;]*m". Doesn't work in regex find mode, but neither does the normal escape highlighting. [1] https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters Signed-off-by: FriendlyNeighborhoodShane --- miscutils/less.c | 54 +++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 8a0525cb7..1e2c4c5cf 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -139,7 +139,7 @@ //usage: "\n -S Truncate long lines" //usage: ) //usage: IF_FEATURE_LESS_RAW( -//usage: "\n -R Remove color escape codes in input" +//usage: "\n -R Output 'raw' color escape codes" //usage: ) //usage: "\n -~ Suppress ~s displayed past EOF" @@ -229,9 +229,6 @@ struct globals { regex_t pattern; smallint pattern_valid; #endif -#if ENABLE_FEATURE_LESS_RAW - smallint in_escape; -#endif #if ENABLE_FEATURE_LESS_ASK_TERMINAL smallint winsize_err; #endif @@ -541,26 +538,6 @@ static void read_lines(void) *--p = '\0'; continue; } -#if ENABLE_FEATURE_LESS_RAW - if (option_mask32 & FLAG_R) { - if (c == '\033') - goto discard; - if (G.in_escape) { - if (isdigit(c) - || c == '[' - || c == ';' - || c == 'm' - ) { - discard: - G.in_escape = (c != 'm'); - readpos++; - continue; - } - /* Hmm, unexpected end of "ESC [ N ; N m" sequence */ - G.in_escape = 0; - } - } -#endif { size_t new_last_line_pos = last_line_pos + 1; if (c == '\t') { @@ -864,13 +841,34 @@ static void print_found(const char *line) void print_found(const char *line); #endif +static size_t count_colctrl(const char *str) +{ + size_t n; + if (str[1] == '[' + && (n = strspn(str+2, "0123456789;")) >= 0 // always true + && str[n+2] == 'm') + return n+3; + return 0; +} + static void print_ascii(const char *str) { char buf[width+1]; char *p; size_t n; +#if ENABLE_FEATURE_LESS_RAW + size_t esc = 0; +#endif while (*str) { +#if ENABLE_FEATURE_LESS_RAW + if (esc) { + printf("%.*s", (int) esc, str); + str += esc; + esc = 0; + continue; + } +#endif n = strcspn(str, controls); if (n) { if (!str[n]) break; @@ -886,6 +884,13 @@ static void print_ascii(const char *str) /* VT100's CSI, aka Meta-ESC. Who's inventor? */ /* I want to know who committed this sin */ *p++ = '{'; +#if ENABLE_FEATURE_LESS_RAW + else if ((option_mask32 & FLAG_R) + && *str == '\033' + && (esc = count_colctrl(str))) { + break; // flush collected control chars + } +#endif else *p++ = ctrlconv[(unsigned char)*str]; str++; @@ -894,6 +899,7 @@ static void print_ascii(const char *str) print_hilite(buf); } puts(str); + printf(NORMAL); } /* Print the buffer */ -- 2.36.1 From shane.880088.supw at gmail.com Tue May 10 15:08:10 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 20:38:10 +0530 Subject: [PATCH v4r 2/2] less: replace most uses of NORMAL escape with UNHIGHLIGHT In-Reply-To: <20220510150810.10594-1-shane.880088.supw@gmail.com> References: <20220510150810.10594-1-shane.880088.supw@gmail.com> Message-ID: <20220510150810.10594-3-shane.880088.supw@gmail.com> Emmitting NORMAL resets the entire SGR state of the terminal, which includes colors. We don't want that now, since those sequences can come between a colored line, and this would cut the coloring short. UNHIGHLIGHT is a dedicated code to just flip the HIGHLIGHT (invert) bit to off, and is a better complement anywhere after HIGHLIGHT. NORMAL is still used wherever appropriate, e.g. at the end of lines to reset color state. This cannot handle the case when there is a HIGHLIGHT sequence in the input itself, and any such highlighting can be cut short by less-emmitted highlight sequences. Avoiding that probably requires looking at the codes and keeping state. Testing shows that even greenwood less doesn't bother to do that. Signed-off-by: FriendlyNeighborhoodShane --- miscutils/less.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 1e2c4c5cf..2f618ba34 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -155,6 +155,7 @@ #define ESC "\033" /* The escape codes for highlighted and normal text */ #define HIGHLIGHT ESC"[7m" +#define UNHIGHLIGHT ESC"[27m" #define NORMAL ESC"[m" /* The escape code to home and clear to the end of screen */ #define CLEAR ESC"[H"ESC"[J" @@ -312,13 +313,13 @@ static void clear_line(void) static void print_hilite(const char *str) { - printf(HIGHLIGHT"%s"NORMAL, str); + printf(HIGHLIGHT"%s"UNHIGHLIGHT, str); } static void print_statusline(const char *str) { clear_line(); - printf(HIGHLIGHT"%.*s"NORMAL, width - 1, str); + printf(HIGHLIGHT"%.*s"UNHIGHLIGHT, width - 1, str); } /* Exit the program gracefully */ @@ -710,7 +711,7 @@ static void m_status_print(void) percent = (100 * last + num_lines/2) / num_lines; printf(" %i%%", percent <= 100 ? percent : 100); } - printf(NORMAL); + printf(UNHIGHLIGHT); } #endif @@ -740,7 +741,7 @@ static void status_print(void) if (!cur_fline) p = filename; if (num_files > 1) { - printf(HIGHLIGHT"%s (file %i of %i)"NORMAL, + printf(HIGHLIGHT"%s (file %i of %i)"UNHIGHLIGHT, p, current_file, num_files); return; } @@ -807,7 +808,7 @@ static void print_found(const char *line) /* buf[] holds quarantined version of str */ /* Each part of the line that matches has the HIGHLIGHT - * and NORMAL escape sequences placed around it. + * and UNHIGHLIGHT escape sequences placed around it. * NB: we regex against line, but insert text * from quarantined copy (buf[]) */ str = buf; @@ -816,7 +817,7 @@ static void print_found(const char *line) goto start; while (match_status == 0) { - char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, + char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"UNHIGHLIGHT, growline ? growline : "", (int)match_structs.rm_so, str, (int)(match_structs.rm_eo - match_structs.rm_so), @@ -1551,7 +1552,7 @@ static void show_flag_status(void) } clear_line(); - printf(HIGHLIGHT"The status of the flag is: %u"NORMAL, flag_val != 0); + printf(HIGHLIGHT"The status of the flag is: %u"UNHIGHLIGHT, flag_val != 0); } #endif -- 2.36.1 From ska-dietlibc at skarnet.org Tue May 10 15:12:31 2022 From: ska-dietlibc at skarnet.org (Laurent Bercot) Date: Tue, 10 May 2022 15:12:31 +0000 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: <20220510142312.jdbxo4gqvzzfdinc@t480> References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> <20220510142312.jdbxo4gqvzzfdinc@t480> Message-ID: >You're right. I am a part of a community distro which uses busybox by >default, and we need something to be able to change privileges to an >arbitrary user, but it is not portable to expect a tool to print all of >a username longer than 8 characters. Using the UID is more reliable. >There is no standard for su, but my hope with this patch is for there >to be one more tool with which our problem can be solved; it's nice to >have more options. As much as I understand and sympathize with your plight - I'm the first one to complain about the low quality of "traditional" low-level userspace on Linux - I don't think your approach is the right solution. "su" has - more or less - a known interface, and is - more or less - usable on every distribution; a script using su will generally be portable from one distro to another. Adding an option to busybox su that is not supported by util-linux su destroys that guarantee, and fragments the user space even more than it already is. "su -n" will only be usable with busybox, so to an external viewer, it's more confusing than anything else why the tool is called su. Only use existing tool names when you provide an interface that's exactly compatible with the existing tool; else you will weaken the reach and usefulness of the tool. If you need new functionality, implement the functionality as a separate tool, that can take inspiration from the existing tool for its name and interface, but you should call it ben-su rather than su. Introducing a divergence in busybox su is harmful in the long run. (This is why GNU coreutils is so difficult to replace: it has embraced and extended, and now the world is full of scripts relying on cp --useless-options that every potential replacement has to implement.) For non-interactive applications of su with numeric uids, may I suggest https://skarnet.org/software/s6/s6-applyuidgid.html ? -- Laurent From shane.880088.supw at gmail.com Tue May 10 15:38:20 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 21:08:20 +0530 Subject: [PATCH v5 0/2] less: fully implement -R Message-ID: <20220510153822.42554-1-shane.880088.supw@gmail.com> The switch was half-implemented earlier and it only used to trim escape sequences. This patch series implements the feature fully i.e. makes it emit color (SGR) sequences raw, and fixes other behaviour around it. Bloatcheck: function old new delta buffer_print 734 884 +150 .rodata 100509 100527 +18 packed_usage 34508 34506 -2 read_lines 896 810 -86 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/2 up/down: 168/-88) Total: 80 bytes Changes from v4: - replace strspn with manual loop for size reduction - fix formatting mistakes Changes from v3: - fixed regex in commit message Changes from v2: - fixed corrupted patches (accidentally edited before sending) - fix code style Changes from v1: - count_colctrl does better validation for SGR sequences From shane.880088.supw at gmail.com Tue May 10 15:38:21 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 21:08:21 +0530 Subject: [PATCH v5 1/2] less: fully implement -R and print color escapes In-Reply-To: <20220510153822.42554-1-shane.880088.supw@gmail.com> References: <20220510153822.42554-1-shane.880088.supw@gmail.com> Message-ID: <20220510153822.42554-2-shane.880088.supw@gmail.com> The earlier implementation used to just strip color escapes. This makes them output 'raw', coloring the screen. Like less, it assumes that the codes don't move the cursor. Emits NORMAL at newlines, like less, to deal with malformed input. count_colctrl() counts the number of chars in the next ANSI-SGR [1] escape, essentially matching for "\033\[[0-9;]*m". Doesn't work in regex find mode, but neither does the normal escape highlighting. [1] https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters function old new delta buffer_print 734 884 +150 packed_usage 34508 34506 -2 read_lines 896 810 -86 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 150/-88) Total: 62 bytes Signed-off-by: FriendlyNeighborhoodShane --- miscutils/less.c | 56 +++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 8a0525cb7..cad37aaac 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -139,7 +139,7 @@ //usage: "\n -S Truncate long lines" //usage: ) //usage: IF_FEATURE_LESS_RAW( -//usage: "\n -R Remove color escape codes in input" +//usage: "\n -R Output 'raw' color escape codes" //usage: ) //usage: "\n -~ Suppress ~s displayed past EOF" @@ -229,9 +229,6 @@ struct globals { regex_t pattern; smallint pattern_valid; #endif -#if ENABLE_FEATURE_LESS_RAW - smallint in_escape; -#endif #if ENABLE_FEATURE_LESS_ASK_TERMINAL smallint winsize_err; #endif @@ -541,26 +538,6 @@ static void read_lines(void) *--p = '\0'; continue; } -#if ENABLE_FEATURE_LESS_RAW - if (option_mask32 & FLAG_R) { - if (c == '\033') - goto discard; - if (G.in_escape) { - if (isdigit(c) - || c == '[' - || c == ';' - || c == 'm' - ) { - discard: - G.in_escape = (c != 'm'); - readpos++; - continue; - } - /* Hmm, unexpected end of "ESC [ N ; N m" sequence */ - G.in_escape = 0; - } - } -#endif { size_t new_last_line_pos = last_line_pos + 1; if (c == '\t') { @@ -864,13 +841,36 @@ static void print_found(const char *line) void print_found(const char *line); #endif +static size_t count_colctrl(const char *str) +{ + size_t n = 0; + if (str[1] == '[') { + while (isdigit(*(str+2+n)) || *(str+2+n) == ';') + n++; + if (str[n+2] == 'm') + return n+3; + } + return 0; +} + static void print_ascii(const char *str) { char buf[width+1]; char *p; size_t n; +#if ENABLE_FEATURE_LESS_RAW + size_t esc = 0; +#endif while (*str) { +#if ENABLE_FEATURE_LESS_RAW + if (esc) { + printf("%.*s", (int) esc, str); + str += esc; + esc = 0; + continue; + } +#endif n = strcspn(str, controls); if (n) { if (!str[n]) break; @@ -886,6 +886,13 @@ static void print_ascii(const char *str) /* VT100's CSI, aka Meta-ESC. Who's inventor? */ /* I want to know who committed this sin */ *p++ = '{'; +#if ENABLE_FEATURE_LESS_RAW + else if ((option_mask32 & FLAG_R) + && *str == '\033' + && (esc = count_colctrl(str))) { + break; // flush collected control chars + } +#endif else *p++ = ctrlconv[(unsigned char)*str]; str++; @@ -894,6 +901,7 @@ static void print_ascii(const char *str) print_hilite(buf); } puts(str); + printf(NORMAL); } /* Print the buffer */ -- 2.36.1 From shane.880088.supw at gmail.com Tue May 10 15:38:22 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 21:08:22 +0530 Subject: [PATCH v5 2/2] less: replace most uses of NORMAL escape with UNHIGHLIGHT In-Reply-To: <20220510153822.42554-1-shane.880088.supw@gmail.com> References: <20220510153822.42554-1-shane.880088.supw@gmail.com> Message-ID: <20220510153822.42554-3-shane.880088.supw@gmail.com> Emmitting NORMAL resets the entire SGR state of the terminal, which includes colors. We don't want that now, since those sequences can come between a colored line, and this would cut the coloring short. UNHIGHLIGHT is a dedicated code to just flip the HIGHLIGHT (invert) bit to off, and is a better complement anywhere after HIGHLIGHT. NORMAL is still used wherever appropriate, e.g. at the end of lines to reset color state. This cannot handle the case when there is a HIGHLIGHT sequence in the input itself, and any such highlighting can be cut short by less-emmitted highlight sequences. Avoiding that probably requires looking at the codes and keeping state. Testing shows that even greenwood less doesn't bother to do that. function old new delta .rodata 100509 100527 +18 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 18/0) Total: 18 bytes Signed-off-by: FriendlyNeighborhoodShane --- miscutils/less.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index cad37aaac..5e8a87ca5 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -155,6 +155,7 @@ #define ESC "\033" /* The escape codes for highlighted and normal text */ #define HIGHLIGHT ESC"[7m" +#define UNHIGHLIGHT ESC"[27m" #define NORMAL ESC"[m" /* The escape code to home and clear to the end of screen */ #define CLEAR ESC"[H"ESC"[J" @@ -312,13 +313,13 @@ static void clear_line(void) static void print_hilite(const char *str) { - printf(HIGHLIGHT"%s"NORMAL, str); + printf(HIGHLIGHT"%s"UNHIGHLIGHT, str); } static void print_statusline(const char *str) { clear_line(); - printf(HIGHLIGHT"%.*s"NORMAL, width - 1, str); + printf(HIGHLIGHT"%.*s"UNHIGHLIGHT, width - 1, str); } /* Exit the program gracefully */ @@ -710,7 +711,7 @@ static void m_status_print(void) percent = (100 * last + num_lines/2) / num_lines; printf(" %i%%", percent <= 100 ? percent : 100); } - printf(NORMAL); + printf(UNHIGHLIGHT); } #endif @@ -740,7 +741,7 @@ static void status_print(void) if (!cur_fline) p = filename; if (num_files > 1) { - printf(HIGHLIGHT"%s (file %i of %i)"NORMAL, + printf(HIGHLIGHT"%s (file %i of %i)"UNHIGHLIGHT, p, current_file, num_files); return; } @@ -807,7 +808,7 @@ static void print_found(const char *line) /* buf[] holds quarantined version of str */ /* Each part of the line that matches has the HIGHLIGHT - * and NORMAL escape sequences placed around it. + * and UNHIGHLIGHT escape sequences placed around it. * NB: we regex against line, but insert text * from quarantined copy (buf[]) */ str = buf; @@ -816,7 +817,7 @@ static void print_found(const char *line) goto start; while (match_status == 0) { - char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, + char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"UNHIGHLIGHT, growline ? growline : "", (int)match_structs.rm_so, str, (int)(match_structs.rm_eo - match_structs.rm_so), @@ -1553,7 +1554,7 @@ static void show_flag_status(void) } clear_line(); - printf(HIGHLIGHT"The status of the flag is: %u"NORMAL, flag_val != 0); + printf(HIGHLIGHT"The status of the flag is: %u"UNHIGHLIGHT, flag_val != 0); } #endif -- 2.36.1 From shane.880088.supw at gmail.com Tue May 10 16:10:13 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 21:40:13 +0530 Subject: [PATCH v6 0/2] less: fully implement -R Message-ID: <20220510161015.79220-1-shane.880088.supw@gmail.com> The switch was half-implemented earlier and it only used to trim escape sequences. This patch series implements the feature fully i.e. makes it emit color (SGR) sequences raw, and fixes other behaviour around it. function old new delta buffer_print 734 893 +159 .rodata 100509 100527 +18 packed_usage 34508 34506 -2 read_lines 896 810 -86 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/2 up/down: 177/-88) Total: 89 bytes Changes from v5: - fix build warnings with the config turned off - reduce size cost of patch with config turned off, at cost of a little more size with it turned on. Changes from v4: - replace strspn with manual loop for size reduction - fix formatting mistakes Changes from v3: - fixed regex in commit message Changes from v2: - fixed corrupted patches (accidentally edited before sending) - fix code style Changes from v1: - count_colctrl does better validation for SGR sequences From shane.880088.supw at gmail.com Tue May 10 16:10:14 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 21:40:14 +0530 Subject: [PATCH v6 1/2] less: fully implement -R and print color escapes In-Reply-To: <20220510161015.79220-1-shane.880088.supw@gmail.com> References: <20220510161015.79220-1-shane.880088.supw@gmail.com> Message-ID: <20220510161015.79220-2-shane.880088.supw@gmail.com> The earlier implementation used to just strip color escapes. This makes them output 'raw', coloring the screen. Like less, it assumes that the codes don't move the cursor. Emits NORMAL at newlines, like less, to deal with malformed input. count_colctrl() counts the number of chars in the next ANSI-SGR [1] escape, essentially matching for "\033\[[0-9;]*m". Doesn't work in regex find mode, but neither does the normal escape highlighting. [1] https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters function old new delta buffer_print 734 893 +159 packed_usage 34508 34506 -2 read_lines 896 810 -86 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 159/-88) Total: 71 bytes Signed-off-by: FriendlyNeighborhoodShane --- miscutils/less.c | 61 +++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 8a0525cb7..54bec8c9f 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -139,7 +139,7 @@ //usage: "\n -S Truncate long lines" //usage: ) //usage: IF_FEATURE_LESS_RAW( -//usage: "\n -R Remove color escape codes in input" +//usage: "\n -R Output 'raw' color escape codes" //usage: ) //usage: "\n -~ Suppress ~s displayed past EOF" @@ -229,9 +229,6 @@ struct globals { regex_t pattern; smallint pattern_valid; #endif -#if ENABLE_FEATURE_LESS_RAW - smallint in_escape; -#endif #if ENABLE_FEATURE_LESS_ASK_TERMINAL smallint winsize_err; #endif @@ -541,26 +538,6 @@ static void read_lines(void) *--p = '\0'; continue; } -#if ENABLE_FEATURE_LESS_RAW - if (option_mask32 & FLAG_R) { - if (c == '\033') - goto discard; - if (G.in_escape) { - if (isdigit(c) - || c == '[' - || c == ';' - || c == 'm' - ) { - discard: - G.in_escape = (c != 'm'); - readpos++; - continue; - } - /* Hmm, unexpected end of "ESC [ N ; N m" sequence */ - G.in_escape = 0; - } - } -#endif { size_t new_last_line_pos = last_line_pos + 1; if (c == '\t') { @@ -864,13 +841,38 @@ static void print_found(const char *line) void print_found(const char *line); #endif +#if ENABLE_FEATURE_LESS_RAW +static size_t count_colctrl(const char *str) +{ + size_t n = 0; + if (str[1] == '[') { + while (isdigit(*(str+2+n)) || *(str+2+n) == ';') + n++; + if (str[n+2] == 'm') + return n+3; + } + return 0; +} +#endif + static void print_ascii(const char *str) { char buf[width+1]; char *p; size_t n; +#if ENABLE_FEATURE_LESS_RAW + size_t esc = 0; +#endif while (*str) { +#if ENABLE_FEATURE_LESS_RAW + if (esc) { + printf("%.*s", (int) esc, str); + str += esc; + esc = 0; + continue; + } +#endif n = strcspn(str, controls); if (n) { if (!str[n]) break; @@ -886,6 +888,13 @@ static void print_ascii(const char *str) /* VT100's CSI, aka Meta-ESC. Who's inventor? */ /* I want to know who committed this sin */ *p++ = '{'; +#if ENABLE_FEATURE_LESS_RAW + else if ((option_mask32 & FLAG_R) + && *str == '\033' + && (esc = count_colctrl(str))) { + break; // flush collected control chars + } +#endif else *p++ = ctrlconv[(unsigned char)*str]; str++; @@ -894,6 +903,10 @@ static void print_ascii(const char *str) print_hilite(buf); } puts(str); +#if ENABLE_FEATURE_LESS_RAW + if (option_mask32 & FLAG_R) + printf(NORMAL); +#endif } /* Print the buffer */ -- 2.36.1 From shane.880088.supw at gmail.com Tue May 10 16:10:15 2022 From: shane.880088.supw at gmail.com (FriendlyNeighborhoodShane) Date: Tue, 10 May 2022 21:40:15 +0530 Subject: [PATCH v6 2/2] less: replace most uses of NORMAL escape with UNHIGHLIGHT In-Reply-To: <20220510161015.79220-1-shane.880088.supw@gmail.com> References: <20220510161015.79220-1-shane.880088.supw@gmail.com> Message-ID: <20220510161015.79220-3-shane.880088.supw@gmail.com> Emmitting NORMAL resets the entire SGR state of the terminal, which includes colors. We don't want that now, since those sequences can come between a colored line, and this would cut the coloring short. UNHIGHLIGHT is a dedicated code to just flip the HIGHLIGHT (invert) bit to off, and is a better complement anywhere after HIGHLIGHT. NORMAL is still used wherever appropriate, e.g. at the end of lines to reset color state. This cannot handle the case when there is a HIGHLIGHT sequence in the input itself, and any such highlighting can be cut short by less-emmitted highlight sequences. Avoiding that probably requires looking at the codes and keeping state. Testing shows that even greenwood less doesn't bother to do that. function old new delta .rodata 100509 100527 +18 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 18/0) Total: 18 bytes Signed-off-by: FriendlyNeighborhoodShane --- miscutils/less.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 54bec8c9f..bac6c5572 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -155,6 +155,7 @@ #define ESC "\033" /* The escape codes for highlighted and normal text */ #define HIGHLIGHT ESC"[7m" +#define UNHIGHLIGHT ESC"[27m" #define NORMAL ESC"[m" /* The escape code to home and clear to the end of screen */ #define CLEAR ESC"[H"ESC"[J" @@ -312,13 +313,13 @@ static void clear_line(void) static void print_hilite(const char *str) { - printf(HIGHLIGHT"%s"NORMAL, str); + printf(HIGHLIGHT"%s"UNHIGHLIGHT, str); } static void print_statusline(const char *str) { clear_line(); - printf(HIGHLIGHT"%.*s"NORMAL, width - 1, str); + printf(HIGHLIGHT"%.*s"UNHIGHLIGHT, width - 1, str); } /* Exit the program gracefully */ @@ -710,7 +711,7 @@ static void m_status_print(void) percent = (100 * last + num_lines/2) / num_lines; printf(" %i%%", percent <= 100 ? percent : 100); } - printf(NORMAL); + printf(UNHIGHLIGHT); } #endif @@ -740,7 +741,7 @@ static void status_print(void) if (!cur_fline) p = filename; if (num_files > 1) { - printf(HIGHLIGHT"%s (file %i of %i)"NORMAL, + printf(HIGHLIGHT"%s (file %i of %i)"UNHIGHLIGHT, p, current_file, num_files); return; } @@ -807,7 +808,7 @@ static void print_found(const char *line) /* buf[] holds quarantined version of str */ /* Each part of the line that matches has the HIGHLIGHT - * and NORMAL escape sequences placed around it. + * and UNHIGHLIGHT escape sequences placed around it. * NB: we regex against line, but insert text * from quarantined copy (buf[]) */ str = buf; @@ -816,7 +817,7 @@ static void print_found(const char *line) goto start; while (match_status == 0) { - char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, + char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"UNHIGHLIGHT, growline ? growline : "", (int)match_structs.rm_so, str, (int)(match_structs.rm_eo - match_structs.rm_so), @@ -1558,7 +1559,7 @@ static void show_flag_status(void) } clear_line(); - printf(HIGHLIGHT"The status of the flag is: %u"NORMAL, flag_val != 0); + printf(HIGHLIGHT"The status of the flag is: %u"UNHIGHLIGHT, flag_val != 0); } #endif -- 2.36.1 From ben at bvnf.space Tue May 10 16:48:06 2022 From: ben at bvnf.space (Ben Fuller) Date: Tue, 10 May 2022 17:48:06 +0100 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> <20220510142312.jdbxo4gqvzzfdinc@t480> Message-ID: <20220510164806.qbxb5nlf74555oew@t480> On Tue, May 10, 2022 at 15:12:31 +0000, Laurent Bercot wrote: > As much as I understand and sympathize with your plight - I'm the > first one to complain about the low quality of "traditional" low-level > userspace on Linux - I don't think your approach is the right solution. > "su" has - more or less - a known interface, and is - more or less - > usable on every distribution; a script using su will generally be > portable from one distro to another. Across Linux, this is mostly true, but across *NIX, there is less compatibility - the BSDs have a very different -c, for example. > Only use existing tool names when you provide an interface that's > exactly compatible with the existing tool; else you will weaken the > reach and usefulness of the tool. If you need new functionality, > implement the functionality as a separate tool, that can take > inspiration from the existing tool for its name and interface, but > you should call it ben-su rather than su. Introducing a divergence > in busybox su is harmful in the long run. > > (This is why GNU coreutils is so difficult to replace: it has > embraced and extended, and now the world is full of scripts relying > on cp --useless-options that every potential replacement has to > implement.) I very much agree with your points here, you've convinced me. In any case, it's a lazy way out. I think the better solution is to write a non-portable utility specifically for our use-case, and as you said, to avoid naming it similarly to existing tools. Thanks, Ben From ben at bvnf.space Tue May 10 17:24:39 2022 From: ben at bvnf.space (Ben Fuller) Date: Tue, 10 May 2022 18:24:39 +0100 Subject: patch ls to avoid username truncation? In-Reply-To: <20220510164806.qbxb5nlf74555oew@t480> References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> <20220510142312.jdbxo4gqvzzfdinc@t480> <20220510164806.qbxb5nlf74555oew@t480> Message-ID: <20220510172439.txksjnlcyk3qzth4@t480> On Tue, May 10, 2022 at 17:48:06 +0100, Ben Fuller wrote: > I think the better solution is to write a non-portable utility > specifically for our use-case, and as you said, to avoid naming it > similarly to existing tools. As an alternative, would a patch for ls to stop username truncation be accepted here? While POSIX prohibits usernames longer than 8 characters, many systems now support them. From danomimanchego123 at gmail.com Wed May 11 01:34:18 2022 From: danomimanchego123 at gmail.com (Danomi Manchego) Date: Tue, 10 May 2022 21:34:18 -0400 Subject: udhcpc6 kernel listen mode is broken Message-ID: Hello, On April 1, I sent "udhcpc6 renew message copy/paste error" email about udhcpc6 sends the wrong message ID for Renew message due to copy/paste error from IPv4 dhcpc.c. (Was DHCPREQUEST, should be D6_MSG_RENEW.) After fixing that, I found that the Renew is sent correctly, and the DHCPv6 server replies, but udhcpc6 fails to get the reply. Because there is no reply, the lease does not get extended by Renew. I found that the issue is that the udhcp_listen_socket() in socket.c (used for kernel listen mode in d6_dhcpc.c) is somewhat hard-coded for IPv4. I was able to get kernel listen mode to work by adding a new function like this to socket.c and using it in d6_dhcp.c. My udhcp6_listen_socket() differs from udhcp_listen_socket() as follows: * Use PF_INET6 instead of PF_INET. * Set IPPROTO_IPV6 / IPV6_V6ONLY socket option rather than broadcast option. * Use `struct sockaddr_in6` instead of `struct sockaddr_in`. * Use AF_INET6 instead of AF_INET. (Maybe SOCK_CLOEXEC should also be set in *both* functions when calling xsocket since udhcpc/udhcpc6 invoke external udhcpc.script, but I did not try it.) My function is pasted below. int FAST_FUNC udhcp6_listen_socket(/*uint32_t ip,*/ int port, const char *inf) { int fd; struct sockaddr_in6 addr; char *colon; log2("opening listen socket on *:%d %s", port, inf); fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); setsockopt_reuseaddr(fd); if (setsockopt_1(fd, IPPROTO_IPV6, IPV6_V6ONLY) < 0) bb_simple_perror_msg_and_die("IPPROTO_IPV6"); /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */ colon = strrchr(inf, ':'); if (colon) *colon = '\0'; if (setsockopt_bindtodevice(fd, inf)) xfunc_die(); /* warning is already printed */ if (colon) *colon = ':'; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_port = htons(port); /* addr.sin_addr.s_addr = ip; - all-zeros is INADDR_ANY */ xbind(fd, (struct sockaddr *)&addr, sizeof(addr)); return fd; } Regards, Danomi - From kkoshelev at gmail.com Wed May 11 21:47:51 2022 From: kkoshelev at gmail.com (Konstantin Koshelev) Date: Wed, 11 May 2022 14:47:51 -0700 Subject: [PATCH] add ip sub commands needed by wg-quick script Message-ID: 1. "ip rule" now supports "not" keyword. 2. "ip" command now supports arbitrary numeric routing tables above 1024. --- a/networking/libiproute/iprule.c 2021-01-01 05:30:02.000000000 -0800 +++ b/iprule.c 2022-05-10 16:32:10.781087924 -0700 @@ -19,6 +19,7 @@ /* from : */ #define FRA_SUPPRESS_IFGROUP 13 #define FRA_SUPPRESS_PREFIXLEN 14 +#define FIB_RULE_INVERT 0x00000002 #include "ip_common.h" /* #include "libbb.h" is inside */ #include "rt_names.h" @@ -31,18 +32,18 @@ /* If you add stuff here, update iprule_full_usage */ static const char keywords[] ALIGN1 = - "from\0""to\0""preference\0""order\0""priority\0" + "not\0""from\0""to\0""preference\0""order\0""priority\0" "tos\0""fwmark\0""realms\0""table\0""lookup\0" "suppress_prefixlength\0""suppress_ifgroup\0" "dev\0""iif\0""nat\0""map-to\0""type\0""help\0" ; -#define keyword_preference (keywords + sizeof("from") + sizeof("to")) +#define keyword_preference (keywords + sizeof("not") + sizeof("from") + sizeof("to")) #define keyword_fwmark (keyword_preference + sizeof("preference") + sizeof("order") + sizeof("priority") + sizeof("tos")) #define keyword_realms (keyword_fwmark + sizeof("fwmark")) #define keyword_suppress_prefixlength (keyword_realms + sizeof("realms") + sizeof("table") + sizeof("lookup")) #define keyword_suppress_ifgroup (keyword_suppress_prefixlength + sizeof("suppress_prefixlength")) enum { - ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority, + ARG_not = 1, ARG_from, ARG_to, ARG_preference, ARG_order, ARG_priority, ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_suppress_prefixlength, ARG_suppress_ifgroup, ARG_dev, ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help, @@ -78,6 +79,10 @@ printf("%u:\t", tb[RTA_PRIORITY] ? *(unsigned*)RTA_DATA(tb[RTA_PRIORITY]) : 0); + + if (r->rtm_flags & FIB_RULE_INVERT) + printf("not "); + printf("from "); if (tb[RTA_SRC]) { if (r->rtm_src_len != host_len) { @@ -230,7 +235,9 @@ key = index_in_substrings(keywords, *argv) + 1; if (key == 0) /* no match found in keywords array, bail out. */ invarg_1_to_2(*argv, applet_name); - if (key == ARG_from) { + if (key == ARG_not) { + req.r.rtm_flags |= FIB_RULE_INVERT; + } else if (key == ARG_from) { inet_prefix dst; NEXT_ARG(); get_prefix(&dst, *argv, req.r.rtm_family); --- a/networking/libiproute/rt_names.c 2021-01-01 05:30:02.000000000 -0800 +++ b/rt_names.c 2022-05-10 16:50:30.298597124 -0700 @@ -251,7 +251,14 @@ int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg) { rtnl_rttable_initialize(); - return rtnl_a2n(rtnl_rttable_tab, id, arg, 0); + if (!rtnl_a2n(rtnl_rttable_tab, id, arg, 0)) return 0; + + unsigned i = bb_strtou(arg, NULL, 0); + if (i > RT_TABLE_MAX) { + *id = i; + return 0; + } + return -1; } #endif -------------- next part -------------- An HTML attachment was scrubbed... URL: From rep.dot.nop at gmail.com Thu May 12 17:14:44 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Thu, 12 May 2022 19:14:44 +0200 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> <20220510142312.jdbxo4gqvzzfdinc@t480> Message-ID: <1B22EBFE-682A-4186-8C6E-2A36F10AFCFB@gmail.com> On 10 May 2022 17:12:31 CEST, Laurent Bercot wrote: > For non-interactive applications of su with numeric uids, may I suggest >https://skarnet.org/software/s6/s6-applyuidgid.html ? Or simply write your own trivial "execas". Maybe something like http://lists.busybox.net/pipermail/busybox/attachments/20060119/38bb8279/attachment.c HTH, From ghanson at arista.com Thu May 12 17:44:37 2022 From: ghanson at arista.com (Geoff Hanson) Date: Thu, 12 May 2022 10:44:37 -0700 Subject: udhcpc6 expects string for bootfile-param opt(60) In-Reply-To: References: <45cca76e-f2ec-078c-b60a-d1af9a8f91e7@petrovitsch.priv.at> Message-ID: Just wanted to follow up on this again. If there's no further comments on the patch, could someone consider integrating it? I've re-attached the patch. Thanks, Geoff On Wed, Feb 23, 2022 at 8:14 AM Geoff Hanson wrote: > Just following up on this patch. Are there any more comments on this? > > Thanks, > Geoff > > On Tue, Feb 8, 2022 at 11:58 AM Geoff Hanson wrote: > >> Any further feedback on this? >> >> Anything more I need to do or is what I've provided sufficient for the >> bug report? >> >> Thanks, >> Geoff >> >> On Tue, Feb 1, 2022 at 12:53 PM Geoff Hanson wrote: >> >>> Hi Bernd. Can you look at my second attachment? As part of addressing >>> the issue Xabier reported, >>> I switched to using memcpy. >>> >>> Thanks, >>> Geoff >>> >>> On Tue, Feb 1, 2022 at 12:36 PM Bernd Petrovitsch < >>> bernd at petrovitsch.priv.at> wrote: >>> >>>> -Hi all! >>>> >>>> On 01.02.2022 18:12, Geoff Hanson wrote: >>>> [...]> In most cases, there's no printf directive so this just means >>>> it's >>>> > copying the string. >>>> >>>> Using some user-provided string as a format-string opens the >>>> possibility >>>> ofexploits - since decades .... >>>> > But this would cause problems in the case where the string did >>>> contain %'s. >>>> >>>> So why just not only use strncpy(), strlcpy(), memcpy() or similar? >>>> >>>> Kind regards, >>>> Bernd >>>> >>> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- Index: busybox-1.33.1/networking/udhcp/d6_dhcpc.c =================================================================== --- busybox-1.33.1.orig/networking/udhcp/d6_dhcpc.c +++ busybox-1.33.1/networking/udhcp/d6_dhcpc.c @@ -79,7 +79,7 @@ static const struct dhcp_optflag d6_optf #endif #if ENABLE_FEATURE_UDHCPC6_RFC5970 { OPTION_STRING, D6_OPT_BOOT_URL }, - { OPTION_STRING, D6_OPT_BOOT_PARAM }, + { OPTION_STRING | OPTION_LIST, D6_OPT_BOOT_PARAM }, #endif { OPTION_STRING, 0xd1 }, /* DHCP_PXE_CONF_FILE */ { OPTION_STRING, 0xd2 }, /* DHCP_PXE_PATH_PREFIX */ @@ -214,19 +214,16 @@ static char** new_env(void) return &client6_data.env_ptr[client6_data.env_idx++]; } -static char *string_option_to_env(const uint8_t *option, - const uint8_t *option_end) +static const char *get_option_name(const uint8_t *option) { - const char *ptr, *name = NULL; - unsigned val_len; + const char *ptr = NULL; int i; ptr = d6_option_strings; i = 0; while (*ptr) { if (d6_optflags[i].code == option[1]) { - name = ptr; - goto found; + return ptr; } ptr += strlen(ptr) + 1; i++; @@ -234,7 +231,19 @@ static char *string_option_to_env(const bb_error_msg("can't find option name for 0x%x, skipping", option[1]); return NULL; - found: +} + +static char *string_option_to_env(const uint8_t *option, + const uint8_t *option_end) +{ + const char *name = NULL; + unsigned val_len; + + name = get_option_name(option); + if (!name) { + return NULL; + } + val_len = (option[2] << 8) | option[3]; if (val_len + &option[D6_OPT_DATA] > option_end) { bb_simple_error_msg("option data exceeds option length"); @@ -243,6 +252,52 @@ static char *string_option_to_env(const return xasprintf("%s=%.*s", name, val_len, (char*)option + 4); } +/* parse list of variable length strings. The length of each string + is the first two bytes */ +static char *string_list_option_to_env(const uint8_t *option, + const uint8_t *option_end) +{ + const char *name = NULL; + unsigned val_len, name_len, parm_len; + int i; + char *envstr, *envptr, *envval; + const uint8_t *optptr; + + name = get_option_name(option); + if (!name) + return NULL; + name_len = strlen(name); + + val_len = (option[2] << 8) | option[3]; + if (val_len + &option[D6_OPT_DATA] > option_end) { + bb_simple_error_msg("option data exceeds option length"); + return NULL; + } + + envptr = envstr = xmalloc(name_len + 1 + val_len); + envptr = stpcpy(envptr, name); + envval = envptr = stpcpy(envptr, "="); + + optptr = option + D6_OPT_DATA; + while (optptr + 1 < option_end) { + parm_len = (*optptr++ << 8) | *optptr++; + if (optptr + parm_len > option_end) { + bb_simple_error_msg("option parm length overflows option length"); + return NULL; + } + if (parm_len > 0) { + if (envptr > envval) + *envptr++ = ' '; + memcpy(envptr, optptr, parm_len); + envptr += parm_len; + optptr += parm_len; + *envptr = '\0'; + } + } + + return envstr; +} + /* put all the parameters into the environment */ static void option_to_env(const uint8_t *option, const uint8_t *option_end) { @@ -407,7 +462,6 @@ static void option_to_env(const uint8_t break; #endif case D6_OPT_BOOT_URL: - case D6_OPT_BOOT_PARAM: case 0xd1: /* DHCP_PXE_CONF_FILE */ case 0xd2: /* DHCP_PXE_PATH_PREFIX */ { @@ -415,6 +469,38 @@ static void option_to_env(const uint8_t if (tmp) *new_env() = tmp; break; + } + case D6_OPT_BOOT_PARAM: +/* 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | OPT_BOOTFILE_PARAM | option-len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | param-len 1 | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ parameter 1 . + * . (variable length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * . . + * . . + * . . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | param-len n | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ parameter n . + * . (variable length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + { + char *tmp; + if (option[4]) + /* If the high byte of param-len 1 is non-zero, most + likely this was caused by a non-compliant server + sending the param as a single string. */ + tmp = string_option_to_env(option, option_end); + else + tmp = string_list_option_to_env(option, option_end); + if (tmp) + *new_env() = tmp; + break; } } len_m4 -= 4 + option[3]; From rknecht at pm.me Thu May 12 22:06:37 2022 From: rknecht at pm.me (Roger Knecht) Date: Thu, 12 May 2022 22:06:37 +0000 Subject: [PATCH v5] tree: new applet Message-ID: <20220512220620.24821-1-rknecht@pm.me> Add new applet which resembles the MS-DOS tree program to list directories and files in a tree structure. function old new delta tree_print - 388 +388 tree_main - 73 +73 .rodata 95703 95776 +73 tree_print_prefix - 28 +28 globals - 8 +8 applet_main 3200 3208 +8 packed_usage 34431 34438 +7 applet_names 2753 2758 +5 applet_suid 100 101 +1 applet_install_loc 200 201 +1 ------------------------------------------------------------------------------ (add/remove: 5/0 grow/shrink: 6/0 up/down: 592/0) Total: 592 bytes Signed-off-by: Roger Knecht --- Changelog: V5: - Added ASCII only build option (new default) - Simplified code V4: - Rephrase commit message - Updated bloatcheck to latest master V3: - Fixed symlink handling - Handle multiple directories in command line arguments - Extended tests for symlink and multiple directories - Reduced size by using libbb functions V2: - Fixed tree help text - Reduced size by 644 bytes AUTHORS | 3 + miscutils/tree.c | 148 +++++++++++++++++++++++++++++++++++++++++++ testsuite/tree.tests | 97 ++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 miscutils/tree.c create mode 100755 testsuite/tree.tests diff --git a/AUTHORS b/AUTHORS index 5c9a634c9..9ec0e2ee4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -181,3 +181,6 @@ Jie Zhang Maxime Coste paste implementation + +Roger Knecht + tree diff --git a/miscutils/tree.c b/miscutils/tree.c new file mode 100644 index 000000000..cd1cf2c25 --- /dev/null +++ b/miscutils/tree.c @@ -0,0 +1,148 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2022 Roger Knecht + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config TREE +//config: bool "tree (0.6 kb)" +//config: default n +//config: help +//config: List files and directories in a tree structure. +//config: +//config:config FEATURE_TREE_UNICODE +//config: bool "Print tree with unicode characters" +//config: default n +//config: depends on TREE +//config: help +//config: Print tree with unicode characters + +//applet:IF_TREE(APPLET(tree, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TREE) += tree.o + +//usage:#define tree_trivial_usage NOUSAGE_STR +//usage:#define tree_full_usage "" + +#include "libbb.h" + +#define DEFAULT_PATH "." + +#if ENABLE_FEATURE_TREE_UNICODE +#define PREFIX_CHILD "??? " +#define PREFIX_LAST_CHILD "??? " +#define PREFIX_GRAND_CHILD "??? " +#define PREFIX_LAST_GRAND_CHILD " " +#else +#define PREFIX_CHILD "|-- " +#define PREFIX_LAST_CHILD "`-- " +#define PREFIX_GRAND_CHILD "| " +#define PREFIX_LAST_GRAND_CHILD " " +#endif + +struct directory { + struct directory* parent; + const char* prefix; +}; + +static struct globals { + int directories; + int files; +} globals; + +static void tree_print_prefix(struct directory* directory) { + if (directory) { + tree_print_prefix(directory->parent); + fputs_stdout(directory->prefix); + } +} + +static void tree_print(const char* directory_name, struct directory* directory) { + struct dirent **entries, *dirent; + struct directory child_directory; + char* symlink_path; + int index, size; + bool is_file; + + // read directory entries + size = scandir(directory_name, &entries, NULL, alphasort); + + if (size < 0) { + fputs_stdout(directory_name); + puts(" [error opening dir]"); + return; + } + + // print directory name + puts(directory_name); + + // switch to sub directory + xchdir(directory_name); + + child_directory.parent = directory; + + // print all directory entries + for (index = 0; index < size; index++) { + dirent = entries[index]; + + // filter hidden files and directories + if (dirent->d_name[0] != '.') { + is_file = !is_directory(dirent->d_name, 1); + symlink_path = xmalloc_readlink(dirent->d_name); + + // print tree line prefix + tree_print_prefix(directory); + + if (index + 1 < size) { + child_directory.prefix = PREFIX_GRAND_CHILD; + fputs_stdout(PREFIX_CHILD); + } else { + child_directory.prefix = PREFIX_LAST_GRAND_CHILD; + fputs_stdout(PREFIX_LAST_CHILD); + } + + // count directories and files + if (is_file) + globals.files++; + else + globals.directories++; + + if (symlink_path) { + // handle symlink + printf("%s -> %s\n", dirent->d_name, symlink_path); + free(symlink_path); + } else if (is_file) + // handle file + puts(dirent->d_name); + else + // handle directory + tree_print(dirent->d_name, &child_directory); + } + + // release directory entry + free(dirent); + } + + // release directory array + free(entries); + + // switch to parent directory + xchdir(".."); +} + +int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int tree_main(int argc, char **argv) +{ + if (argc == 1) + // list current working directory + tree_print(DEFAULT_PATH, NULL); + + // list directories given as command line arguments + while (*(++argv)) + tree_print(*argv, NULL); + + // print statistic + printf("\n%d directories, %d files\n", globals.directories, globals.files); + + return EXIT_SUCCESS; +} diff --git a/testsuite/tree.tests b/testsuite/tree.tests new file mode 100755 index 000000000..dead5f9a1 --- /dev/null +++ b/testsuite/tree.tests @@ -0,0 +1,97 @@ +#!/bin/sh + +# Copyright 2022 by Roger Knecht +# Licensed under GPLv2, see file LICENSE in this source tree. + +. ./testing.sh -v + +# testing "description" "command" "result" "infile" "stdin" + +testing "tree error opening dir" \ + "tree tree.tempdir" \ + "\ +tree.tempdir [error opening dir]\n\ +\n\ +0 directories, 0 files\n" \ + "" "" + +mkdir -p tree2.tempdir +touch tree2.tempdir/testfile + +testing "tree single file" \ + "cd tree2.tempdir && tree" \ + "\ +.\n\ +\`-- testfile\n\ +\n\ +0 directories, 1 files\n" \ + "" "" + +mkdir -p tree3.tempdir/test1 \ + tree3.tempdir/test2/a \ + tree3.tempdir/test2/b \ + tree3.tempdir/test3/c \ + tree3.tempdir/test3/d + +touch tree3.tempdir/test2/a/testfile1 \ + tree3.tempdir/test2/a/testfile2 \ + tree3.tempdir/test2/a/testfile3 \ + tree3.tempdir/test2/b/testfile4 \ + tree3.tempdir/test3/c/testfile5 \ + tree3.tempdir/test3/d/testfile6 \ + tree3.tempdir/test3/d/.testfile7 + +(cd tree3.tempdir/test2/a && ln -s ../b/testfile4 .) +(cd tree3.tempdir/test2/b && ln -s ../../test3 .) + +testing "tree nested directories and files" \ + "cd tree3.tempdir && tree" \ + "\ +.\n\ +|-- test1\n\ +|-- test2\n\ +| |-- a\n\ +| | |-- testfile1\n\ +| | |-- testfile2\n\ +| | |-- testfile3\n\ +| | \`-- testfile4 -> ../b/testfile4\n\ +| \`-- b\n\ +| |-- test3 -> ../../test3\n\ +| \`-- testfile4\n\ +\`-- test3\n\ + |-- c\n\ + | \`-- testfile5\n\ + \`-- d\n\ + \`-- testfile6\n\ +\n\ +8 directories, 7 files\n" \ + "" "" + +testing "tree multiple directories" \ + "tree tree2.tempdir tree3.tempdir" \ + "\ +tree2.tempdir\n\ +\`-- testfile\n\ +tree3.tempdir\n\ +|-- test1\n\ +|-- test2\n\ +| |-- a\n\ +| | |-- testfile1\n\ +| | |-- testfile2\n\ +| | |-- testfile3\n\ +| | \`-- testfile4 -> ../b/testfile4\n\ +| \`-- b\n\ +| |-- test3 -> ../../test3\n\ +| \`-- testfile4\n\ +\`-- test3\n\ + |-- c\n\ + | \`-- testfile5\n\ + \`-- d\n\ + \`-- testfile6\n\ +\n\ +8 directories, 8 files\n" \ + "" "" + +rm -rf tree.tempdir tree2.tempdir tree3.tempdir + +exit $FAILCOUNT -- 2.17.1 From spareproject776 at gmail.com Fri May 13 03:54:46 2022 From: spareproject776 at gmail.com (spareproject776) Date: Fri, 13 May 2022 03:54:46 +0000 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: <1B22EBFE-682A-4186-8C6E-2A36F10AFCFB@gmail.com> References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> <20220510142312.jdbxo4gqvzzfdinc@t480> <1B22EBFE-682A-4186-8C6E-2A36F10AFCFB@gmail.com> Message-ID: Read the setpriv post from before, is adding that not more benifical. Just quick tested util-linux version. It allows privdropping udhcpd - net_raw udhcpc - net_raw,net_admin udhcpc6 - net_raw,net_admin ntpd - sys_time telnetd - setuid,setgid ftpd - setuid,setgid,(sys_chroot someone posted the homedir patch the other day) crond - setuid,setgid even managed to get dropbear out of it nothing to do with actually coding but that just gifted me an easy way to harden my current busybox setup so many thanks who ever posted that :) off down a seccomp cli wrapper rabbit hole now -- -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: From rep.dot.nop at gmail.com Sat May 14 06:07:56 2022 From: rep.dot.nop at gmail.com (Bernhard Reutner-Fischer) Date: Sat, 14 May 2022 08:07:56 +0200 Subject: [PATCH] su: support numeric UIDs with a -n flag In-Reply-To: References: <20220510133007.n7igtreurt6fdwoh@t480> <02a54989-c3af-b7a1-3fed-b3b39512cffa@msgid.tls.msk.ru> Message-ID: On 10 May 2022 16:06:35 CEST, Michael Tokarev wrote: >10.05.2022 16:53, Michael Tokarev wrote: >.. >> Do you really want su there? Maybe setpriv will better suit your needs? > >Grrr, and setpriv in busybox does not support user/group settings at all... ;) Then adding support for setting user and group to setpriv seems to be the proper fix. thanks, From hi at alyssa.is Sun May 15 17:18:47 2022 From: hi at alyssa.is (Alyssa Ross) Date: Sun, 15 May 2022 17:18:47 +0000 Subject: [PATCH] volume_id: volume_id_get_buffer with small FSes Message-ID: <20220515171847.2457337-1-hi@alyssa.is> I was working with some very small ext4 filesystems, used for overlaying on immutable VM/container images. If it's only desired to overlay a single config file, these filesystems can be very small indeed, and so ran afoul of this length check. I tested both the cases mentioned in the comments ? an empty floppy drive, and an unused loop device. Reading from an empty floppy drive is ENXIO, and reading from an unused loop device returns 0, so it should be fine to drop the minimum length, and be happy with any read as long as it returns at least one byte. By initializing read_len to -1, we can handle both lseek() failing and read_full() failing with the same check. --- util-linux/volume_id/util.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/util-linux/volume_id/util.c b/util-linux/volume_id/util.c index 061545fde..a5844c673 100644 --- a/util-linux/volume_id/util.c +++ b/util-linux/volume_id/util.c @@ -180,7 +180,7 @@ void *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) { uint8_t *dst; unsigned small_off; - ssize_t read_len; + ssize_t read_len = -1; dbg("get buffer off 0x%llx(%llu), len 0x%zx", (unsigned long long) off, (unsigned long long) off, len); @@ -237,13 +237,7 @@ void *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) dbg("requested 0x%x bytes, got 0x%x bytes", (unsigned) len, (unsigned) read_len); err: - /* No filesystem can be this tiny. It's most likely - * non-associated loop device, empty drive and so on. - * Flag it, making it possible to short circuit future - * accesses. Rationale: - * users complained of slow blkid due to empty floppy drives. - */ - if (off < 64*1024) + if (read_len <= 0) id->error = 1; /* id->seekbuf_len or id->sbbuf_len is wrong now! Fixing. */ volume_id_free_buffer(id); -- 2.35.1 From algore3698 at gmail.com Sun May 15 18:21:25 2022 From: algore3698 at gmail.com (Alex Gorinson) Date: Sun, 15 May 2022 14:21:25 -0400 Subject: [PATCHv2]ash: Add ifsfree to varunset and varvalue function to fix a logic error that leaks the heap Message-ID: Details: First bug: Due to a logic error in the ifsbreakup function in ash.c when a heredoc and normal command is run one after the other by means of a semi-colon, when the second command drops into ifsbreakup the command will be evaluated with the ifslastp/ifsfirst struct that was set when the here doc was evaluated. This results in a buffer over-read that can leak the program's heap, stack, and arena addresses which can be used to beat ASLR. Second bug: If the heap is sprayed with a certain amount of bash variables and part of the first bug is sent, a predictable heap value can be free'd and put into the tcache. After the heap value is free'd if the heap was sprayed correctly, an attacker can overwrite the free?d tcache address to obtain numerous write-what-where and the ability to arbitrarily overwrite any writable memory address. This could lead to a DoS, arbitrary code execution, or possible privilege escalation if the setuid flag is set. Steps to Reproduce: First bug: cmd args: ~/exampleDir/example> busybox ash $ M='AAAAAAAAAAAAAAAAA' $ q00(){ $ <<000;echo $ ${D?$M$M$M$M$M$M} $ 000 $ } $ q00 Second bug: cmd args: ~/exampleDir/example> busybox ash $ AAAAAAAAAAAAAA $ `spray 600 bash variables with size of 0x30 bytes` $ `send bash variable with size of 0x20 bytes` $ `send bash variable with size of 0x60 bytes` $ `spray 12 bash variables with size of 0x20 bytes` $ `Send part of first vulnerability` $ <<000000;V $ ${x?0p$^?A<$B*442>$0bdbasdfg$0} in this line are not meant to be entered in as is, but instead shows amount of letter inside <> that would be entered in.> $ 000000 Patch: Adding the following to ash.c will fix both bugs in one go. -- --- a/shell/ash.c +++ b/shell/ash.c @@ -7030,6 +7030,7 @@ msg = umsg; } } +ifsfree(); ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail); } @@ -7445,6 +7446,7 @@ if (discard) return -1; +ifsfree(); raise_error_syntax("bad substitution"); } -- From cand at gmx.com Mon May 16 05:23:37 2022 From: cand at gmx.com (Lauri Kasanen) Date: Mon, 16 May 2022 08:23:37 +0300 Subject: [PATCH] volume_id: volume_id_get_buffer with small FSes In-Reply-To: <20220515171847.2457337-1-hi@alyssa.is> References: <20220515171847.2457337-1-hi@alyssa.is> Message-ID: <20220516082337.718c70295cbee27af360946e@gmx.com> On Sun, 15 May 2022 17:18:47 +0000 Alyssa Ross wrote: > I tested both the cases mentioned in the comments ? an empty floppy > drive, and an unused loop device. Reading from an empty floppy drive > is ENXIO, and reading from an unused loop device returns 0, so it > should be fine to drop the minimum length, and be happy with any read > as long as it returns at least one byte. > - * accesses. Rationale: > - * users complained of slow blkid due to empty floppy drives. But is it slow like the comment said? Ie. does this patch cause a 1-2s delay due to the floppy drive spinning up? - Lauri From hi at alyssa.is Mon May 16 10:03:20 2022 From: hi at alyssa.is (Alyssa Ross) Date: Mon, 16 May 2022 10:03:20 +0000 Subject: [PATCH] volume_id: volume_id_get_buffer with small FSes In-Reply-To: <20220516082337.718c70295cbee27af360946e@gmx.com> References: <20220515171847.2457337-1-hi@alyssa.is> <20220516082337.718c70295cbee27af360946e@gmx.com> Message-ID: <20220516100320.i24nzzzhtregqfrc@eve> On Mon, May 16, 2022 at 08:23:37AM +0300, Lauri Kasanen wrote: > On Sun, 15 May 2022 17:18:47 +0000 > Alyssa Ross wrote: > > > I tested both the cases mentioned in the comments ? an empty floppy > > drive, and an unused loop device. Reading from an empty floppy drive > > is ENXIO, and reading from an unused loop device returns 0, so it > > should be fine to drop the minimum length, and be happy with any read > > as long as it returns at least one byte. > > > - * accesses. Rationale: > > - * users complained of slow blkid due to empty floppy drives. > > But is it slow like the comment said? Ie. does this patch cause a 1-2s > delay due to the floppy drive spinning up? How would it? In the case of a floppy or loop device, the operations that are happening are exactly the same. Both before and after my patch, it would try to seek or read, that would fail, and then it would set id->error and return. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From cand at gmx.com Mon May 16 14:36:16 2022 From: cand at gmx.com (Lauri Kasanen) Date: Mon, 16 May 2022 17:36:16 +0300 Subject: [PATCH] volume_id: volume_id_get_buffer with small FSes In-Reply-To: <20220516100320.i24nzzzhtregqfrc@eve> References: <20220515171847.2457337-1-hi@alyssa.is> <20220516082337.718c70295cbee27af360946e@gmx.com> <20220516100320.i24nzzzhtregqfrc@eve> Message-ID: <20220516173616.bde037ed87ab19ad7d26384a@gmx.com> On Mon, 16 May 2022 10:03:20 +0000 Alyssa Ross wrote: > On Mon, May 16, 2022 at 08:23:37AM +0300, Lauri Kasanen wrote: > > On Sun, 15 May 2022 17:18:47 +0000 > > Alyssa Ross wrote: > > > > > I tested both the cases mentioned in the comments ? an empty floppy > > > drive, and an unused loop device. Reading from an empty floppy drive > > > is ENXIO, and reading from an unused loop device returns 0, so it > > > should be fine to drop the minimum length, and be happy with any read > > > as long as it returns at least one byte. > > > > > - * accesses. Rationale: > > > - * users complained of slow blkid due to empty floppy drives. > > > > But is it slow like the comment said? Ie. does this patch cause a 1-2s > > delay due to the floppy drive spinning up? > > How would it? In the case of a floppy or loop device, the operations > that are happening are exactly the same. Both before and after my > patch, it would try to seek or read, that would fail, and then it would > set id->error and return. If you mean that the code comment was wrong, please mention that in the commit message. - Lauri From hi at alyssa.is Mon May 16 16:23:11 2022 From: hi at alyssa.is (Alyssa Ross) Date: Mon, 16 May 2022 16:23:11 +0000 Subject: [PATCH] volume_id: volume_id_get_buffer with small FSes In-Reply-To: <20220516173616.bde037ed87ab19ad7d26384a@gmx.com> References: <20220515171847.2457337-1-hi@alyssa.is> <20220516082337.718c70295cbee27af360946e@gmx.com> <20220516100320.i24nzzzhtregqfrc@eve> <20220516173616.bde037ed87ab19ad7d26384a@gmx.com> Message-ID: <20220516162311.rwjk6amo26mpwkoy@eve> On Mon, May 16, 2022 at 05:36:16PM +0300, Lauri Kasanen wrote: > On Mon, 16 May 2022 10:03:20 +0000 > Alyssa Ross wrote: > > > On Mon, May 16, 2022 at 08:23:37AM +0300, Lauri Kasanen wrote: > > > On Sun, 15 May 2022 17:18:47 +0000 > > > Alyssa Ross wrote: > > > > > > > I tested both the cases mentioned in the comments ? an empty floppy > > > > drive, and an unused loop device. Reading from an empty floppy drive > > > > is ENXIO, and reading from an unused loop device returns 0, so it > > > > should be fine to drop the minimum length, and be happy with any read > > > > as long as it returns at least one byte. > > > > > > > - * accesses. Rationale: > > > > - * users complained of slow blkid due to empty floppy drives. > > > > > > But is it slow like the comment said? Ie. does this patch cause a 1-2s > > > delay due to the floppy drive spinning up? > > > > How would it? In the case of a floppy or loop device, the operations > > that are happening are exactly the same. Both before and after my > > patch, it would try to seek or read, that would fail, and then it would > > set id->error and return. > > If you mean that the code comment was wrong, please mention that in > the commit message. I do not mean that. The previous check was one way of setting id->error for floppy drives and loop devices, and this is a better way of doing the same thing that doesn't also break small filesystems. In any case, it has been pointed out to me that since commit 4fc5ec56f ("device matching against UUIDs: do not try floppies") (from 2009), floppy drives are skipped before this function is even called. But that's orthogonal to the correctness of my patch. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From renchunhui2 at huawei.com Wed May 18 07:58:11 2022 From: renchunhui2 at huawei.com (renchunhui (A)) Date: Wed, 18 May 2022 07:58:11 +0000 Subject: [PATCH] taskset --help command hide -c command Message-ID: <44dd971e946f46cf910a19ea98e1a308@huawei.com> Shouldn't show -c in taskset --help if -c command is not enabled Signed-off-by: Chunhui Ren> --- busybox/util-linux/ taskset.c | 2+- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/util-linux/taskset.c b/util-linux/taskset.c index d834a58..ff083d5 100644 --- a/util-linux/taskset.c +++ b/util-linux/taskset.c @@ -39,7 +39,7 @@ //usage: "Set or get CPU affinity\n" //usage: "\n -p Operate on PID" //usage: "\n -a Operate on all threads" -//usage: "\n -c Affinity is a list, not mask" +//usage: IF_FEATURE_TASKSET_CPULIST("\n -c Affinity is a list, not mask") //usage: //usage:#define taskset_example_usage //usage: "$ taskset 0x7 ./dgemm_test&\n" -------------- next part -------------- An HTML attachment was scrubbed... URL: From icecodenew+busybox at gmail.com Thu May 19 11:13:21 2022 From: icecodenew+busybox at gmail.com (IceCode New) Date: Thu, 19 May 2022 19:13:21 +0800 Subject: Fwd: [PATCH] libbb/Kbuild: fix cut compilation with regex feature enabled In-Reply-To: References: Message-ID: --- libbb/Kbuild +++ libbb/Kbuild.ori @@ -226,7 +226,6 @@ lib-$(CONFIG_PGREP) += xregcomp.o lib-$(CONFIG_PKILL) += xregcomp.o lib-$(CONFIG_DEVFSD) += xregcomp.o -lib-$(CONFIG_FEATURE_CUT_REGEX) += xregcomp.o lib-$(CONFIG_FEATURE_FIND_REGEX) += xregcomp.o # Add the experimental logging functionality, only used by zcip -------------- next part -------------- An HTML attachment was scrubbed... URL: From rknecht at pm.me Sat May 21 09:59:04 2022 From: rknecht at pm.me (Roger Knecht) Date: Sat, 21 May 2022 09:59:04 +0000 Subject: [PATCH v5 RESEND] tree: new applet Message-ID: <20220521095844.10261-1-rknecht@pm.me> Add new applet which resembles the MS-DOS tree program to list directories and files in a tree structure. function old new delta tree_print - 388 +388 tree_main - 73 +73 .rodata 95703 95776 +73 tree_print_prefix - 28 +28 globals - 8 +8 applet_main 3200 3208 +8 packed_usage 34431 34438 +7 applet_names 2753 2758 +5 applet_suid 100 101 +1 applet_install_loc 200 201 +1 ------------------------------------------------------------------------------ (add/remove: 5/0 grow/shrink: 6/0 up/down: 592/0) Total: 592 bytes Signed-off-by: Roger Knecht --- Changelog: V5: - Added ASCII only build option (new default) - Simplified code V4: - Rephrase commit message - Updated bloatcheck to latest master V3: - Fixed symlink handling - Handle multiple directories in command line arguments - Extended tests for symlink and multiple directories - Reduced size by using libbb functions V2: - Fixed tree help text - Reduced size by 644 bytes AUTHORS | 3 + miscutils/tree.c | 148 +++++++++++++++++++++++++++++++++++++++++++ testsuite/tree.tests | 97 ++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 miscutils/tree.c create mode 100755 testsuite/tree.tests diff --git a/AUTHORS b/AUTHORS index 5c9a634c9..9ec0e2ee4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -181,3 +181,6 @@ Jie Zhang Maxime Coste paste implementation + +Roger Knecht + tree diff --git a/miscutils/tree.c b/miscutils/tree.c new file mode 100644 index 000000000..cd1cf2c25 --- /dev/null +++ b/miscutils/tree.c @@ -0,0 +1,148 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2022 Roger Knecht + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config TREE +//config: bool "tree (0.6 kb)" +//config: default n +//config: help +//config: List files and directories in a tree structure. +//config: +//config:config FEATURE_TREE_UNICODE +//config: bool "Print tree with unicode characters" +//config: default n +//config: depends on TREE +//config: help +//config: Print tree with unicode characters + +//applet:IF_TREE(APPLET(tree, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TREE) += tree.o + +//usage:#define tree_trivial_usage NOUSAGE_STR +//usage:#define tree_full_usage "" + +#include "libbb.h" + +#define DEFAULT_PATH "." + +#if ENABLE_FEATURE_TREE_UNICODE +#define PREFIX_CHILD "??? " +#define PREFIX_LAST_CHILD "??? " +#define PREFIX_GRAND_CHILD "??? " +#define PREFIX_LAST_GRAND_CHILD " " +#else +#define PREFIX_CHILD "|-- " +#define PREFIX_LAST_CHILD "`-- " +#define PREFIX_GRAND_CHILD "| " +#define PREFIX_LAST_GRAND_CHILD " " +#endif + +struct directory { + struct directory* parent; + const char* prefix; +}; + +static struct globals { + int directories; + int files; +} globals; + +static void tree_print_prefix(struct directory* directory) { + if (directory) { + tree_print_prefix(directory->parent); + fputs_stdout(directory->prefix); + } +} + +static void tree_print(const char* directory_name, struct directory* directory) { + struct dirent **entries, *dirent; + struct directory child_directory; + char* symlink_path; + int index, size; + bool is_file; + + // read directory entries + size = scandir(directory_name, &entries, NULL, alphasort); + + if (size < 0) { + fputs_stdout(directory_name); + puts(" [error opening dir]"); + return; + } + + // print directory name + puts(directory_name); + + // switch to sub directory + xchdir(directory_name); + + child_directory.parent = directory; + + // print all directory entries + for (index = 0; index < size; index++) { + dirent = entries[index]; + + // filter hidden files and directories + if (dirent->d_name[0] != '.') { + is_file = !is_directory(dirent->d_name, 1); + symlink_path = xmalloc_readlink(dirent->d_name); + + // print tree line prefix + tree_print_prefix(directory); + + if (index + 1 < size) { + child_directory.prefix = PREFIX_GRAND_CHILD; + fputs_stdout(PREFIX_CHILD); + } else { + child_directory.prefix = PREFIX_LAST_GRAND_CHILD; + fputs_stdout(PREFIX_LAST_CHILD); + } + + // count directories and files + if (is_file) + globals.files++; + else + globals.directories++; + + if (symlink_path) { + // handle symlink + printf("%s -> %s\n", dirent->d_name, symlink_path); + free(symlink_path); + } else if (is_file) + // handle file + puts(dirent->d_name); + else + // handle directory + tree_print(dirent->d_name, &child_directory); + } + + // release directory entry + free(dirent); + } + + // release directory array + free(entries); + + // switch to parent directory + xchdir(".."); +} + +int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int tree_main(int argc, char **argv) +{ + if (argc == 1) + // list current working directory + tree_print(DEFAULT_PATH, NULL); + + // list directories given as command line arguments + while (*(++argv)) + tree_print(*argv, NULL); + + // print statistic + printf("\n%d directories, %d files\n", globals.directories, globals.files); + + return EXIT_SUCCESS; +} diff --git a/testsuite/tree.tests b/testsuite/tree.tests new file mode 100755 index 000000000..dead5f9a1 --- /dev/null +++ b/testsuite/tree.tests @@ -0,0 +1,97 @@ +#!/bin/sh + +# Copyright 2022 by Roger Knecht +# Licensed under GPLv2, see file LICENSE in this source tree. + +. ./testing.sh -v + +# testing "description" "command" "result" "infile" "stdin" + +testing "tree error opening dir" \ + "tree tree.tempdir" \ + "\ +tree.tempdir [error opening dir]\n\ +\n\ +0 directories, 0 files\n" \ + "" "" + +mkdir -p tree2.tempdir +touch tree2.tempdir/testfile + +testing "tree single file" \ + "cd tree2.tempdir && tree" \ + "\ +.\n\ +\`-- testfile\n\ +\n\ +0 directories, 1 files\n" \ + "" "" + +mkdir -p tree3.tempdir/test1 \ + tree3.tempdir/test2/a \ + tree3.tempdir/test2/b \ + tree3.tempdir/test3/c \ + tree3.tempdir/test3/d + +touch tree3.tempdir/test2/a/testfile1 \ + tree3.tempdir/test2/a/testfile2 \ + tree3.tempdir/test2/a/testfile3 \ + tree3.tempdir/test2/b/testfile4 \ + tree3.tempdir/test3/c/testfile5 \ + tree3.tempdir/test3/d/testfile6 \ + tree3.tempdir/test3/d/.testfile7 + +(cd tree3.tempdir/test2/a && ln -s ../b/testfile4 .) +(cd tree3.tempdir/test2/b && ln -s ../../test3 .) + +testing "tree nested directories and files" \ + "cd tree3.tempdir && tree" \ + "\ +.\n\ +|-- test1\n\ +|-- test2\n\ +| |-- a\n\ +| | |-- testfile1\n\ +| | |-- testfile2\n\ +| | |-- testfile3\n\ +| | \`-- testfile4 -> ../b/testfile4\n\ +| \`-- b\n\ +| |-- test3 -> ../../test3\n\ +| \`-- testfile4\n\ +\`-- test3\n\ + |-- c\n\ + | \`-- testfile5\n\ + \`-- d\n\ + \`-- testfile6\n\ +\n\ +8 directories, 7 files\n" \ + "" "" + +testing "tree multiple directories" \ + "tree tree2.tempdir tree3.tempdir" \ + "\ +tree2.tempdir\n\ +\`-- testfile\n\ +tree3.tempdir\n\ +|-- test1\n\ +|-- test2\n\ +| |-- a\n\ +| | |-- testfile1\n\ +| | |-- testfile2\n\ +| | |-- testfile3\n\ +| | \`-- testfile4 -> ../b/testfile4\n\ +| \`-- b\n\ +| |-- test3 -> ../../test3\n\ +| \`-- testfile4\n\ +\`-- test3\n\ + |-- c\n\ + | \`-- testfile5\n\ + \`-- d\n\ + \`-- testfile6\n\ +\n\ +8 directories, 8 files\n" \ + "" "" + +rm -rf tree.tempdir tree2.tempdir tree3.tempdir + +exit $FAILCOUNT -- 2.17.1