From 878fd59d878b00f26df441ff2e88b83223c2651a Mon Sep 17 00:00:00 2001 From: emaste Date: Sun, 1 Sep 2019 16:12:05 +0000 Subject: [PATCH] libc: remove gets gets is unsafe and shouldn't be used (for many years now). Leave it in the existing symbol version so anything that previously linked aginst it still runs, but do not allow new software to link against it. (The compatability/legacy implementation must not be static so that the symbol and in particular the compat sym gets@FBSD_1.0 make it into libc.) PR: 222796 (exp-run) Reported by: Paul Vixie Reviewed by: allanjude, cy, eadler, gnn, jhb, kib, ngie (some earlier) Relnotes: Yes Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D12298 --- contrib/libc++/include/cstdio | 4 -- contrib/netbsd-tests/lib/libc/ssp/h_gets.c | 18 ++++++++ gnu/lib/libssp/Makefile | 2 +- include/stdio.h | 1 - lib/libc/stdio/fgets.3 | 48 ++++------------------ lib/libc/stdio/gets.c | 5 +-- lib/libc/stdio/stdio.3 | 1 - 7 files changed, 29 insertions(+), 50 deletions(-) diff --git a/contrib/libc++/include/cstdio b/contrib/libc++/include/cstdio index 00b989fad7c..6b69f5e89c1 100644 --- a/contrib/libc++/include/cstdio +++ b/contrib/libc++/include/cstdio @@ -74,7 +74,6 @@ int fputc(int c, FILE* stream); int fputs(const char* restrict s, FILE* restrict stream); int getc(FILE* stream); int getchar(void); -char* gets(char* s); // removed in C++14 int putc(int c, FILE* stream); int putchar(int c); int puts(const char* s); @@ -153,9 +152,6 @@ using ::tmpnam; #ifndef _LIBCPP_HAS_NO_STDIN using ::getchar; -#if _LIBCPP_STD_VER <= 11 && !defined(_LIBCPP_MSVCRT) -using ::gets; -#endif using ::scanf; using ::vscanf; #endif diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_gets.c b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c index 8c601b0a8c5..f73d29a08bf 100644 --- a/contrib/netbsd-tests/lib/libc/ssp/h_gets.c +++ b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c @@ -33,6 +33,24 @@ __RCSID("$NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); #include +#ifdef __FreeBSD__ +/* + * We want to test the gets() implementation, but cannot simply link against + * the gets symbol because it is not in the default version. (We've made it + * unavailable by default on FreeBSD because it should not be used.) + * + * The next two lines create an unsafe_gets() function that resolves to + * gets@FBSD_1.0, which we call from our local gets() implementation. + */ +__sym_compat(gets, unsafe_gets, FBSD_1.0); +char *unsafe_gets(char *); + +char *gets(char *buf) +{ + return unsafe_gets(buf); +} +#endif + int main(int argc, char *argv[]) { diff --git a/gnu/lib/libssp/Makefile b/gnu/lib/libssp/Makefile index e611f5dfee4..51e36d5ddb7 100644 --- a/gnu/lib/libssp/Makefile +++ b/gnu/lib/libssp/Makefile @@ -17,7 +17,7 @@ LIB= ssp SHLIB_MAJOR= 0 LD_FATAL_WARNINGS= no -SRCS= ssp.c gets-chk.c memcpy-chk.c memmove-chk.c mempcpy-chk.c \ +SRCS= ssp.c memcpy-chk.c memmove-chk.c mempcpy-chk.c \ memset-chk.c snprintf-chk.c sprintf-chk.c stpcpy-chk.c \ strcat-chk.c strcpy-chk.c strncat-chk.c strncpy-chk.c \ vsnprintf-chk.c vsprintf-chk.c diff --git a/include/stdio.h b/include/stdio.h index e94583097a2..41ae893dd7d 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -269,7 +269,6 @@ long ftell(FILE *); size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict); int getc(FILE *); int getchar(void); -char *gets(char *); #if __EXT1_VISIBLE char *gets_s(char *, rsize_t); #endif diff --git a/lib/libc/stdio/fgets.3 b/lib/libc/stdio/fgets.3 index ce334b7493b..8b4bd388b7e 100644 --- a/lib/libc/stdio/fgets.3 +++ b/lib/libc/stdio/fgets.3 @@ -32,12 +32,11 @@ .\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 3, 2018 +.Dd September 1, 2019 .Dt FGETS 3 .Os .Sh NAME .Nm fgets , -.Nm gets , .Nm gets_s .Nd get a line from a stream .Sh LIBRARY @@ -48,8 +47,6 @@ .Fn fgets "char * restrict str" "int size" "FILE * restrict stream" .Ft char * .Fn gets_s "char *str" "rsize_t size" -.Ft char * -.Fn gets "char *str" .Sh DESCRIPTION The .Fn fgets @@ -81,23 +78,12 @@ except that the newline character (if any) is not stored in the string. The .Fn gets function -is equivalent to -.Fn fgets -with an infinite -.Fa size -and a -.Fa stream -of -.Dv stdin , -except that the newline character (if any) is not stored in the string. -It is the caller's responsibility to ensure that the input line, -if any, is sufficiently short to fit in the string. +was unsafe and is no longer available. .Sh RETURN VALUES Upon successful completion, -.Fn fgets , -.Fn gets_s , +.Fn fgets and -.Fn gets +.Fn gets_s return a pointer to the string. If end-of-file occurs before any characters are read, @@ -109,10 +95,9 @@ they return .Dv NULL and the buffer contents are indeterminate. The -.Fn fgets , -.Fn gets_s , +.Fn fgets and -.Fn gets +.Fn gets_s functions do not distinguish between end-of-file and error, and callers must use .Xr feof 3 @@ -139,8 +124,6 @@ or .Xr malloc 3 . .Pp The function -.Fn gets -and .Fn gets_s may also fail and set .Va errno @@ -153,11 +136,9 @@ for any of the errors specified for the routine .Xr fgetws 3 , .Xr getline 3 .Sh STANDARDS -The functions +The .Fn fgets -and -.Fn gets -conform to +function conforms to .St -isoC-99 . .Fn gets_s conforms to @@ -166,16 +147,3 @@ K.3.7.4.1. .Fn gets has been removed from .St -isoC-2011 . -.Sh SECURITY CONSIDERATIONS -The -.Fn gets -function cannot be used securely. -Because of its lack of bounds checking, -and the inability for the calling program -to reliably determine the length of the next incoming line, -the use of this function enables malicious users -to arbitrarily change a running program's functionality through -a buffer overflow attack. -It is strongly suggested that the -.Fn fgets -function be used in all cases. diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c index 1f360ac5ae6..c8822e3b8d8 100644 --- a/lib/libc/stdio/gets.c +++ b/lib/libc/stdio/gets.c @@ -45,10 +45,8 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" #include "local.h" -__warn_references(gets, "warning: this program uses gets(), which is unsafe."); - char * -gets(char *buf) +__gets_unsafe(char *buf) { int c; char *s, *ret; @@ -78,3 +76,4 @@ end: FUNLOCKFILE_CANCELSAFE(); return (ret); } +__sym_compat(gets, __gets_unsafe, FBSD_1.0); diff --git a/lib/libc/stdio/stdio.3 b/lib/libc/stdio/stdio.3 index 0ac315b957c..7b3dd364c79 100644 --- a/lib/libc/stdio/stdio.3 +++ b/lib/libc/stdio/stdio.3 @@ -279,7 +279,6 @@ library conforms to .It "getchar get next character or word from input stream" .It "getdelim get a line from a stream" .It "getline get a line from a stream" -.It "gets get a line from a stream" .It "getw get next character or word from input stream" .It "getwc get next wide character from input stream" .It "getwchar get next wide character from input stream" -- 2.39.5