Date: Sat, 1 Jun 1996 10:03:16 +0400 (MSD) From: =?KOI8-R?Q?=E1=CE=C4=D2=C5=CA_=FE=C5=D2=CE=CF=D7?= (aka Andrey A. Chernov, Black Mage) <ache@astral.msk.su> To: security@freebsd.org Cc: joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch), pst@freebsd.org Subject: Man security fixes for review Message-ID: <199606010603.KAA00964@astral.msk.su>
next in thread | raw e-mail | index | archive | help
I think, this patch is enough to close man hole and return s-bit back. Any comments? *** man.c.orig Tue May 30 14:11:59 1995 --- man.c Sat Jun 1 09:55:16 1996 *************** *** 19,24 **** --- 19,25 ---- #include <sys/types.h> #include <stdio.h> #include <ctype.h> + #include <errno.h> #include <string.h> #include <sys/file.h> #include <signal.h> *************** *** 131,136 **** --- 132,138 ---- prognam = mkprogname (argv[0]); + unsetenv("IFS"); man_getopt (argc, argv); if (optind == argc) *************** *** 981,987 **** fprintf (stderr, "using default preprocessor sequence\n"); if ((cp = get_expander(file)) == NULL) ! cp = "cat"; sprintf(buf, "%s %s | ", cp, file); #ifdef HAS_TROFF if (troff) --- 983,989 ---- fprintf (stderr, "using default preprocessor sequence\n"); if ((cp = get_expander(file)) == NULL) ! cp = "/bin/cat"; sprintf(buf, "%s %s | ", cp, file); #ifdef HAS_TROFF if (troff) *************** *** 1020,1025 **** --- 1022,1054 ---- return buf; } + sig_t ohup, oint, oquit, oterm; + static char temp[FILENAME_MAX]; + + void cleantmp() + { + unlink(temp); + exit(1); + } + + void + set_sigs() + { + ohup = signal(SIGHUP, cleantmp); + oint = signal(SIGINT, cleantmp); + oquit = signal(SIGQUIT, cleantmp); + oterm = signal(SIGTERM, cleantmp); + } + + void + restore_sigs() + { + signal(SIGHUP, ohup); + signal(SIGINT, oint); + signal(SIGQUIT, oquit); + signal(SIGTERM, oterm); + } + /* * Try to format the man page and create a new formatted file. Return * 1 for success and 0 for failure. *************** *** 1030,1102 **** register char *man_file; register char *cat_file; { ! int status; ! int mode; ! FILE *fp; char *roff_command; char command[FILENAME_MAX]; - char temp[FILENAME_MAX]; ! sprintf(temp, "%s.tmp", cat_file); ! if ((fp = fopen (temp, "w")) != NULL) { ! fclose (fp); ! unlink (temp); ! roff_command = make_roff_command (man_file); ! if (roff_command == NULL) return 0; ! else #ifdef DO_COMPRESS ! sprintf (command, "(cd %s ; %s | %s > %s)", path, ! roff_command, COMPRESSOR, temp); #else ! sprintf (command, "(cd %s ; %s > %s)", path, ! roff_command, temp); #endif - /* - * Don't let the user interrupt the system () call and screw up - * the formatted man page if we're not done yet. - */ fprintf (stderr, "Formatting page, please wait..."); fflush(stderr); ! status = do_system_command (command); ! ! if (status <= 0) { ! fprintf(stderr, "Failed.\n"); ! unlink(temp); ! exit(1); ! } else { ! if (rename(temp, cat_file) == -1) { ! /* FS might be sticky */ ! sprintf(command, "cp %s %s", temp, cat_file); ! if (system(command)) ! fprintf(stderr, ! "\nHmm! Can't seem to rename %s to %s, check permissions on man dir!\n", ! temp, cat_file); ! unlink(temp); ! return 0; } - } - fprintf(stderr, "Done.\n"); - if (status == 1) - { - mode = CATMODE; - chmod (cat_file, mode); ! if (debug) ! fprintf (stderr, "mode of %s is now %o\n", cat_file, mode); } return 1; } else { ! if (debug) ! fprintf (stderr, "Couldn't open %s for writing.\n", cat_file); return 0; } --- 1059,1179 ---- register char *man_file; register char *cat_file; { ! int s, f; ! FILE *fp, *pp; char *roff_command; char command[FILENAME_MAX]; ! roff_command = make_roff_command (man_file); ! if (roff_command == NULL) ! return 0; ! ! sprintf(temp, "%s.tmpXXXXXX", cat_file); ! if ((f = mkstemp(temp)) >= 0 && (fp = fdopen(f, "w")) != NULL) { ! set_sigs(); ! if (fchmod (f, CATMODE) < 0) { ! perror("fchmod"); ! unlink(temp); ! restore_sigs(); ! fclose(fp); return 0; ! } else if (debug) ! fprintf (stderr, "mode of %s is now %o\n", temp, CATMODE); ! #ifdef DO_COMPRESS ! sprintf (command, "(cd %s ; %s | %s)", path, ! roff_command, COMPRESSOR); #else ! sprintf (command, "(cd %s ; %s)", path, ! roff_command); #endif fprintf (stderr, "Formatting page, please wait..."); fflush(stderr); ! if (debug) ! fprintf (stderr, "\ntrying command: %s\n", command); else { ! ! if ((pp = popen(command, "r")) == NULL) { ! s = errno; ! fprintf(stderr, "Failed.\n"); ! errno = s; ! perror("popen"); ! unlink(temp); ! restore_sigs(); ! fclose(fp); ! return 0; } ! while ((s = getc(pp)) != EOF) ! putc(s, fp); ! ! if ((s = pclose(pp)) == -1) { ! s = errno; ! fprintf(stderr, "Failed.\n"); ! errno = s; ! perror("pclose"); ! unlink(temp); ! restore_sigs(); ! fclose(fp); ! return 0; } + if (s != 0) { + fprintf(stderr, "Failed.\n"); + gripe_system_command(s); + unlink(temp); + restore_sigs(); + fclose(fp); + return 0; + } + } + + if (rename(temp, cat_file) == -1) { + s = errno; + fprintf(stderr, + "\nHmm! Can't seem to rename %s to %s, check permissions on man dir!\n", + temp, cat_file); + errno = s; + perror("rename"); + unlink(temp); + restore_sigs(); + fclose(fp); + return 0; + } + restore_sigs(); + + if (fclose(fp)) { + s = errno; + unlink(cat_file); + fprintf(stderr, "Failed.\n"); + errno = s; + perror("fclose"); + return 0; + } + + fprintf(stderr, "Done.\n"); return 1; } else { ! if (f >= 0) { ! s = errno; ! unlink(temp); ! errno = s; ! } ! if (debug) { ! s = errno; ! fprintf (stderr, "Couldn't open %s for writing.\n", temp); ! errno = s; ! } ! if (f >= 0) { ! perror("fdopen"); ! close(f); ! } return 0; } -- Andrey A. Chernov : And I rest so composedly, /Now, in my bed, ache@astral.msk.su : That any beholder /Might fancy me dead - http://dt.demos.su/~ache : Might start at beholding me, /Thinking me dead. RELCOM Team,FreeBSD Team : E.A.Poe From "For Annie" 1849
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199606010603.KAA00964>