svn commit: r291293 - in stable/10: lib/libc/stdio tools/regression/lib/libc/stdio

Garrett Cooper ngie at FreeBSD.org
Wed Nov 25 08:19:03 UTC 2015


Author: ngie
Date: Wed Nov 25 08:19:01 2015
New Revision: 291293
URL: https://svnweb.freebsd.org/changeset/base/291293

Log:
  MFC r264737:
  
  Discussed with: jilles
  
  r264737 (by jilles):
  
  libc/stdio: Fail fdopen() on an execute-only fd.
  
  An execute-only fd (opened with O_EXEC) allows neither read() nor write()
  and is therefore incompatible with all stdio modes. Therefore, the [EINVAL]
  error applies.
  
  Also adjust the similar check in freopen() with a NULL path, even though
  this checks an fd which is already from a FILE.

Added:
  stable/10/tools/regression/lib/libc/stdio/test-fdopen.c
     - copied unchanged from r264737, head/tools/regression/lib/libc/stdio/test-fdopen.c
  stable/10/tools/regression/lib/libc/stdio/test-fdopen.t
     - copied unchanged from r264737, head/tools/regression/lib/libc/stdio/test-fdopen.t
  stable/10/tools/regression/lib/libc/stdio/test-freopen.c
     - copied unchanged from r264737, head/tools/regression/lib/libc/stdio/test-freopen.c
  stable/10/tools/regression/lib/libc/stdio/test-freopen.t
     - copied unchanged from r264737, head/tools/regression/lib/libc/stdio/test-freopen.t
Modified:
  stable/10/lib/libc/stdio/fdopen.c
  stable/10/lib/libc/stdio/freopen.c
  stable/10/tools/regression/lib/libc/stdio/Makefile
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libc/stdio/fdopen.c
==============================================================================
--- stable/10/lib/libc/stdio/fdopen.c	Wed Nov 25 07:31:59 2015	(r291292)
+++ stable/10/lib/libc/stdio/fdopen.c	Wed Nov 25 08:19:01 2015	(r291293)
@@ -70,7 +70,8 @@ fdopen(int fd, const char *mode)
 	/* Make sure the mode the user wants is a subset of the actual mode. */
 	if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0)
 		return (NULL);
-	tmp = fdflags & O_ACCMODE;
+	/* Work around incorrect O_ACCMODE. */
+	tmp = fdflags & (O_ACCMODE | O_EXEC);
 	if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
 		errno = EINVAL;
 		return (NULL);

Modified: stable/10/lib/libc/stdio/freopen.c
==============================================================================
--- stable/10/lib/libc/stdio/freopen.c	Wed Nov 25 07:31:59 2015	(r291292)
+++ stable/10/lib/libc/stdio/freopen.c	Wed Nov 25 08:19:01 2015	(r291293)
@@ -92,8 +92,9 @@ freopen(const char * __restrict file, co
 			errno = sverrno;
 			return (NULL);
 		}
