Skip site navigation (1)Skip section navigation (2)
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>