Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Aug 2017 04:18:31 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r322608 - in stable/11: contrib/netbsd-tests/usr.bin/grep usr.bin/grep
Message-ID:  <201708170418.v7H4IVEM012002@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Thu Aug 17 04:18:31 2017
New Revision: 322608
URL: https://svnweb.freebsd.org/changeset/base/322608

Log:
  bsdgrep: fix segfault with --mmap and add relevant test
  
  MFC r318565: bsdgrep: fix segfault with --mmap
  
  r313948 partially fixed --mmap behavior but was incomplete.  This commit
  generally reverts it and does it the more correct way- by just consuming
  the rest of the buffer and moving on.
  
  MFC r318908: bsdgrep: add --mmap tests
  
  Basic sanity tests as well as coverage for the bug fixed in r318565.
  
  PR:		219402
  Approved by:	emaste (mentor, blanket MFC)

Modified:
  stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh
  stable/11/usr.bin/grep/file.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh
==============================================================================
--- stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh	Thu Aug 17 04:04:42 2017	(r322607)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh	Thu Aug 17 04:18:31 2017	(r322608)
@@ -574,6 +574,46 @@ binary_flags_body()
 	atf_check -o inline:"A\000B\000C\n" grep --binary-files=text 'B' test1
 	atf_check -s exit:1 grep --binary-files=without-match 'B' test2
 }
+
+atf_test_case mmap
+mmap_head()
+{
+	atf_set "descr" "Check basic matching with --mmap flag"
+}
+mmap_body()
+{
+	grep_type
+	if [ $? -eq $GREP_TYPE_GNU ]; then
+		atf_expect_fail "gnu grep from ports has no --mmap option"
+	fi
+
+	printf "A\nB\nC\n" > test1
+
+	atf_check -s exit:0 -o inline:"B\n" grep --mmap -oe "B" test1
+	atf_check -s exit:1 grep --mmap -e "Z" test1
+}
+
+atf_test_case mmap_eof_not_eol
+mmap_eof_not_eol_head()
+{
+	atf_set "descr" "Check --mmap flag handling of encountering EOF without EOL (PR 165471, 219402)"
+}
+mmap_eof_not_eol_body()
+{
+	grep_type
+	if [ $? -eq $GREP_TYPE_GNU ]; then
+		atf_expect_fail "gnu grep from ports has no --mmap option"
+	fi
+
+	printf "ABC" > test1
+	jot -b " "  -s "" 4096 >> test2
+
+	atf_check -s exit:0 -o inline:"B\n" grep --mmap -oe "B" test1
+	# Dependency on jemalloc(3) to detect buffer overflow, otherwise this
+	# unreliably produces a SIGSEGV or SIGBUS
+	atf_check -s exit:0 -o not-empty \
+	    env MALLOC_CONF="redzone:true" grep --mmap -e " " test2
+}
 # End FreeBSD
 
 atf_init_test_cases()
@@ -610,5 +650,7 @@ atf_init_test_cases()
 	atf_add_test_case grep_nomatch_flags
 	atf_add_test_case binary_flags
 	atf_add_test_case badcontext
+	atf_add_test_case mmap
+	atf_add_test_case mmap_eof_not_eol
 # End FreeBSD
 }

Modified: stable/11/usr.bin/grep/file.c
==============================================================================
--- stable/11/usr.bin/grep/file.c	Thu Aug 17 04:04:42 2017	(r322607)
+++ stable/11/usr.bin/grep/file.c	Thu Aug 17 04:18:31 2017	(r322608)
@@ -213,24 +213,24 @@ grep_fgetln(struct file *f, size_t *lenp)
 		if (grep_lnbufgrow(len + LNBUFBUMP))
 			goto error;
 		memcpy(lnbuf + off, bufpos, len - off);
+		/* With FILE_MMAP, this is EOF; there's no more to refill */
+		if (filebehave == FILE_MMAP) {
+			bufrem -= len;
+			break;
+		}
 		off = len;
+		/* Fetch more to try and find EOL/EOF */
 		if (grep_refill(f) != 0)
 			goto error;
 		if (bufrem == 0)
 			/* EOF: return partial line */
 			break;
-		if ((p = memchr(bufpos, fileeol, bufrem)) == NULL &&
-		    filebehave != FILE_MMAP)
+		if ((p = memchr(bufpos, fileeol, bufrem)) == NULL)
 			continue;
-		if (p == NULL) {
-			/* mmap EOF: return partial line, consume buffer */
-			diff = len;
-		} else {
-			/* got it: finish up the line (like code above) */
-			++p;
-			diff = p - bufpos;
-			len += diff;
-		}
+		/* got it: finish up the line (like code above) */
+		++p;
+		diff = p - bufpos;
+		len += diff;
 		if (grep_lnbufgrow(len))
 		    goto error;
 		memcpy(lnbuf + off, bufpos, diff);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708170418.v7H4IVEM012002>