-		if ((dflags & O_ACCMODE) != O_RDWR && (dflags & O_ACCMODE) !=
-		    (oflags & O_ACCMODE)) {
+		/* Work around incorrect O_ACCMODE. */
+		if ((dflags & O_ACCMODE) != O_RDWR &&
+		    (dflags & (O_ACCMODE | O_EXEC)) != (oflags & O_ACCMODE)) {
 			fclose(fp);
 			FUNLOCKFILE(fp);
 			errno = EBADF;

Modified: stable/10/tools/regression/lib/libc/stdio/Makefile
==============================================================================
--- stable/10/tools/regression/lib/libc/stdio/Makefile	Wed Nov 25 07:31:59 2015	(r291292)
+++ stable/10/tools/regression/lib/libc/stdio/Makefile	Wed Nov 25 08:19:01 2015	(r291293)
@@ -1,6 +1,8 @@
 # $FreeBSD$
 
-TESTS=	test-fopen \
+TESTS=	test-fdopen \
+	test-fopen \
+	test-freopen \
 	test-getdelim \
 	test-mkostemp \
 	test-open_memstream \

Copied: stable/10/tools/regression/lib/libc/stdio/test-fdopen.c (from r264737, head/tools/regression/lib/libc/stdio/test-fdopen.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/tools/regression/lib/libc/stdio/test-fdopen.c	Wed Nov 25 08:19:01 2015	(r291293, copy of r264737, head/tools/regression/lib/libc/stdio/test-fdopen.c)
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2014 Jilles Tjoelker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include	<fcntl.h>
+#include	<stdbool.h>
+#include	<stdio.h>
+#include	<string.h>
+#include	<unistd.h>
+
+static int testnum = 1;
+
+static void
+runtest(const char *fname, int intmode, const char *strmode, bool success)
+{
+	FILE *fp;
+	int fd;
+
+	fd = open(fname, intmode);
+	if (fd == -1) {
+		printf("not ok %d - open(\"%s\", %#x) failed\n",
+		    testnum++, fname, intmode);
+		return;
+	}
+	fp = fdopen(fd, strmode);
+	if (fp == NULL) {
+		close(fd);
+		if (success)
+			printf("not ok %d - "
+			    "fdopen(open(\"%s\", %#x), \"%s\") failed\n",
+			    testnum++, fname, intmode, strmode);
+		else
+			printf("ok %d - "
+			    "fdopen(open(\"%s\", %#x), \"%s\") failed\n",
+			    testnum++, fname, intmode, strmode);
+		return;
+	}
+	if (success)
+		printf("ok %d - "
+		    "fdopen(open(\"%s\", %#x), \"%s\") succeeded\n",
+		    testnum++, fname, intmode, strmode);
+	else
+		printf("not ok %d - "
+		    "fdopen(open(\"%s\", %#x), \"%s\") succeeded\n",
+		    testnum++, fname, intmode, strmode);
+	fclose(fp);
+}
+
+/*
+ * Test program for fdopen().
+ */
+int
+main(int argc, char *argv[])
+{
+	printf("1..19\n");
+	runtest("/dev/null", O_RDONLY, "r", true);
+	runtest("/dev/null", O_WRONLY, "r", false);
+	runtest("/dev/null", O_RDWR, "r", true);
+	runtest("/dev/null", O_RDONLY, "w", false);
+	runtest("/dev/null", O_WRONLY, "w", true);
+	runtest("/dev/null", O_RDWR, "w", true);
+	runtest("/dev/null", O_RDONLY, "a", false);
+	runtest("/dev/null", O_WRONLY, "a", true);
+	runtest("/dev/null", O_RDWR, "a", true);
+	runtest("/dev/null", O_RDONLY, "r+", false);
+	runtest("/dev/null", O_WRONLY, "r+", false);
+	runtest("/dev/null", O_RDWR, "r+", true);
+	runtest("/dev/null", O_RDONLY, "w+", false);
+	runtest("/dev/null", O_WRONLY, "w+", false);
+	runtest("/dev/null", O_RDWR, "w+", true);
+	runtest("/bin/sh", O_EXEC, "r", false);
+	runtest("/bin/sh", O_EXEC, "w", false);
+	runtest("/bin/sh", O_EXEC, "r+", false);
+	runtest("/bin/sh", O_EXEC, "w+", false);
+
+	return 0;
+}
+
+/* vim:ts=8:cin:sw=8
+ *  */

Copied: stable/10/tools/regression/lib/libc/stdio/test-fdopen.t (from r264737, head/tools/regression/lib/libc/stdio/test-fdopen.t)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/tools/regression/lib/libc/stdio/test-fdopen.t	Wed Nov 25 08:19:01 2015	(r291293, copy of r264737, head/tools/regression/lib/libc/stdio/test-fdopen.t)
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable

Copied: stable/10/tools/regression/lib/libc/stdio/test-freopen.c (from r264737, head/tools/regression/lib/libc/stdio/test-freopen.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/tools/regression/lib/libc/stdio/test-freopen.c	Wed Nov 25 08:19:01 2015	(r291293, copy of r264737, head/tools/regression/lib/libc/stdio/test-freopen.c)
@@ -0,0 +1,109 @@
+/*-
+ * Copyright (c) 2014 Jilles Tjoelker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include	<stdbool.h>
+#include	<stdio.h>
+#include	<string.h>
+
+static int testnum = 1;
+
+static void
+runtest(const char *fname1, const char *mode1, const char *fname2,
+    const char *mode2, bool success)
+{
+	FILE *fp1, *fp2;
+	const char *fname2_print;
+
+	fname2_print = fname2 != NULL ? fname2 : "<NULL>";
+	fp1 = fopen(fname1, mode1);
+	if (fp1 == NULL) {
+		printf("not ok %d - fopen(\"%s\", \"%s\") failed\n",
+		    testnum++, fname1, mode1);
+		return;
+	}
+	fp2 = freopen(fname2, mode2, fp1);
+	if (fp2 == NULL) {
+		fclose(fp1);
+		if (success)
+			printf("not ok %d - "
+			    "freopen(\"%s\", \"%s\", fopen(\"%s\", \"%s\")) "
+			    "failed\n",
+			    testnum++, fname2_print, mode2, fname1, mode1);
+		else
+			printf("ok %d - "
+			    "freopen(\"%s\", \"%s\", fopen(\"%s\", \"%s\")) "
+			    "failed\n",
+			    testnum++, fname2_print, mode2, fname1, mode1);
+		return;
+	}
+	if (success)
+		printf("ok %d - "
+		    "freopen(\"%s\", \"%s\", fopen(\"%s\", \"%s\")) "
+		    "succeeded\n",
+		    testnum++, fname2_print, mode2, fname1, mode1);
+	else
+		printf("not ok %d - "
+		    "freopen(\"%s\", \"%s\", fopen(\"%s\", \"%s\")) "
+		    "succeeded\n",
+		    testnum++, fname2_print, mode2, fname1, mode1);
+	fclose(fp2);
+}
+
+/*
+ * Test program for freopen().
+ */
+int
+main(int argc, char *argv[])
+{
+	printf("1..19\n");
+	runtest("/dev/null", "r", NULL, "r", true);
+	runtest("/dev/null", "w", NULL, "r", false);
+	runtest("/dev/null", "r+", NULL, "r", true);
+	runtest("/dev/null", "r", NULL, "w", false);
+	runtest("/dev/null", "w", NULL, "w", true);
+	runtest("/dev/null", "r+", NULL, "w", true);
+	runtest("/dev/null", "r", NULL, "a", false);
+	runtest("/dev/null", "w", NULL, "a", true);
+	runtest("/dev/null", "r+", NULL, "a", true);
+	runtest("/dev/null", "r", NULL, "r+", false);
+	runtest("/dev/null", "w", NULL, "r+", false);
+	runtest("/dev/null", "r+", NULL, "r+", true);
+	runtest("/dev/null", "r", NULL, "w+", false);
+	runtest("/dev/null", "w", NULL, "w+", false);
+	runtest("/dev/null", "r+", NULL, "w+", true);
+	runtest("/bin/sh", "r", NULL, "r", true);
+	runtest("/bin/sh", "r", "/bin/sh", "r", true);
+	runtest("/bin/sh", "r", "/dev/null", "r", true);
+	runtest("/bin/sh", "r", "/dev/null", "w", true);
+
+	return 0;
+}
+
+/* vim:ts=8:cin:sw=8
+ *  */

Copied: stable/10/tools/regression/lib/libc/stdio/test-freopen.t (from r264737, head/tools/regression/lib/libc/stdio/test-freopen.t)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/tools/regression/lib/libc/stdio/test-freopen.t	Wed Nov 25 08:19:01 2015	(r291293, copy of r264737, head/tools/regression/lib/libc/stdio/test-freopen.t)
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable


More information about the svn-src-all mailing list