Bugtraq mailing list archives

rxvt hole


From: marc () redhat com (Marc Ewing)
Date: Tue, 2 Jan 1996 20:58:30 -0500


OK, second attempt.  This one should only retain privileges for the
utmp stuff and /dev/ttyp* stuff, which is all it should need, as far
as I can tell.  If someone more knowlegeable than me gives this an
OK, I'll release new rpms.

Thanks,
Marc
--
--- rxvt/rxvt.h.marc    Tue Jan  2 20:02:10 1996
+++ rxvt/rxvt.h Tue Jan  2 20:14:30 1996
@@ -21,3 +21,7 @@
 extern void clean_exit(int);
 extern void cleanutent(void);
 extern void makeutent(char *);
+
+void save_privs(void);
+void get_privs(void);
+void release_privs(void);
--- rxvt/rxvt.c.marc    Tue Jan  2 20:02:14 1996
+++ rxvt/rxvt.c Tue Jan  2 20:46:04 1996
@@ -45,6 +45,10 @@
   int i;
   char *shell;
   char **com_argv;
+
+  /* Save then give up any suid/sgid privileges */
+  save_privs();
+  release_privs();

   for (i = 0; i < argc; i++)
     if (strcmp(argv[i],"-e") == 0)
--- rxvt/command.c.marc Tue Jan  2 20:09:00 1996
+++ rxvt/command.c      Tue Jan  2 20:47:18 1996
@@ -222,6 +222,26 @@
 }
 #endif

+static uid_t saved_uid;
+static gid_t saved_gid;
+
+void save_privs()
+{
+    saved_uid = geteuid();
+    saved_gid = getegid();
+}
+
+void get_privs()
+{
+    seteuid(saved_uid);
+    seteuid(saved_gid);
+}
+
+void release_privs()
+{
+    seteuid(getuid());
+    setegid(getgid());
+}

 /*  Catch a SIGCHLD signal and exit if the direct child has died.
  */
@@ -348,8 +368,10 @@
        gid = gr->gr_gid;
       else
        gid = -1;
+      get_privs();
       fchown(ttyfd,uid,gid);
       fchmod(ttyfd,0600);
+      release_privs();
 #endif
 #ifdef TIOCCONS
      if (console)
--- rxvt/utmp.c.marc    Tue Jan  2 20:19:35 1996
+++ rxvt/utmp.c Tue Jan  2 20:43:55 1996
@@ -71,9 +71,11 @@
   extern char ttynam[];
   extern struct stat ttyfd_stat;

+  get_privs();
   chmod(ttynam,ttyfd_stat.st_mode);

   chown(ttynam,ttyfd_stat.st_uid,ttyfd_stat.st_gid);
+  release_privs();
 #endif
   if(madeutent)
     cleanutent();
@@ -228,12 +230,14 @@
   FILE *ut;
   struct utmp u;

+  get_privs();
   if((ut = fopen(UTMP,"r+")) == NULL)
     return;
   fseek(ut,utmp_pos,0);
   memset(&u,0,sizeof(u));
   fwrite((char *)&u,sizeof(struct utmp),1,ut);
   fclose(ut);
+  release_privs();
 }


@@ -250,10 +254,12 @@
 int write_utmp(struct utmp * u)
 {
   int pos;
+  get_privs();
   utmpname(UTMP);
   setutent();
   pututline(u);
   endutent();
+  release_privs();
   pos = (int)NULL;
   madeutent = 1;
   return(pos);
@@ -306,6 +312,7 @@
   int pid;
   struct utmp *u;

+  get_privs();
   utmpname(UTMP);
   setutent();
   pid = getpid();
@@ -333,6 +340,7 @@
          endutent();
        }
     }
+  release_privs();
 }

 #endif /* BSD */



Current thread: