Do not install man(1) setuid ``man''.

The catpaging and setuidness features of man(1) combined make
it vulnerable to a number of security attacks.  Specifically,
it was possible to overwrite system catpages with arbitrarily
contents by either setting up a symlink to a directory holding
system catpages, or by writing custom -mdoc or -man groff(1)
macro packages and setting up GROFF_TMAC_PATH in environment
to point to them.  (See PR below for details).

This means man(1) can no longer create system catpages on a
regular user's behalf.  (It is still able to if the user has
write permissions to the directory holding catpages, e.g.,
user's own manpages, or if the running user is ``root''.)

To create and install catpages during ``make world'', please
set MANBUILDCAT=YES in /etc/make.conf.  To rebuild catpages
on a weekly basis, please set weekly_catman_enable="YES" in
/etc/periodic.conf.

PR:		bin/32791
This commit is contained in:
Ruslan Ermilov 2002-01-15 14:11:05 +00:00
parent f1ff35aecb
commit 30843b9337
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=89390
6 changed files with 10 additions and 83 deletions

View file

@ -40,7 +40,6 @@
libexec
..
man
/set uname=man
cat1
..
cat2
@ -63,7 +62,7 @@
..
catn
..
de.ISO8859-1 uname=root
de.ISO8859-1
cat1
..
cat2
@ -86,7 +85,6 @@
..
catn
..
/set uname=root
man1
..
man2
@ -111,7 +109,6 @@
..
..
en.ISO8859-1
/set uname=man
cat1
..
cat1aout
@ -145,7 +142,7 @@
catn
..
..
ja uname=root
ja
cat1
..
cat2
@ -168,7 +165,6 @@
..
catn
..
/set uname=root
man1
..
man2

View file

@ -645,7 +645,6 @@
..
..
man
/set uname=man
cat1
..
cat1aout
@ -678,7 +677,7 @@
..
catn
..
en.ISO8859-1 uname=root
en.ISO8859-1
cat1
..
cat1aout
@ -712,7 +711,7 @@
catn
..
..
ja uname=root
ja
cat1
..
cat2
@ -733,7 +732,6 @@
..
catn
..
/set uname=root
man1
..
man2
@ -970,7 +968,7 @@
..
perl
man
cat3 uname=man
cat3
..
man3
..

View file

@ -314,7 +314,6 @@
libexec
..
man
/set uname=man
cat1
..
cat2
@ -337,7 +336,7 @@
..
catn
..
ja uname=root
ja
cat1
..
cat2
@ -360,7 +359,6 @@
..
catn
..
/set uname=root
man1
..
man2

View file

@ -196,7 +196,6 @@
libexec
..
man
/set uname=man
cat1
..
cat2
@ -219,7 +218,7 @@
..
catn
..
ja uname=root
ja
cat1
..
cat2
@ -242,7 +241,6 @@
..
catn
..
/set uname=root
man1
..
man2

View file

@ -5,9 +5,6 @@ MAN_LIBZ=YES
PROG= man
SRCS= man.c manpath.c glob.c
BINOWN= man
BINMODE=4555
INSTALLFLAGS= -fschg
CFLAGS+= -I${LIBDESTDIR}
DPADD= ${LIBMAN}
@ -20,7 +17,7 @@ CFLAGS+=-DHAVE_LIBZ=1
.endif
CFLAGS+= -I${.CURDIR}/../lib -DSTDC_HEADERS -DPOSIX -DHAS_TROFF
CFLAGS+= -DDO_COMPRESS -DSETUID -DCATMODE=0644
CFLAGS+= -DDO_COMPRESS -DCATMODE=0644
CLEANFILES+= man.1
.PATH: ${.CURDIR}/../manpath

View file

@ -121,11 +121,6 @@ static char args[] = "M:P:S:adfhkm:p:w?";
#endif
#endif
#ifdef SETUID
uid_t ruid;
uid_t euid;
#endif
int
main (argc, argv)
int argc;
@ -163,12 +158,6 @@ main (argc, argv)
gripe_no_name (tmp);
}
#ifdef SETUID
ruid = getuid();
euid = geteuid();
seteuid(ruid);
#endif
while (optind < argc)
{
nextarg = argv[optind++];
@ -1118,7 +1107,7 @@ restore_sigs()
* 1 for success and 0 for failure.
*/
int
make_cat_file (path, man_file, cat_file, manid)
make_cat_file (path, man_file, cat_file)
register char *path;
register char *man_file;
register char *cat_file;
@ -1159,29 +1148,16 @@ make_cat_file (path, man_file, cat_file, manid)
if (debug)
fprintf (stderr, "\ntrying command: %s\n", command);
else {
#ifdef SETUID
if (manid)
seteuid(ruid);
#endif
if ((pp = popen(command, "r")) == NULL) {
s = errno;
fprintf(stderr, "Failed.\n");
errno = s;
perror("popen");
#ifdef SETUID
if (manid)
seteuid(euid);
#endif
unlink(temp);
restore_sigs();
fclose(fp);
return 0;
}
#ifdef SETUID
if (manid)
seteuid(euid);
#endif
f = 0;
while ((s = getc(pp)) != EOF) {
@ -1317,43 +1293,7 @@ format_and_display (path, man_file, cat_file)
}
else
{
#ifdef SETUID
seteuid(euid);
found = make_cat_file (path, man_file, cat_file, 1);
seteuid(ruid);
if (!found)
{
/* Try again as real user - see note below.
By running with
effective group (user) ID == real group (user) ID
except for the call above, I believe the problems
of reading private man pages is avoided. */
found = make_cat_file (path, man_file, cat_file, 0);
}
#else
found = make_cat_file (path, man_file, cat_file, 0);
#endif
#ifdef SECURE_MAN_UID
if (!found)
{
/*
* Try again as real user. Note that for private
* man pages, we won't even get this far unless the
* effective user can read the real user's man page
* source. Also, if we are trying to find all the
* man pages, this will probably make it impossible
* to make cat files in the system directories if
* the real user's man directories are searched
* first, because there's no way to undo this (is
* there?). Yikes, am I missing something obvious?
*/
setuid (getuid ());
found = make_cat_file (path, man_file, cat_file, 0);
}
#endif
found = make_cat_file (path, man_file, cat_file);
if (found)
{
/*