From bugzilla at busybox.net Wed Jun 1 21:06:49 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 01 Jun 2022 21:06:49 +0000 Subject: [Bug 14831] New: Segfault by recursively source-ing the same file Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14831 Bug ID: 14831 Summary: Segfault by recursively source-ing the same file Product: Busybox Version: 1.30.x Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: g at gergelykalman.com CC: busybox-cvs at busybox.net Target Milestone: --- Exact version: v1.30.1 (Debian 1:1.30.1-7+b3) To reproduce: $ cat c source ./c $ busybox sh c Segmentation fault -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Tue Jun 7 18:32:17 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Tue, 07 Jun 2022 18:32:17 +0000 Subject: [Bug 14781] A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14781 --- Comment #2 from Natanael Copa --- I'm trying to reproduce this here. What is the content of `1.txt`? -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Tue Jun 7 18:40:38 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Tue, 07 Jun 2022 18:40:38 +0000 Subject: [Bug 14781] A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14781 --- Comment #3 from Natanael Copa --- It does not crash here but valgrind detects it and various other use after free: $ echo foo | valgrind ./busybox_unstripped awk '$3i$3in$9=$r||$9=i6/6-9f' ==3430== Memcheck, a memory error detector ==3430== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==3430== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info ==3430== Command: ./busybox_unstripped awk $3i$3in$9=$r||$9=i6/6-9f ==3430== ==3430== Invalid read of size 4 ==3430== at 0x195B74: copyvar (awk.c:1064) ==3430== by 0x196ED1: evaluate (awk.c:3141) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b7510 is 0 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x19698C: evaluate (awk.c:2923) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x19698C: evaluate (awk.c:2923) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 8 ==3430== at 0x195B76: copyvar (awk.c:1066) ==3430== by 0x196ED1: evaluate (awk.c:3141) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b7520 is 16 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x19698C: evaluate (awk.c:2923) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x19698C: evaluate (awk.c:2923) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 8 ==3430== at 0x195B7B: copyvar (awk.c:1067) ==3430== by 0x196ED1: evaluate (awk.c:3141) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b7518 is 8 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x19698C: evaluate (awk.c:2923) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x19698C: evaluate (awk.c:2923) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 4 ==3430== at 0x1947E6: getvar_i (awk.c:1023) ==3430== by 0x194869: is_numeric (awk.c:1082) ==3430== by 0x194869: istrue (awk.c:1089) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c10 is 0 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid write of size 8 ==3430== at 0x1947EF: getvar_i (awk.c:1024) ==3430== by 0x194869: is_numeric (awk.c:1082) ==3430== by 0x194869: istrue (awk.c:1089) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c20 is 16 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 8 ==3430== at 0x1947F7: getvar_i (awk.c:1025) ==3430== by 0x194869: is_numeric (awk.c:1082) ==3430== by 0x194869: istrue (awk.c:1089) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c18 is 8 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid write of size 4 ==3430== at 0x194839: getvar_i (awk.c:1039) ==3430== by 0x194869: is_numeric (awk.c:1082) ==3430== by 0x194869: istrue (awk.c:1089) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c10 is 0 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 4 ==3430== at 0x19483B: getvar_i (awk.c:1041) ==3430== by 0x194869: is_numeric (awk.c:1082) ==3430== by 0x194869: istrue (awk.c:1089) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c10 is 0 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 8 ==3430== at 0x194841: getvar_i (awk.c:1044) ==3430== by 0x194869: is_numeric (awk.c:1082) ==3430== by 0x194869: istrue (awk.c:1089) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c20 is 16 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 4 ==3430== at 0x19486A: is_numeric (awk.c:1083) ==3430== by 0x19486A: istrue (awk.c:1089) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c10 is 0 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== Invalid read of size 8 ==3430== at 0x19488D: istrue (awk.c:1091) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Address 0x48b6c18 is 8 bytes inside a block of size 64 free'd ==3430== at 0x48A4B0D: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x1974EA: evaluate (awk.c:3537) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== Block was alloc'd at ==3430== at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==3430== by 0x117287: xmalloc (xfuncs_printf.c:50) ==3430== by 0x1172BC: xzalloc (xfuncs_printf.c:71) ==3430== by 0x1968F6: nvalloc (awk.c:1825) ==3430== by 0x1968F6: evaluate (awk.c:2877) ==3430== by 0x1983EB: ptest (awk.c:2227) ==3430== by 0x196A25: evaluate (awk.c:2951) ==3430== by 0x19885A: awk_main (awk.c:3713) ==3430== by 0x11600D: run_applet_no_and_exit (appletlib.c:967) ==3430== by 0x116331: run_applet_and_exit (appletlib.c:986) ==3430== by 0x116314: busybox_main (appletlib.c:917) ==3430== by 0x116314: run_applet_and_exit (appletlib.c:979) ==3430== by 0x1163AA: main (appletlib.c:1126) ==3430== ==3430== ==3430== HEAP SUMMARY: ==3430== in use at exit: 11,033 bytes in 174 blocks ==3430== total heap usage: 204 allocs, 30 frees, 13,028 bytes allocated ==3430== ==3430== LEAK SUMMARY: ==3430== definitely lost: 0 bytes in 0 blocks ==3430== indirectly lost: 0 bytes in 0 blocks ==3430== possibly lost: 11,033 bytes in 174 blocks ==3430== still reachable: 0 bytes in 0 blocks ==3430== suppressed: 0 bytes in 0 blocks ==3430== Rerun with --leak-check=full to see details of leaked memory ==3430== ==3430== For lists of detected and suppressed errors, rerun with: -s ==3430== ERROR SUMMARY: 12 errors from 11 contexts (suppressed: 0 from 0) -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Tue Jun 7 18:49:18 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Tue, 07 Jun 2022 18:49:18 +0000 Subject: [Bug 14781] A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14781 --- Comment #4 from Natanael Copa --- simpler way to reproduce it: echo "foo" | valgrind ./busybox_unstripped awk '$1$1=0' -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Tue Jun 7 19:14:25 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Tue, 07 Jun 2022 19:14:25 +0000 Subject: [Bug 14781] A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14781 --- Comment #5 from Natanael Copa --- This change makes it segfault early: $ git diff diff --git a/editors/awk.c b/editors/awk.c index 079d0bde5..840f2595f 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -55,7 +55,7 @@ /* If you comment out one of these below, it will be #defined later * to perform debug printfs to stderr: */ #define debug_printf_walker(...) do {} while (0) -#define debug_printf_eval(...) do {} while (0) +//#define debug_printf_eval(...) do {} while (0) #define debug_printf_parse(...) do {} while (0) #ifndef debug_printf_walker @@ -2922,7 +2922,7 @@ static var *evaluate(node *op, var *res) if (opinfo & OF_RES2) { R.v = evaluate(op->r.n, TMPVAR1); //TODO: L.v may be invalid now, set L.v to NULL to catch bugs? - //L.v = NULL; + L.v = NULL; if (opinfo & OF_STR2) { R.s = getvar_s(R.v); debug_printf_eval("R.s:'%s'\n", R.s); $ echo "foo" | ./busybox_unstripped awk '$1$1=0' fsrealloc: xrealloc(0, 512) fsrealloc: Fields=0x7f6dbda05030..0x7f6dbda0522f getvar_i: 0.000000 getvar_i: 1.000000 entered awk_getline() returning from awk_getline(): 1 getvar_i: 0.000000 getvar_i: 0.000000 entered evaluate() opinfo:00000300 opn:00000000 switch(0x3) NEWSOURCE opinfo:00000d00 opn:00000000 switch(0xd) TEST entered evaluate() opinfo:4a031f00 opn:00000000 entered evaluate() opinfo:230f1500 opn:00000000 entered evaluate() opinfo:05021700 opn:00000000 entered evaluate() opinfo:00002700 opn:00000000 switch(0x27) VAR returning from evaluate(): 0x7f6dbda03410 switch(0x17) FIELD getvar_i: 1.000000 returning from evaluate(): 0x7f6dbda05030 L.s:'foo' entered evaluate() opinfo:05021700 opn:00000000 entered evaluate() opinfo:00002700 opn:00000000 switch(0x27) VAR returning from evaluate(): 0x7f6dbda034d0 switch(0x17) FIELD getvar_i: 1.000000 returning from evaluate(): 0x7f6dbda05030 R.s:'foo' switch(0x15) CONCAT / COMMA returning from evaluate(): 0x7f6dbda04bb0 entered evaluate() opinfo:00002700 opn:00000000 switch(0x27) VAR returning from evaluate(): 0x7f6dbda03560 switch(0x1f) MOVE Segmentation fault -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Tue Jun 7 19:31:09 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Tue, 07 Jun 2022 19:31:09 +0000 Subject: [Bug 14781] A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14781 --- Comment #6 from Natanael Copa --- Possible fix: diff --git a/editors/awk.c b/editors/awk.c index 079d0bde5..d68b8d4bc 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -2922,7 +2922,7 @@ static var *evaluate(node *op, var *res) if (opinfo & OF_RES2) { R.v = evaluate(op->r.n, TMPVAR1); //TODO: L.v may be invalid now, set L.v to NULL to catch bugs? - //L.v = NULL; + L.v = NULL; if (opinfo & OF_STR2) { R.s = getvar_s(R.v); debug_printf_eval("R.s:'%s'\n", R.s); @@ -3128,6 +3128,8 @@ static var *evaluate(node *op, var *res) case XC( OC_MOVE ): debug_printf_eval("MOVE\n"); + if (L.v == NULL) + syntax_error(EMSG_POSSIBLE_ERROR); /* if source is a temporary string, jusk relink it to dest */ if (R.v == TMPVAR1 && !(R.v->type & VF_NUMBER) -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Fri Jun 10 02:05:26 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 10 Jun 2022 02:05:26 +0000 Subject: [Bug 11506] Out of bounds read in udhcp_get_option() In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=11506 --- Comment #6 from ??? <982326510 at qq.com> --- Comment on attachment 7881 --> https://bugs.busybox.net/attachment.cgi?id=7881 Corrupt dhcpdiscover message which triggers the out of bounds read ? -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Wed Jun 15 08:19:49 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 15 Jun 2022 08:19:49 +0000 Subject: [Bug 14846] New: quoting causes only first lib in CONFIG_EXTRA_LDLIBS to be taken Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14846 Bug ID: 14846 Summary: quoting causes only first lib in CONFIG_EXTRA_LDLIBS to be taken Product: Busybox Version: 1.35.x Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: arekm at maven.pl CC: busybox-cvs at busybox.net Target Milestone: --- Commit commit 1f9ed02caffb269e5fc6fbdf19fc9ba05a79e628 Author: Denys Vlasenko Date: Tue Feb 23 23:09:49 2021 +0100 trylink: do not drop libs from CONFIG_EXTRA_LDLIBS removed (by not putting it in new place) -ifneq ($(CONFIG_EXTRA_LDLIBS),) -LDLIBS += $(strip $(subst ",,$(CONFIG_EXTRA_LDLIBS))) -#")) -endif which was stripping "" from CONFIG_EXTRA_LDLIBS and now we get this: .../busybox-1.35.0/scripts/trylink "busybox_unstripped" "x86_64-pld-linux-gnux32-gcc" "-malign-data=abi ..." " applets/built-in.o" " archival/lib.a ar ...id/built-in.o" "m crypt rt" ""tirpc pthread gssapi"" && /home/users/arekm/rpm/BUILD-x32/busybox-1.35.0/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h note the double quoting of ""tirpc pthread gssapi"". Then script/trylink does: CONFIG_EXTRA_LDLIBS="$8" which will be only + CONFIG_EXTRA_LDLIBS=tirpc missing pthread and gssapi. -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Wed Jun 15 08:21:39 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 15 Jun 2022 08:21:39 +0000 Subject: [Bug 14846] quoting causes only first lib in CONFIG_EXTRA_LDLIBS to be taken In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14846 --- Comment #1 from Arkadiusz Miskiewicz --- Created attachment 9321 --> https://bugs.busybox.net/attachment.cgi?id=9321&action=edit fix -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Fri Jun 17 01:12:49 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 17 Jun 2022 01:12:49 +0000 Subject: [Bug 14851] New: Support pipefail in `sh` Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14851 Bug ID: 14851 Summary: Support pipefail in `sh` Product: Busybox Version: unspecified Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: tmgross at umich.edu CC: busybox-cvs at busybox.net Target Milestone: --- Hello all, As I understand, POSIX:2022 will include the option to set -o pipefail. Would busybox consider adding this to their flavor of `sh`? The POSIX standard is expected to be released in 2023 I believe. The in-progress standard is quite difficult to access for those not involved, but this discussion makes it clear that it should be coming: https://www.austingroupbugs.net/view.php?id=789. Additionally, St?phane in this comment states that the resolution was accepted in 2019: https://unix.stackexchange.com/a/654932/150903 Even outside of the scope of this standard, pipefail is a very useful option and could be added at any time. Note: I opened this request at the suggestion of Natanael Copa, based on the Alpine git issue here: https://github.com/alpinelinux/docker-alpine/issues/258. Most of the aboce is paraphrased from what I wrote in the comments there. -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Fri Jun 17 09:49:42 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 17 Jun 2022 09:49:42 +0000 Subject: [Bug 14781] A use-after-free in Busybox's awk applet leads to denial of service and possibly code execution when processing a crafted awk pattern in the copyvar function In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14781 --- Comment #7 from Natanael Copa --- (In reply to Natanael Copa from comment #6) Setting L.v to null does not work. it breaks other stuff. This might work and ./runtests awk passes: diff --git a/editors/awk.c b/editors/awk.c index 079d0bde5..acdc50e32 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -3128,6 +3128,9 @@ static var *evaluate(node *op, var *res) case XC( OC_MOVE ): debug_printf_eval("MOVE\n"); + /* make sure that we never return a temp var */ + if (L.v == TMPVAR0) + L.v = res; /* if source is a temporary string, jusk relink it to dest */ if (R.v == TMPVAR1 && !(R.v->type & VF_NUMBER) -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Wed Jun 22 11:05:23 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Wed, 22 Jun 2022 11:05:23 +0000 Subject: [Bug 14861] New: ln: unrecognized option: t Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14861 Bug ID: 14861 Summary: ln: unrecognized option: t Product: Busybox Version: 1.35.x Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: spam at ipik.org CC: busybox-cvs at busybox.net Target Milestone: --- There are a few discrepancies between documented usages of -t and -T options Trivial usage message [1] implies -t exists and says: //usage: "[-sfnbtv] [-S SUF] TARGET... LINK|DIR" but opt does not handle it [2]: opts = getopt32(argv, "^" "sfnbS:vT" "\0" "-1", &suffix); and web site command help does not list -T (nor -t)[3]: ln ln [OPTIONS] TARGET... LINK|DIRECTORY Create a link LINK or DIRECTORY/TARGET to the specified TARGET(s) Options: -s Make symlinks instead of hardlinks -f Remove existing destination files -n Don't dereference symlinks - treat like normal file -b Make a backup of the target (if exists) before link operation -S suf Use suffix instead of ~ when making backup files [1] https://git.busybox.net/busybox/tree/coreutils/ln.c#n24 [2] https://git.busybox.net/busybox/tree/coreutils/ln.c#n64 [3] https://busybox.net/downloads/BusyBox.html -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Fri Jun 24 20:29:59 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Fri, 24 Jun 2022 20:29:59 +0000 Subject: [Bug 14866] New: sha256sum reports false mismatch if input not delimited by two spaces Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14866 Bug ID: 14866 Summary: sha256sum reports false mismatch if input not delimited by two spaces Product: Busybox Version: unspecified Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Other Assignee: unassigned at busybox.net Reporter: rittneje+bugzilla at gmail.com CC: busybox-cvs at busybox.net Target Milestone: --- For some reason, the Alpine version of sha256sum requires two spaces between the hash and file path. No other version of sha256sum has this requirement. See https://github.com/alpinelinux/docker-alpine/issues/246 for further details. -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Sat Jun 25 14:13:03 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sat, 25 Jun 2022 14:13:03 +0000 Subject: [Bug 14871] New: `sort -s -u -k 2' didn't remove duplicate lines Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14871 Bug ID: 14871 Summary: `sort -s -u -k 2' didn't remove duplicate lines Product: Busybox Version: unspecified Hardware: All OS: Linux Status: NEW Severity: normal Priority: P5 Component: Standard Compliance Assignee: unassigned at busybox.net Reporter: zhangboyang.id at gmail.com CC: busybox-cvs at busybox.net Target Milestone: --- Hi, Please run `LANG=C sort -s -u -k 2' with following input data: z b a b z a a a The output of busybox's sort is: z a a a z b a b The expected output (from GNU sort) is: z a z b -- You are receiving this mail because: You are on the CC list for the bug. From bugzilla at busybox.net Sat Jun 25 14:30:31 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sat, 25 Jun 2022 14:30:31 +0000 Subject: [Bug 14871] sort: `sort -s -u -k 2' didn't remove duplicate lines In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14871 Zhang Boyang changed: What |Removed |Added ---------------------------------------------------------------------------- Summary|`sort -s -u -k 2' didn't |sort: `sort -s -u -k 2' |remove duplicate lines |didn't remove duplicate | |lines --- Comment #1 from Zhang Boyang --- (In reply to Zhang Boyang from comment #0) -- You are receiving this mail because: You are on the CC list for the bug. From vda.linux at googlemail.com Sun Jun 26 15:17:02 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 26 Jun 2022 17:17:02 +0200 Subject: [git commit] libbb: restore special handling of nomsg errors Message-ID: <20220626150657.BD1FD87527@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=95fec31be601bfdced6bed7007a33b26e968e0db branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master The functions bb_perror_nomsg() and bb_perror_nomsg_and_die() are used to print error messages where no specific information is available. For example: $ busybox mktemp -p / mktemp: (null): Permission denied mktemp(3) doesn't tell us the name of the file it tried to create. However, printing '(null)' is a regression introduced by commit 6937487be (libbb: reduce the overhead of single parameter bb_error_msg() calls). Restore the previous behaviour by reverting the changes to the two functions mentioned: $ busybox mktemp -p / mktemp: Permission denied function old new delta bb_perror_nomsg_and_die 7 14 +7 bb_perror_nomsg 7 14 +7 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 14/0) Total: 14 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/perror_nomsg.c | 4 ++-- libbb/perror_nomsg_and_die.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libbb/perror_nomsg.c b/libbb/perror_nomsg.c index d7d53de44..a2a11cc8e 100644 --- a/libbb/perror_nomsg.c +++ b/libbb/perror_nomsg.c @@ -12,11 +12,11 @@ * instead of including libbb.h */ //#include "libbb.h" #include "platform.h" -extern void bb_simple_perror_msg(const char *s) FAST_FUNC; +extern void bb_perror_msg(const char *s, ...) FAST_FUNC; /* suppress gcc "no previous prototype" warning */ void FAST_FUNC bb_perror_nomsg(void); void FAST_FUNC bb_perror_nomsg(void) { - bb_simple_perror_msg(0); + bb_perror_msg(0); } diff --git a/libbb/perror_nomsg_and_die.c b/libbb/perror_nomsg_and_die.c index bea5f25a5..543ff5178 100644 --- a/libbb/perror_nomsg_and_die.c +++ b/libbb/perror_nomsg_and_die.c @@ -12,11 +12,11 @@ * instead of including libbb.h */ //#include "libbb.h" #include "platform.h" -extern void bb_simple_perror_msg_and_die(const char *s) FAST_FUNC; +extern void bb_perror_msg_and_die(const char *s, ...) FAST_FUNC; /* suppress gcc "no previous prototype" warning */ void FAST_FUNC bb_perror_nomsg_and_die(void); void FAST_FUNC bb_perror_nomsg_and_die(void) { - bb_simple_perror_msg_and_die(0); + bb_perror_msg_and_die(0); } From vda.linux at googlemail.com Sun Jun 26 16:05:50 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 26 Jun 2022 18:05:50 +0200 Subject: [git commit] ash,hush: use HOME for tab completion and prompts Message-ID: <20220626155814.B6F768755A@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=7d1c7d8337853ca99e6ec1150ac4b834cfed5cd3 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master ash and hush correctly use the value of HOME for tilde expansion. However the line editing code in libbb obtains the user's home directory by calling getpwuid(). Thus tildes in tab completion and prompts may be interpreted differently than in tilde expansion. When the line editing code is invoked from a shell make it use the shell's interpretation of tilde. This is similar to how GNU readline and bash collaborate. function old new delta get_homedir_or_NULL 29 72 +43 optschanged 119 126 +7 hush_main 1204 1211 +7 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 57/0) Total: 57 bytes v2: Always check for HOME before trying the password database: this is what GNU readline does. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- include/libbb.h | 11 +++-------- libbb/lineedit.c | 12 +++++++++++- shell/ash.c | 7 +++---- shell/hush.c | 5 ++--- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 6aeec249d..abbc9ac59 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1924,6 +1924,7 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC; # define MAX_HISTORY 0 # endif typedef const char *get_exe_name_t(int i) FAST_FUNC; +typedef const char *sh_get_var_t(const char *name) FAST_FUNC; typedef struct line_input_t { int flags; int timeout; @@ -1937,9 +1938,8 @@ typedef struct line_input_t { # if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH /* function to fetch additional application-specific names to match */ get_exe_name_t *get_exe_name; -# define EDITING_HAS_get_exe_name 1 -# else -# define EDITING_HAS_get_exe_name 0 + /* function to fetch value of shell variable */ + sh_get_var_t *sh_get_var; # endif # endif # if MAX_HISTORY @@ -1993,11 +1993,6 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; read_line_input(prompt, command, maxsize) #endif -#ifndef EDITING_HAS_get_exe_name -# define EDITING_HAS_get_exe_name 0 -#endif - - #ifndef COMM_LEN # ifdef TASK_COMM_LEN enum { COMM_LEN = TASK_COMM_LEN }; diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 82624757e..b685399f9 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -259,6 +259,16 @@ static const char *get_username_str(void) static NOINLINE const char *get_homedir_or_NULL(void) { + const char *home; + +# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH + home = state->sh_get_var ? state->sh_get_var("HOME") : getenv("HOME"); +# else + home = getenv("HOME"); +# endif + if (home != NULL && home[0] != '\0') + return home; + if (!got_user_strings) get_user_strings(); return home_pwd_buf; @@ -861,7 +871,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) continue; } # endif -# if EDITING_HAS_get_exe_name +# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH if (state->get_exe_name) { i = 0; for (;;) { diff --git a/shell/ash.c b/shell/ash.c index ef4a47afe..d29de37b7 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9720,7 +9720,7 @@ evalpipe(union node *n, int flags) } /* setinteractive needs this forward reference */ -#if EDITING_HAS_get_exe_name +#if ENABLE_FEATURE_EDITING static const char *get_builtin_name(int i) FAST_FUNC; #endif @@ -9757,9 +9757,8 @@ setinteractive(int on) #if ENABLE_FEATURE_EDITING if (!line_input_state) { line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); -# if EDITING_HAS_get_exe_name line_input_state->get_exe_name = get_builtin_name; -# endif + line_input_state->sh_get_var = lookupvar; } #endif } @@ -10262,7 +10261,7 @@ find_builtin(const char *name) return bp; } -#if EDITING_HAS_get_exe_name +#if ENABLE_FEATURE_EDITING static const char * FAST_FUNC get_builtin_name(int i) { diff --git a/shell/hush.c b/shell/hush.c index ae81f0da5..051b123e7 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8188,7 +8188,7 @@ static const struct built_in_command *find_builtin(const char *name) return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); } -#if ENABLE_HUSH_JOB && EDITING_HAS_get_exe_name +#if ENABLE_HUSH_JOB && ENABLE_FEATURE_EDITING static const char * FAST_FUNC get_builtin_name(int i) { if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { @@ -10668,9 +10668,8 @@ int hush_main(int argc, char **argv) # if ENABLE_FEATURE_EDITING G.line_input_state = new_line_input_t(FOR_SHELL); -# if EDITING_HAS_get_exe_name G.line_input_state->get_exe_name = get_builtin_name; -# endif + G.line_input_state->sh_get_var = get_local_var_value; # endif # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 { From bugzilla at busybox.net Sun Jun 26 17:23:31 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sun, 26 Jun 2022 17:23:31 +0000 Subject: [Bug 14866] sha256sum reports false mismatch if input not delimited by two spaces In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14866 --- Comment #1 from wolf+busybox at wolfsden.cz --- As far as I know all versions of sha256sum do generate the output with two spaces (or rather, one space and one character for mode indicator). Why do you feed it something else? -- You are receiving this mail because: You are on the CC list for the bug. From vda.linux at googlemail.com Sun Jun 26 17:38:28 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 26 Jun 2022 19:38:28 +0200 Subject: [git commit] vi: fix regression in autoindent handling Message-ID: <20220626174327.DA61E87570@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=af3b585815de5af367995d6064d994394b46c928 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Suppose autoindent is enabled and we have a line with an initial tab where we want to split the words onto separate lines: split the words One way to do this is with the sequence 'f r;r', but in BusyBox vi the result is: split he words This is a regression introduced by commit 9659a8db1 (vi: remove autoindent from otherwise empty lines). The amount of indentation is being recorded when the 'r' command inserts a newline but isn't subsequently reset. A fix is to only record the indent when in insert or replace mode. Proper handling of the 'o' and 'O' commands then requires them to switch to insert mode before calling char_insert() to insert a newline. function old new delta char_insert 884 891 +7 do_cmd 4243 4247 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 11/0) Total: 11 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/editors/vi.c b/editors/vi.c index 6fa0a4e18..5b86b0516 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -2227,7 +2227,10 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' p--; // open above, indent before newly inserted NL if (len) { - indentcol = col; + // only record indent if in insert/replace mode or for + // the 'o'/'O' commands, which are switched to insert + // mode early. + indentcol = cmd_mode != 0 ? col : 0; if (expandtab) { ntab = 0; nspc = col; @@ -4265,6 +4268,9 @@ static void do_cmd(int c) case 'o': // o- open an empty line below dot_end(); dc3: +#if ENABLE_FEATURE_VI_SETOPTS + cmd_mode = 1; // switch to insert mode early +#endif dot = char_insert(dot, '\n', ALLOW_UNDO); if (c == 'O' && !autoindent) { // done in char_insert() for 'O'+autoindent From vda.linux at googlemail.com Sun Jun 26 17:38:31 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Sun, 26 Jun 2022 19:38:31 +0200 Subject: [git commit] vi: handle autoindent in 'cc' command Message-ID: <20220626174327.EAD5087571@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=2617a5e4c600b4577b2c18f794701276e55da43b branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master When the 'cc' command is invoked with autoindent enabled it should use the indent of the first line being changed. The size of the indent has to be established before char_insert() is called as the lines being changed are deleted. Introduce a new global variable, newindent, to handle this. The indentcol global is now effectively a static variable in char_insert(). function old new delta do_cmd 4247 4308 +61 vi_main 416 422 +6 char_insert 891 875 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 67/-16) Total: 51 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- editors/vi.c | 71 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index 5b86b0516..d799a8170 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -380,7 +380,9 @@ struct globals { char *last_search_pattern; // last pattern from a '/' or '?' search #endif #if ENABLE_FEATURE_VI_SETOPTS - int indentcol; // column of recently autoindent, 0 or -1 + int char_insert__indentcol; // column of recent autoindent or 0 + int newindent; // autoindent value for 'O'/'cc' commands + // or -1 to use indent from previous line #endif smallint cmd_error; @@ -507,7 +509,8 @@ struct globals { #define ioq_start (G.ioq_start ) #define dotcnt (G.dotcnt ) #define last_search_pattern (G.last_search_pattern) -#define indentcol (G.indentcol ) +#define char_insert__indentcol (G.char_insert__indentcol) +#define newindent (G.newindent ) #define cmd_error (G.cmd_error ) #define edit_file__cur_line (G.edit_file__cur_line) @@ -540,10 +543,11 @@ struct globals { #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ - last_modified_count = -1; \ + last_modified_count--; \ /* "" but has space for 2 chars: */ \ IF_FEATURE_VI_SEARCH(last_search_pattern = xzalloc(2);) \ tabstop = 8; \ + IF_FEATURE_VI_SETOPTS(newindent--;) \ } while (0) #if ENABLE_FEATURE_VI_CRASHME @@ -2113,6 +2117,7 @@ static size_t indent_len(char *p) static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' { #if ENABLE_FEATURE_VI_SETOPTS +# define indentcol char_insert__indentcol size_t len; int col, ntab, nspc; #endif @@ -2141,7 +2146,8 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' #if ENABLE_FEATURE_VI_SETOPTS if (autoindent) { len = indent_len(bol); - if (len && get_column(bol + len) == indentcol && bol[len] == '\n') { + col = get_column(bol + len); + if (len && col == indentcol && bol[len] == '\n') { // remove autoindent from otherwise empty line text_hole_delete(bol, bol + len - 1, undo); p = bol; @@ -2210,26 +2216,30 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' showmatching(p - 1); } if (autoindent && c == '\n') { // auto indent the new line - // use indent of current/previous line - bol = indentcol < 0 ? p : prev_line(p); - len = indent_len(bol); - col = get_column(bol + len); - - if (len && col == indentcol) { - // previous line was empty except for autoindent - // move the indent to the current line - memmove(bol + 1, bol, len); - *bol = '\n'; - return p; + if (newindent < 0) { + // use indent of previous line + bol = prev_line(p); + len = indent_len(bol); + col = get_column(bol + len); + + if (len && col == indentcol) { + // previous line was empty except for autoindent + // move the indent to the current line + memmove(bol + 1, bol, len); + *bol = '\n'; + return p; + } + } else { + // for 'O'/'cc' commands add indent before newly inserted NL + if (p != end - 1) // but not for 'cc' at EOF + p--; + col = newindent; } - if (indentcol < 0) - p--; // open above, indent before newly inserted NL - - if (len) { + if (col) { // only record indent if in insert/replace mode or for - // the 'o'/'O' commands, which are switched to insert - // mode early. + // the 'o'/'O'/'cc' commands, which are switched to + // insert mode early. indentcol = cmd_mode != 0 ? col : 0; if (expandtab) { ntab = 0; @@ -2252,6 +2262,7 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' } #if ENABLE_FEATURE_VI_SETOPTS indentcol = 0; +# undef indentcol #endif return p; } @@ -4220,6 +4231,9 @@ static void do_cmd(int c) case 'i': // i- insert before current char case KEYCODE_INSERT: // Cursor Key Insert dc_i: +#if ENABLE_FEATURE_VI_SETOPTS + newindent = -1; +#endif cmd_mode = 1; // start inserting undo_queue_commit(); // commit queue when cmd_mode changes break; @@ -4262,7 +4276,8 @@ static void do_cmd(int c) case 'O': // O- open an empty line above dot_begin(); #if ENABLE_FEATURE_VI_SETOPTS - indentcol = -1; + // special case: use indent of current line + newindent = get_column(dot + indent_len(dot)); #endif goto dc3; case 'o': // o- open an empty line below @@ -4385,14 +4400,22 @@ static void do_cmd(int c) if (buftype == WHOLE) { save_dot = p; // final cursor position is start of range p = begin_line(p); +#if ENABLE_FEATURE_VI_SETOPTS + if (c == 'c') // special case: use indent of current line + newindent = get_column(p + indent_len(p)); +#endif q = end_line(q); } dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO); // delete word if (buftype == WHOLE) { if (c == 'c') { +#if ENABLE_FEATURE_VI_SETOPTS + cmd_mode = 1; // switch to insert mode early +#endif dot = char_insert(dot, '\n', ALLOW_UNDO_CHAIN); - // on the last line of file don't move to prev line - if (dot != (end-1)) { + // on the last line of file don't move to prev line, + // handled in char_insert() if autoindent is enabled + if (dot != (end-1) && !autoindent) { dot_prev(); } } else if (c == 'd') { From bugzilla at busybox.net Sun Jun 26 18:21:14 2022 From: bugzilla at busybox.net (bugzilla at busybox.net) Date: Sun, 26 Jun 2022 18:21:14 +0000 Subject: [Bug 14866] sha256sum reports false mismatch if input not delimited by two spaces In-Reply-To: References: Message-ID: https://bugs.busybox.net/show_bug.cgi?id=14866 --- Comment #2 from rittneje+bugzilla at gmail.com --- Particularly with a Dockerfile, people are not always literally feeding the output of sha256sum to itself. It's pretty common to hand-write the echo instead. And the double space is very easy to overlook. As I mentioned, this is particularly confusing because (1) no other implementation of sha256sum cares, and (2) this implementation never clearly states what the problem is. Consequently people come to the conclusion that it is broken. -- You are receiving this mail because: You are on the CC list for the bug. From vda.linux at googlemail.com Thu Jun 30 15:18:12 2022 From: vda.linux at googlemail.com (Denys Vlasenko) Date: Thu, 30 Jun 2022 17:18:12 +0200 Subject: [git commit] tree: new applet Message-ID: <20220630150608.5EF55877E2@busybox.osuosl.org> commit: https://git.busybox.net/busybox/commit/?id=20a4f70ecaad79bb932af09b7317a058872cd867 branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master Adds the tree program to list directories and files in a tree structure. function old new delta tree_print - 343 +343 scandir64 - 330 +330 scandir - 330 +330 tree_main - 86 +86 .rodata 105150 105228 +78 packed_usage 34511 34557 +46 alphasort64 - 31 +31 alphasort - 31 +31 strcoll - 5 +5 applet_names 2801 2806 +5 applet_main 1616 1620 +4 applet_suid 101 102 +1 applet_install_loc 202 203 +1 ------------------------------------------------------------------------------ (add/remove: 11/0 grow/shrink: 6/0 up/down: 1291/0) Total: 1291 bytes Signed-off-by: Roger Knecht Signed-off-by: Denys Vlasenko --- AUTHORS | 3 ++ miscutils/tree.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ testsuite/tree.tests | 100 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) 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..8b16c5383 --- /dev/null +++ b/miscutils/tree.c @@ -0,0 +1,118 @@ +/* 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 y +//config: help +//config: List files and directories in a tree structure. + +//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" +#include "common_bufsiz.h" + +#define prefix_buf bb_common_bufsiz1 + +static void tree_print(unsigned count[2], const char* directory_name, char* prefix_pos) +{ + struct dirent **entries; + int index, size; + + // 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); + + // print all directory entries + for (index = 0; index < size;) { + struct dirent *dirent = entries[index++]; + + // filter hidden files and directories + if (dirent->d_name[0] != '.') { + int status; + struct stat statBuf; + +//TODO: when -l is implemented, use stat, not lstat, if -l + status = lstat(dirent->d_name, &statBuf); + + if (index == size) { + strcpy(prefix_pos, "????????? "); + } else { + strcpy(prefix_pos, "????????? "); + } + fputs_stdout(prefix_buf); + + if (status == 0 && S_ISLNK(statBuf.st_mode)) { + // handle symlink + char* symlink_path = xmalloc_readlink(dirent->d_name); + printf("%s -> %s\n", dirent->d_name, symlink_path); + free(symlink_path); + count[1]++; + } else if (status == 0 && S_ISDIR(statBuf.st_mode) + && (prefix_pos - prefix_buf) < (COMMON_BUFSIZE - 16) + ) { + // handle directory + char* pos; + if (index == size) { + pos = stpcpy(prefix_pos, " "); + } else { + pos = stpcpy(prefix_pos, "??????? "); + } + tree_print(count, dirent->d_name, pos); + count[0]++; + } else { + // handle file + puts(dirent->d_name); + count[1]++; + } + } + + // 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 UNUSED_PARAM, char **argv) +{ + unsigned count[2] = { 0, 0 }; + + setup_common_bufsiz(); + + if (!argv[1]) + *argv-- = (char*)"."; + + // list directories given as command line arguments + while (*(++argv)) + tree_print(count, *argv, prefix_buf); + + // print statistic + printf("\n%u directories, %u files\n", count[0], count[1]); + + return EXIT_SUCCESS; +} diff --git a/testsuite/tree.tests b/testsuite/tree.tests new file mode 100755 index 000000000..4f4a9e30b --- /dev/null +++ b/testsuite/tree.tests @@ -0,0 +1,100 @@ +#!/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\ +7 directories, 8 files\n" \ + "" "" +#note: tree v2.0.1 says "8 directories, 7 files": +#it counts "test3 -> ../../test3" as a directory, even though it does not follow this symlink + +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\ +7 directories, 9 files\n" \ + "" "" +#note: tree v2.0.1 says "8 directories, 7 files" (not "8 files", probably a/testfile4 -> ../b/testfile4 and b/testfile4 are counted as one file, not 2?) + +rm -rf tree.tempdir tree2.tempdir tree3.tempdir + +exit $FAILCOUNT