Module Name:    src
Committed By:   riastradh
Date:           Sun Mar 30 15:38:38 UTC 2025

Modified Files:
        src/lib/libc/gen: ctype_guard.h
        src/tests/lib/libc/gen: Makefile t_ctype.c

Log Message:
ctype(3): Disable guard page in static libc.

Adding the guard page may have overflown several small installation
media.  Let's try to keep this case small.

Update the tests to detect the cases where we will be running against
a libc without a guard page on the LC_CTYPE=C tables, and skip
testing abuse detection when it would rely on the guard page.

PR lib/58208: ctype(3) provides poor runtime feedback of abuse


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/gen/ctype_guard.h
cvs rdiff -u -r1.58 -r1.59 src/tests/lib/libc/gen/Makefile
cvs rdiff -u -r1.10 -r1.11 src/tests/lib/libc/gen/t_ctype.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/gen/ctype_guard.h
diff -u src/lib/libc/gen/ctype_guard.h:1.3 src/lib/libc/gen/ctype_guard.h:1.4
--- src/lib/libc/gen/ctype_guard.h:1.3	Sun Mar 30 00:07:51 2025
+++ src/lib/libc/gen/ctype_guard.h	Sun Mar 30 15:38:38 2025
@@ -1,4 +1,4 @@
-/*	$NetBSD: ctype_guard.h,v 1.3 2025/03/30 00:07:51 riastradh Exp $	*/
+/*	$NetBSD: ctype_guard.h,v 1.4 2025/03/30 15:38:38 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2025 The NetBSD Foundation, Inc.
@@ -94,9 +94,11 @@
  * additional arithmetic relative to _C_ctype_tab_guarded_.
  */
 
-#ifndef __CHAR_UNSIGNED__
+#if defined(__CHAR_UNSIGNED__)	/* disable if char is unsigned */
+#  define	_CTYPE_GUARD_PAGE	0
+#elif defined(__PIC__)		/* enable in shared libc */
 #  define	_CTYPE_GUARD_PAGE	1
-#else
+#else	/* static libc -- let's aim for space-efficiency for now */
 #  define	_CTYPE_GUARD_PAGE	0
 #endif
 

Index: src/tests/lib/libc/gen/Makefile
diff -u src/tests/lib/libc/gen/Makefile:1.58 src/tests/lib/libc/gen/Makefile:1.59
--- src/tests/lib/libc/gen/Makefile:1.58	Fri Mar 28 18:41:55 2025
+++ src/tests/lib/libc/gen/Makefile	Sun Mar 30 15:38:38 2025
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.58 2025/03/28 18:41:55 riastradh Exp $
+# $NetBSD: Makefile,v 1.59 2025/03/30 15:38:38 riastradh Exp $
 
 NOMAN=		# defined
 
@@ -52,6 +52,8 @@ COPTS.t_siginfo.c+=	-DENABLE_TESTS
 .endif
 
 CPPFLAGS.t_arc4random.c+=-I${NETBSDSRCDIR}/lib/libc/include
+CPPFLAGS.t_ctype.c+=	\
+	${"${MKPIC}" == "no" || "${LDSTATIC:U}" == "-static":?-D_CTYPE_GUARD_PAGE=0:}
 CPPFLAGS.t_siginfo.c+=-D__TEST_FENV
 COPTS.t_fpsetround.c+=${${ACTIVE_CC} == "gcc":? -frounding-math :}
 

Index: src/tests/lib/libc/gen/t_ctype.c
diff -u src/tests/lib/libc/gen/t_ctype.c:1.10 src/tests/lib/libc/gen/t_ctype.c:1.11
--- src/tests/lib/libc/gen/t_ctype.c:1.10	Sat Mar 29 19:40:42 2025
+++ src/tests/lib/libc/gen/t_ctype.c	Sun Mar 30 15:38:38 2025
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ctype.c,v 1.10 2025/03/29 19:40:42 riastradh Exp $	*/
+/*	$NetBSD: t_ctype.c,v 1.11 2025/03/30 15:38:38 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2025 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ctype.c,v 1.10 2025/03/29 19:40:42 riastradh Exp $");
+__RCSID("$NetBSD: t_ctype.c,v 1.11 2025/03/30 15:38:38 riastradh Exp $");
 
 #include <atf-c.h>
 #include <ctype.h>
@@ -45,6 +45,20 @@ enum { CHAR_UNSIGNED = 1 };
 enum { CHAR_UNSIGNED = 0 };
 #endif
 
+/*
+ * libc has a guard page for the LC_CTYPE=C ctype(3) tables only on
+ * some platforms.  We skip it if char is unsigned (in which case the
+ * common kind of ctype(3) abuse is unlikely).  We also skip it in
+ * static builds -- this is determined in the Makefile.
+ */
+#ifndef _CTYPE_GUARD_PAGE
+#  ifdef __CHAR_UNSIGNED__
+#    define	_CTYPE_GUARD_PAGE	0
+#  else
+#    define	_CTYPE_GUARD_PAGE	1
+#  endif
+#endif
+
 static const char *const locales[] = { "C.UTF-8", "fr_FR.ISO8859-1", "C" };
 
 static int isalpha_wrapper(int ch) { return isalpha(ch); }
@@ -109,6 +123,12 @@ test_abuse_in_locales(const char *name, 
 	for (i = 0; i < __arraycount(locales); i++) {
 		char buf[128];
 
+		if (!_CTYPE_GUARD_PAGE && macro &&
+		    strcmp(locales[i], "C") == 0) {
+			fprintf(stderr, "skip LC_CTYPE=C ctype(3) abuse --"
+			    " no libc guard page on this platform\n");
+		}
+
 		ATF_REQUIRE_MSG(setlocale(LC_CTYPE, locales[i]) != NULL,
 		    "locales[i]=%s", locales[i]);
 		snprintf(buf, sizeof(buf), "[%s]%s", locales[i], name);
@@ -783,6 +803,8 @@ ATF_TC_BODY(abuse_##FN##_macro_c, tc)			
 		atf_tc_skip("runtime ctype(3) abuse is impossible with"	      \
 		    " unsigned char");					      \
 	}								      \
+	if (!_CTYPE_GUARD_PAGE)						      \
+		atf_tc_skip("no LC_CTYPE=C guard page on this platform");     \
 	test_abuse(#FN, &FN##_wrapper);					      \
 }									      \
 ATF_TC(abuse_##FN##_function_c);					      \
@@ -797,6 +819,8 @@ ATF_TC_BODY(abuse_##FN##_function_c, tc)
 		atf_tc_skip("runtime ctype(3) abuse is impossible with"	      \
 		    " unsigned char");					      \
 	}								      \
+	if (!_CTYPE_GUARD_PAGE)						      \
+		atf_tc_skip("no LC_CTYPE=C guard page on this platform");     \
 	test_abuse(#FN, &FN);						      \
 }									      \
 ATF_TC(abuse_##FN##_macro_locale);					      \

Reply via email to