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:
parent
99ceec2679
commit
2aa7f13a7d
@ -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
|
||||
|
@ -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
|
||||
..
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user