From 322628519e2fba8e20e5b5e7bc8412536193921d Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 22 Jan 2002 15:15:38 +0000 Subject: [PATCH] Reincarnate SETUID code in man(1), not compiled in by default. The code will be fixed for all known security vulnerabilities, and a make.conf(5) knob (ENABLE_SUID_MAN) will be provided for those who still want it installed setuid for whatever reasons. --- etc/mtree/BSD.local.dist | 8 +++++-- etc/mtree/BSD.usr.dist | 8 ++++--- etc/mtree/BSD.x11-4.dist | 4 +++- etc/mtree/BSD.x11.dist | 4 +++- gnu/usr.bin/man/man/man.c | 50 +++++++++++++++++++++++++++++++++------ 5 files changed, 60 insertions(+), 14 deletions(-) diff --git a/etc/mtree/BSD.local.dist b/etc/mtree/BSD.local.dist index 43b5ea2f43ca..2b9f19117e63 100644 --- a/etc/mtree/BSD.local.dist +++ b/etc/mtree/BSD.local.dist @@ -40,6 +40,7 @@ libexec .. man +/set uname=man cat1 .. cat2 @@ -62,7 +63,7 @@ .. catn .. - de.ISO8859-1 + de.ISO8859-1 uname=root cat1 .. cat2 @@ -85,6 +86,7 @@ .. catn .. +/set uname=root man1 .. man2 @@ -109,6 +111,7 @@ .. .. en.ISO8859-1 +/set uname=man cat1 .. cat1aout @@ -142,7 +145,7 @@ catn .. .. - ja + ja uname=root cat1 .. cat2 @@ -165,6 +168,7 @@ .. catn .. +/set uname=root man1 .. man2 diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 14b5deec167f..d65480e45ba5 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -645,6 +645,7 @@ .. .. man +/set uname=man cat1 .. cat1aout @@ -677,7 +678,7 @@ .. catn .. - en.ISO8859-1 + en.ISO8859-1 uname=root cat1 .. cat1aout @@ -711,7 +712,7 @@ catn .. .. - ja + ja uname=root cat1 .. cat2 @@ -732,6 +733,7 @@ .. catn .. +/set uname=root man1 .. man2 @@ -968,7 +970,7 @@ .. perl man - cat3 + cat3 uname=man .. man3 .. diff --git a/etc/mtree/BSD.x11-4.dist b/etc/mtree/BSD.x11-4.dist index b10b0011cf8b..dca7d089a98c 100644 --- a/etc/mtree/BSD.x11-4.dist +++ b/etc/mtree/BSD.x11-4.dist @@ -314,6 +314,7 @@ libexec .. man +/set uname=man cat1 .. cat2 @@ -336,7 +337,7 @@ .. catn .. - ja + ja uname=root cat1 .. cat2 @@ -359,6 +360,7 @@ .. catn .. +/set uname=root man1 .. man2 diff --git a/etc/mtree/BSD.x11.dist b/etc/mtree/BSD.x11.dist index 81ddaedca8c2..ef3378153cba 100644 --- a/etc/mtree/BSD.x11.dist +++ b/etc/mtree/BSD.x11.dist @@ -196,6 +196,7 @@ libexec .. man +/set uname=man cat1 .. cat2 @@ -218,7 +219,7 @@ .. catn .. - ja + ja uname=root cat1 .. cat2 @@ -241,6 +242,7 @@ .. catn .. +/set uname=root man1 .. man2 diff --git a/gnu/usr.bin/man/man/man.c b/gnu/usr.bin/man/man/man.c index 35fb3aef1cd3..7b6fc419fade 100644 --- a/gnu/usr.bin/man/man/man.c +++ b/gnu/usr.bin/man/man/man.c @@ -45,11 +45,6 @@ #endif #endif -#ifdef SECURE_MAN_UID -extern uid_t getuid (); -extern int setuid (); -#endif - #ifdef STDC_HEADERS #include #else @@ -121,6 +116,11 @@ 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; @@ -158,6 +158,12 @@ main (argc, argv) gripe_no_name (tmp); } +#ifdef SETUID + ruid = getuid(); + euid = geteuid(); + seteuid(ruid); +#endif + while (optind < argc) { nextarg = argv[optind++]; @@ -1107,7 +1113,7 @@ restore_sigs() * 1 for success and 0 for failure. */ int -make_cat_file (path, man_file, cat_file) +make_cat_file (path, man_file, cat_file, manid) register char *path; register char *man_file; register char *cat_file; @@ -1148,16 +1154,29 @@ make_cat_file (path, man_file, cat_file) 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) { @@ -1293,7 +1312,24 @@ format_and_display (path, man_file, cat_file) } else { - found = make_cat_file (path, man_file, cat_file); + +#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 if (found) { /*