Download raw body.
lang/gbc write overflow
Ok from me.
On Wed, Mar 27, 2024, 7:04 PM George Koehler <kernigh@gmail.com> wrote:
> Here's a diff to fix GNU bc 1.07.1 in OpenBSD ports.
>
> Wrong code in bc/scan.c was using (yy_size_t *)&result to write to an
> int. This was an overflow on LP64_ARCHS, by writing 8 bytes to a
> 4-byte int. The problem was more obvious when big-endian.
>
> If we would read 51 bytes,
> - a little-endian amd64 would write (int []){51, 0}, so result = 51
> was correct, but the extra 0 clobbered 4 bytes of other memory.
> - my big-endian powerpc64 wrote (int []){0, 51}, so result = 0 caused
> an early end of file. This broke my powerpc64 build when bc tried
> to compile its math library, but the compiled code was empty.
>
> The new patch does "result = ...", so the C compiler writes the
> correct size. Now my powerpc64 can package and run gbc.
>
> The patch causes flex(1) to remake scan.c from scan.l. OpenBSD's
> flex changes result from int to yy_size_t, but "result = ..." should
> work with either type. (When I tried (int *)&result, I built a broken
> bc that wrote 4 bytes to an 8-byte size.)
>
> Also delete BROKEN-sparc64, but I don't have a sparc64. I suspect
> that (yy_size_t *)&result was not a multiple of 8 and raised a SIGBUS
> for misalignment on sparc64, but I don't know.
>
> ok?
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/math/gbc/Makefile,v
> diff -u -p -r1.6 Makefile
> --- Makefile 27 Sep 2023 09:27:54 -0000 1.6
> +++ Makefile 27 Mar 2024 22:04:45 -0000
> @@ -1,9 +1,7 @@
> -BROKEN-sparc64 = Bus error during build
> -
> COMMENT = GNU version of the arbitrary precision calculators bc and
> dc
> DISTNAME = bc-1.07.1
> PKGNAME = g${DISTNAME}
> -REVISION = 0
> +REVISION = 1
> CATEGORIES = math
>
> HOMEPAGE = https://www.gnu.org/software/bc/
> Index: patches/patch-bc_scan_l
> ===================================================================
> RCS file: patches/patch-bc_scan_l
> diff -N patches/patch-bc_scan_l
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-bc_scan_l 27 Mar 2024 22:04:45 -0000
> @@ -0,0 +1,74 @@
> +The cast (yy_size_t *)&result was wrong, because result was an int in
> +upstream's flex; this caused an overflow on LP64_ARCHS (by writing 8
> +bytes to a 4-byte int), which broke the build on powerpc64.
> +
> +This patch causes the build to run flex(1), overwriting scan.c from
> +upstream. OpenBSD's flex changes result from int to yy_size_t.
> +
> +Index: bc/scan.l
> +--- bc/scan.l.orig
> ++++ bc/scan.l
> +@@ -59,7 +59,7 @@ int yywrap (void);
> + /* Have input call the following function. */
> + #undef YY_INPUT
> + #define YY_INPUT(buf,result,max_size) \
> +- bcel_input((char *)buf, (yy_size_t *)&result, max_size)
> ++ result = bcel_input((char *)buf, max_size)
> +
> + /* Variables to help interface editline with bc. */
> + static const char *bcel_line = (char *)NULL;
> +@@ -70,10 +70,11 @@ static int bcel_len = 0;
> + stdin, use editline. Otherwise, just read it.
> + */
> +
> +-static void
> +-bcel_input (char *buf, yy_size_t *result, int max)
> ++static int
> ++bcel_input (char *buf, int max)
> + {
> + ssize_t rdsize;
> ++ int result;
> + if (!edit || yyin != stdin)
> + {
> + while ( (rdsize = read( fileno(yyin), buf, max )) < 0 )
> +@@ -82,8 +83,7 @@ bcel_input (char *buf, yy_size_t *result, int max)
> + yyerror( "read() in flex scanner failed" );
> + bc_exit (1);
> + }
> +- *result = (yy_size_t) rdsize;
> +- return;
> ++ return rdsize;
> + }
> +
> + /* Do we need a new string? */
> +@@ -92,9 +92,8 @@ bcel_input (char *buf, yy_size_t *result, int max)
> + bcel_line = el_gets(edit, &bcel_len);
> + if (bcel_line == NULL) {
> + /* end of file */
> +- *result = 0;
> + bcel_len = 0;
> +- return;
> ++ return 0;
> + }
> + if (bcel_len != 0)
> + history (hist, &histev, H_ENTER, bcel_line);
> +@@ -104,16 +103,17 @@ bcel_input (char *buf, yy_size_t *result, int max)
> + if (bcel_len <= max)
> + {
> + strncpy (buf, bcel_line, bcel_len);
> +- *result = bcel_len;
> ++ result = bcel_len;
> + bcel_len = 0;
> + }
> + else
> + {
> + strncpy (buf, bcel_line, max);
> +- *result = max;
> ++ result = max;
> + bcel_line += max;
> + bcel_len -= max;
> + }
> ++ return result;
> + }
> + #endif
> +
>
lang/gbc write overflow