As discussed on tech-toolchain@netbsd.org, make cpp refuse to attempt to
parse a #include'd file which does not pass S_ISREG() if the environment variable CPP_RESTRICTED is set. This is primarily intended for use by programs such as calendar(1) which use cpp to parse untrusted user files -- without this change (and the corresponding change to calendar(1)), any user can cause a denial-of-service for the daily calendar -a run by #include'ing a named pipe. Many thanks to christos@netbsd for his help in polishing this.
This commit is contained in:
parent
68f709428b
commit
48f45412af
24
gnu/dist/gcc/gcc/cppfiles.c
vendored
24
gnu/dist/gcc/gcc/cppfiles.c
vendored
@ -242,9 +242,13 @@ open_file (pfile, filename)
|
||||
cpp_reader *pfile;
|
||||
const char *filename;
|
||||
{
|
||||
const char *cpp_restricted;
|
||||
|
||||
splay_tree_node nd = find_or_create_entry (pfile, filename);
|
||||
struct include_file *file = (struct include_file *) nd->value;
|
||||
|
||||
GET_ENVIRONMENT(cpp_restricted, "CPP_RESTRICTED");
|
||||
|
||||
if (file->err_no)
|
||||
{
|
||||
/* Ugh. handle_missing_header () needs errno to be set. */
|
||||
@ -265,6 +269,9 @@ open_file (pfile, filename)
|
||||
controlling terminal by mistake (this can't happen on sane
|
||||
systems, but paranoia is a virtue).
|
||||
|
||||
We do, however, use nonblocking mode if CPP_RESTRICTED, since any
|
||||
file which can block will be tossed out after fstat().
|
||||
|
||||
Use the three-argument form of open even though we aren't
|
||||
specifying O_CREAT, to defend against broken system headers.
|
||||
|
||||
@ -285,12 +292,23 @@ open_file (pfile, filename)
|
||||
#endif
|
||||
}
|
||||
else
|
||||
file->fd = open (file->name, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
|
||||
{
|
||||
int mode = O_RDONLY | O_NOCTTY | O_BINARY;
|
||||
|
||||
if (cpp_restricted != NULL)
|
||||
mode |= O_NONBLOCK;
|
||||
|
||||
file->fd = open (file->name, mode, 0666);
|
||||
}
|
||||
|
||||
if (file->fd != -1 && fstat (file->fd, &file->st) == 0)
|
||||
{
|
||||
if (!S_ISDIR (file->st.st_mode))
|
||||
return file;
|
||||
if ((cpp_restricted != NULL) ? S_ISREG (file->st.st_mode) : !S_ISDIR (file->st.st_mode))
|
||||
{
|
||||
if (cpp_restricted)
|
||||
fcntl(file->fd, F_SETFL, fcntl(file->fd, F_GETFL, 0) & ~O_NONBLOCK);
|
||||
return file;
|
||||
}
|
||||
|
||||
/* If it's a directory, we return null and continue the search
|
||||
as the file we're looking for may appear elsewhere in the
|
||||
|
8
gnu/dist/gcc/gcc/doc/cpp.1
vendored
8
gnu/dist/gcc/gcc/doc/cpp.1
vendored
@ -774,7 +774,8 @@ preprocess as normal. With two dashes, exit immediately.
|
||||
.IX Header "ENVIRONMENT"
|
||||
This section describes the environment variables that affect how \s-1CPP\s0
|
||||
operates. You can use them to specify directories or prefixes to use
|
||||
when searching for include files, or to control dependency output.
|
||||
when searching for include files, or to control dependency output or behavior
|
||||
in the face of include files which are device nodes or named pipes.
|
||||
.PP
|
||||
Note that you can also specify places to search using options such as
|
||||
\&\fB\-I\fR, and control dependency output with options like
|
||||
@ -834,6 +835,11 @@ This variable is the same as \fB\s-1DEPENDENCIES_OUTPUT\s0\fR (see above),
|
||||
except that system header files are not ignored, so it implies
|
||||
\&\fB\-M\fR rather than \fB\-MM\fR. However, the dependence on the
|
||||
main input file is omitted.
|
||||
.IP "\fB\s-1CPP_RESTRICTED\s0\fR" 4
|
||||
.IX Item "CPP_RESTRICTED"
|
||||
If this variable is defined, cpp will skip any include file which is not a
|
||||
regular file, and will continue searching for the requested name (this is
|
||||
always done if the found file is a directory).
|
||||
.SH "SEE ALSO"
|
||||
.IX Header "SEE ALSO"
|
||||
\&\fIgcc\fR\|(1), \fIas\fR\|(1), \fIld\fR\|(1), and the Info entries for \fIcpp\fR, \fIgcc\fR, and
|
||||
|
576
gnu/dist/gcc/gcc/doc/cpp.info
vendored
576
gnu/dist/gcc/gcc/doc/cpp.info
vendored
@ -1,7 +1,7 @@
|
||||
Ceci est le fichier Info doc/cpp.info, produit par Makeinfo version 4.6
|
||||
à partir doc/cpp.texi.
|
||||
This is doc/cpp.info, produced by makeinfo version 4.7 from
|
||||
doc/cpp.texi.
|
||||
|
||||
Copyright (C) 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
Copyright (C) 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@ -21,7 +21,8 @@ are (a) (see below), and the Back-Cover Texts are (b) (see below).
|
||||
|
||||
You have freedom to copy and modify this GNU Manual, like GNU
|
||||
software. Copies published by the Free Software Foundation raise
|
||||
funds for GNU development.
|
||||
funds for GNU development. man end
|
||||
|
||||
INFO-DIR-SECTION Programming
|
||||
START-INFO-DIR-ENTRY
|
||||
* Cpp: (cpp). The GNU C preprocessor.
|
||||
@ -30,7 +31,8 @@ END-INFO-DIR-ENTRY
|
||||
|
||||
File: cpp.info, Node: Top, Next: Overview, Up: (dir)
|
||||
|
||||
|
||||
The C Preprocessor
|
||||
******************
|
||||
|
||||
The C preprocessor implements the macro language used to transform C,
|
||||
C++, and Objective-C programs before they are compiled. It can also be
|
||||
@ -130,7 +132,7 @@ Obsolete Features
|
||||
* Assertions::
|
||||
* Obsolete once-only headers::
|
||||
|
||||
Copyright (C) 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
Copyright (C) 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@ -150,7 +152,8 @@ are (a) (see below), and the Back-Cover Texts are (b) (see below).
|
||||
|
||||
You have freedom to copy and modify this GNU Manual, like GNU
|
||||
software. Copies published by the Free Software Foundation raise
|
||||
funds for GNU development.
|
||||
funds for GNU development. man end
|
||||
|
||||
|
||||
File: cpp.info, Node: Overview, Next: Header Files, Prev: Top, Up: Top
|
||||
|
||||
@ -315,7 +318,7 @@ standard.
|
||||
// contains line comment
|
||||
yet more comment
|
||||
*/ outside comment
|
||||
|
||||
|
||||
// line comment /* contains block comment */
|
||||
|
||||
But beware of commenting out one end of a block comment with a line
|
||||
@ -668,7 +671,7 @@ this,
|
||||
|
||||
int x;
|
||||
#include "header.h"
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
@ -680,7 +683,7 @@ read
|
||||
|
||||
int x;
|
||||
char *test (void);
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
@ -790,9 +793,9 @@ contents of the file in a conditional, like this:
|
||||
/* File foo. */
|
||||
#ifndef FILE_FOO_SEEN
|
||||
#define FILE_FOO_SEEN
|
||||
|
||||
|
||||
THE ENTIRE FILE
|
||||
|
||||
|
||||
#endif /* !FILE_FOO_SEEN */
|
||||
|
||||
This construct is commonly known as a "wrapper #ifndef". When the
|
||||
@ -910,9 +913,8 @@ Headers::), it will recurse infinitely and cause a fatal error.
|
||||
|
||||
You could include the old header with an absolute pathname:
|
||||
#include "/usr/include/old-header.h"
|
||||
|
||||
This works, but is not clean; should the system headers ever move, you
|
||||
would have to edit the new headers to match.
|
||||
This works, but is not clean; should the system headers ever move,
|
||||
you would have to edit the new headers to match.
|
||||
|
||||
There is no way to solve this problem within the C standard, but you
|
||||
can use the GNU extension `#include_next'. It means, "Include the
|
||||
@ -971,6 +973,9 @@ command line. If the same directory is named by both `-I' and
|
||||
`-isystem', the `-I' option is ignored. GCC provides an informative
|
||||
message when this occurs if `-v' is used.
|
||||
|
||||
The `-isystem-cxx' command line option adds its argument to the list
|
||||
of C++ system headers, similar to `-isystem' for C headers.
|
||||
|
||||
There is also a directive, `#pragma GCC system_header', which tells
|
||||
GCC to consider the rest of the current include file a system header,
|
||||
no matter where it was found. Code that comes before the `#pragma' in
|
||||
@ -1238,7 +1243,7 @@ Here are some silly examples using `min':
|
||||
min(a, ) ==> ((a ) < ( ) ? (a ) : ( ))
|
||||
min(,) ==> (( ) < ( ) ? ( ) : ( ))
|
||||
min((,),) ==> (((,)) < ( ) ? ((,)) : ( ))
|
||||
|
||||
|
||||
min() error--> macro "min" requires 2 arguments, but only 1 given
|
||||
min(,,) error--> macro "min" passed 3 arguments, but takes just 2
|
||||
|
||||
@ -1383,7 +1388,7 @@ as follows:
|
||||
char *name;
|
||||
void (*function) (void);
|
||||
};
|
||||
|
||||
|
||||
struct command commands[] =
|
||||
{
|
||||
{ "quit", quit_command },
|
||||
@ -1399,7 +1404,7 @@ and the function name by concatenating the argument with `_command'.
|
||||
Here is how it is done:
|
||||
|
||||
#define COMMAND(NAME) { #NAME, NAME ## _command }
|
||||
|
||||
|
||||
struct command commands[] =
|
||||
{
|
||||
COMMAND (quit),
|
||||
@ -1947,8 +1952,7 @@ These definitions are effectively the same:
|
||||
#define FOUR (2 + 2)
|
||||
#define FOUR (2 + 2)
|
||||
#define FOUR (2 /* two */ + 2)
|
||||
|
||||
but these are not:
|
||||
but these are not:
|
||||
#define FOUR (2 + 2)
|
||||
#define FOUR ( 2+2 )
|
||||
#define FOUR (2 * 2)
|
||||
@ -2276,7 +2280,7 @@ then `x' and `y' expand as follows:
|
||||
|
||||
x ==> (4 + y)
|
||||
==> (4 + (2 * x))
|
||||
|
||||
|
||||
y ==> (2 * x)
|
||||
==> (2 * (4 + y))
|
||||
|
||||
@ -2385,7 +2389,7 @@ different to the line containing the argument causing the problem.
|
||||
Here is an example illustrating this:
|
||||
|
||||
#define ignore_second_arg(a,b,c) a; c
|
||||
|
||||
|
||||
ignore_second_arg (foo (),
|
||||
ignored (),
|
||||
syntax error);
|
||||
@ -2494,9 +2498,9 @@ Ifdef
|
||||
The simplest sort of conditional is
|
||||
|
||||
#ifdef MACRO
|
||||
|
||||
|
||||
CONTROLLED TEXT
|
||||
|
||||
|
||||
#endif /* MACRO */
|
||||
|
||||
This block is called a "conditional group". CONTROLLED TEXT will be
|
||||
@ -2567,9 +2571,9 @@ The `#if' directive allows you to test the value of an arithmetic
|
||||
expression, rather than the mere existence of one macro. Its syntax is
|
||||
|
||||
#if EXPRESSION
|
||||
|
||||
|
||||
CONTROLLED TEXT
|
||||
|
||||
|
||||
#endif /* EXPRESSION */
|
||||
|
||||
EXPRESSION is a C expression of integer type, subject to stringent
|
||||
@ -3907,7 +3911,7 @@ single-letter options may _not_ be grouped: `-dM' is very different from
|
||||
This is typical output:
|
||||
|
||||
test.o: test.c test.h
|
||||
|
||||
|
||||
test.h:
|
||||
|
||||
`-MT TARGET'
|
||||
@ -4076,6 +4080,13 @@ single-letter options may _not_ be grouped: `-dM' is very different from
|
||||
applied to the standard system directories. *Note System
|
||||
Headers::.
|
||||
|
||||
`-isystem-cxx DIR'
|
||||
Search DIR for C++ header files, after all directories specified by
|
||||
`-I' but before the standard system directories. Mark it as a
|
||||
system directory, so that it gets the same special treatment as is
|
||||
applied to the standard system directories. *Note System
|
||||
Headers::.
|
||||
|
||||
`-fpreprocessed'
|
||||
Indicate to the preprocessor that the input file has already been
|
||||
preprocessed. This suppresses things like macro expansion,
|
||||
@ -4269,6 +4280,13 @@ in turn take precedence over the configuration of GCC.
|
||||
`-M' rather than `-MM'. However, the dependence on the main input
|
||||
file is omitted. *Note Invocation::.
|
||||
|
||||
`CPP_RESTRICTED'
|
||||
If this variable is defined, cpp will skip any include file which
|
||||
is not a regular file, and will continue searching for the
|
||||
requested name (this is always done if the found file is a
|
||||
directory). *Note Invocation::.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: GNU Free Documentation License, Next: Index of Directives, Prev: Environment Variables, Up: Top
|
||||
|
||||
@ -4276,9 +4294,10 @@ GNU Free Documentation License
|
||||
******************************
|
||||
|
||||
Version 1.2, November 2002
|
||||
|
||||
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@ -4706,30 +4725,33 @@ File: cpp.info, Node: Index of Directives, Next: Option Index, Prev: GNU Free
|
||||
Index of Directives
|
||||
*******************
|
||||
|
||||
|