Module Name: src Committed By: rillig Date: Fri Oct 29 19:12:49 UTC 2021
Modified Files: src/usr.bin/indent: indent.c io.c pr_comment.c Log Message: indent: fix undefined behavior in buffer handling Adding an arbitrary integer to a pointer may result in an out of bounds pointer, so replace the addition with a pointer subtraction. In the buffer handling functions, handle 'buf' and 'l' before 's' and 'e', since they are pairs. In inbuf_read_line, use 's' instead of 'buf' to make the code easier to understand for human readers. No functional change. To generate a diff of this commit: cvs rdiff -u -r1.172 -r1.173 src/usr.bin/indent/indent.c cvs rdiff -u -r1.105 -r1.106 src/usr.bin/indent/io.c cvs rdiff -u -r1.88 -r1.89 src/usr.bin/indent/pr_comment.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/indent/indent.c diff -u src/usr.bin/indent/indent.c:1.172 src/usr.bin/indent/indent.c:1.173 --- src/usr.bin/indent/indent.c:1.172 Fri Oct 29 18:50:52 2021 +++ src/usr.bin/indent/indent.c Fri Oct 29 19:12:48 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: indent.c,v 1.172 2021/10/29 18:50:52 rillig Exp $ */ +/* $NetBSD: indent.c,v 1.173 2021/10/29 19:12:48 rillig Exp $ */ /*- * SPDX-License-Identifier: BSD-4-Clause @@ -43,7 +43,7 @@ static char sccsid[] = "@(#)indent.c 5.1 #include <sys/cdefs.h> #if defined(__NetBSD__) -__RCSID("$NetBSD: indent.c,v 1.172 2021/10/29 18:50:52 rillig Exp $"); +__RCSID("$NetBSD: indent.c,v 1.173 2021/10/29 19:12:48 rillig Exp $"); #elif defined(__FreeBSD__) __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $"); #endif @@ -390,11 +390,11 @@ buf_init(struct buffer *buf) { size_t size = 200; buf->buf = xmalloc(size); - buf->buf[0] = ' '; /* allow accessing buf->e[-1] */ - buf->buf[1] = '\0'; - buf->s = buf->buf + 1; + buf->l = buf->buf + size - 5 /* safety margin */; + buf->s = buf->buf + 1; /* allow accessing buf->e[-1] */ buf->e = buf->s; - buf->l = buf->buf + size - 5; /* safety margin */ + buf->buf[0] = ' '; + buf->buf[1] = '\0'; } static size_t @@ -404,20 +404,21 @@ buf_len(const struct buffer *buf) } void -buf_expand(struct buffer *buf, size_t desired_size) +buf_expand(struct buffer *buf, size_t add_size) { - size_t nsize = (size_t)(buf->l - buf->s) + 400 + desired_size; + size_t new_size = (size_t)(buf->l - buf->s) + 400 + add_size; size_t len = buf_len(buf); - buf->buf = xrealloc(buf->buf, nsize); - buf->e = buf->buf + len + 1; - buf->l = buf->buf + nsize - 5; + buf->buf = xrealloc(buf->buf, new_size); + buf->l = buf->buf + new_size - 5; buf->s = buf->buf + 1; + buf->e = buf->s + len; + /* At this point, the buffer may not be null-terminated anymore. */ } static void buf_reserve(struct buffer *buf, size_t n) { - if (buf->e + n >= buf->l) + if (n >= (size_t)(buf->l - buf->e)) buf_expand(buf, n); } @@ -467,7 +468,9 @@ main_init_globals(void) inp.buf = xmalloc(10); inp.l = inp.buf + 8; - inp.s = inp.e = inp.buf; + inp.s = inp.buf; + inp.e = inp.buf; + line_no = 1; had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; Index: src/usr.bin/indent/io.c diff -u src/usr.bin/indent/io.c:1.105 src/usr.bin/indent/io.c:1.106 --- src/usr.bin/indent/io.c:1.105 Fri Oct 29 18:18:03 2021 +++ src/usr.bin/indent/io.c Fri Oct 29 19:12:48 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: io.c,v 1.105 2021/10/29 18:18:03 rillig Exp $ */ +/* $NetBSD: io.c,v 1.106 2021/10/29 19:12:48 rillig Exp $ */ /*- * SPDX-License-Identifier: BSD-4-Clause @@ -43,7 +43,7 @@ static char sccsid[] = "@(#)io.c 8.1 (Be #include <sys/cdefs.h> #if defined(__NetBSD__) -__RCSID("$NetBSD: io.c,v 1.105 2021/10/29 18:18:03 rillig Exp $"); +__RCSID("$NetBSD: io.c,v 1.106 2021/10/29 19:12:48 rillig Exp $"); #elif defined(__FreeBSD__) __FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $"); #endif @@ -448,8 +448,8 @@ inbuf_read_line(void) inp.s = inp.buf; inp.e = p; - if (p - inp.buf >= 3 && p[-3] == '*' && p[-2] == '/') { - if (strncmp(inp.buf, "/**INDENT**", 11) == 0) + if (p - inp.s >= 3 && p[-3] == '*' && p[-2] == '/') { + if (strncmp(inp.s, "/**INDENT**", 11) == 0) inbuf_read_line(); /* flush indent error message */ else parse_indent_comment(); Index: src/usr.bin/indent/pr_comment.c diff -u src/usr.bin/indent/pr_comment.c:1.88 src/usr.bin/indent/pr_comment.c:1.89 --- src/usr.bin/indent/pr_comment.c:1.88 Fri Oct 29 17:50:37 2021 +++ src/usr.bin/indent/pr_comment.c Fri Oct 29 19:12:48 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pr_comment.c,v 1.88 2021/10/29 17:50:37 rillig Exp $ */ +/* $NetBSD: pr_comment.c,v 1.89 2021/10/29 19:12:48 rillig Exp $ */ /*- * SPDX-License-Identifier: BSD-4-Clause @@ -43,7 +43,7 @@ static char sccsid[] = "@(#)pr_comment.c #include <sys/cdefs.h> #if defined(__NetBSD__) -__RCSID("$NetBSD: pr_comment.c,v 1.88 2021/10/29 17:50:37 rillig Exp $"); +__RCSID("$NetBSD: pr_comment.c,v 1.89 2021/10/29 19:12:48 rillig Exp $"); #elif defined(__FreeBSD__) __FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $"); #endif @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD: head/usr.bin/indent/ static void com_add_char(char ch) { - if (com.e + 1 >= com.l) + if (1 >= com.l - com.e) buf_expand(&com, 1); *com.e++ = ch; } @@ -69,7 +69,7 @@ com_add_delim(void) if (!opt.star_comment_cont) return; size_t len = 3; - if (com.e + len >= com.l) + if (len >= (size_t)(com.l - com.e)) buf_expand(&com, len); memcpy(com.e, " * ", len); com.e += len; @@ -78,7 +78,7 @@ com_add_delim(void) static void com_terminate(void) { - if (com.e + 1 >= com.l) + if (1 >= com.l - com.e) buf_expand(&com, 1); *com.e = '\0'; } @@ -190,6 +190,9 @@ process_comment(void) /* * XXX: ordered comparison between pointers from different objects * invokes undefined behavior (C99 6.5.8). + * + * XXX: It's easier to understand if inp.s is used instead of inp.buf, + * since inp.buf is only intended to be used for allocation purposes. */ start = inp.s >= save_com && inp.s < save_com + sc_size ? sc_buf : inp.buf;