freebsd-ports/x11/rxvt/files/patch-ac
Peter Wemm 8de3884106 Fix the utmp handling that was broken by the security patch.
It was:
 - setting the euid from the real groupid (yow!)
 - not recovering it's setuid permissions when cleaning the utmp file.
I've left in some diagnostic code for "shouldn't happen" cases.
1996-02-24 14:55:37 +00:00

191 lines
3.8 KiB
Plaintext

# The following is a security patch for rxvt, it (hopefully) avoids problems
# with unauthorized users obtaining root.
#
# Based upon code provided by Marc Ewing (marc@redhat.com) for a previous
# version of rxvt.
#
# BSD utmp code fixed again by peter@freebsd.org
*** rxvt.h Sat Feb 19 09:41:52 1994
--- rxvt.h Wed Jan 10 23:42:09 1996
***************
*** 21,23 ****
--- 21,27 ----
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.c Fri Aug 5 23:52:07 1994
--- rxvt.c Sat Feb 24 22:03:27 1996
***************
*** 45,50 ****
--- 45,54 ----
int i;
char *shell;
char **com_argv;
+
+ /* Save and give up setuid/setgid privileges */
+ save_privs();
+ release_privs();
for (i = 0; i < argc; i++)
if (strcmp(argv[i],"-e") == 0)
*** command.c Sat Feb 24 22:03:27 1996
--- command.c Sat Feb 24 22:12:26 1996
***************
*** 222,227 ****
--- 222,251 ----
}
#endif
+ static uid_t saved_uid;
+ static gid_t saved_gid;
+
+ void save_privs()
+ {
+ saved_uid = geteuid();
+ saved_gid = getegid();
+ }
+
+ void get_privs()
+ {
+ if (seteuid(saved_uid) < 0)
+ perror("failed to restore saved uid");
+ if (setegid(saved_gid) < 0)
+ perror("failed to restore saved gid");
+ }
+
+ void release_privs()
+ {
+ if (seteuid(getuid()) < 0)
+ perror("failed to release setuid");
+ if (setegid(getgid()) < 0)
+ perror("failed to release setgid");
+ }
/* Catch a SIGCHLD signal and exit if the direct child has died.
*/
***************
*** 337,344 ****
--- 361,370 ----
gid = gr->gr_gid;
else
gid = -1;
+ get_privs();
fchown(ttyfd,uid,gid);
fchmod(ttyfd,0600);
+ release_privs();
#endif
#ifdef TIOCCONS
if (console)
*** utmp.c Tue Oct 4 08:47:56 1994
--- utmp.c Sat Feb 24 22:21:30 1996
***************
*** 71,79 ****
extern char ttynam[];
extern struct stat ttyfd_stat;
! chmod(ttynam,ttyfd_stat.st_mode);
!
! chown(ttynam,ttyfd_stat.st_uid,ttyfd_stat.st_gid);
#endif
if(madeutent)
cleanutent();
--- 71,83 ----
extern char ttynam[];
extern struct stat ttyfd_stat;
! get_privs();
! if (chmod(ttynam,ttyfd_stat.st_mode) < 0)
! perror("cant reset tty modes");
!
! if (chown(ttynam,ttyfd_stat.st_uid,ttyfd_stat.st_gid) < 0)
! perror("cant reset tty owner");
! release_privs();
#endif
if(madeutent)
cleanutent();
***************
*** 166,171 ****
--- 170,176 ----
{
FILE *utmp;
+ get_privs();
if((utmp = fopen(UTMP,"r+")) == NULL)
return -1;
utmp_pos = get_tslot(ttyname) * sizeof(struct utmp);
***************
*** 174,179 ****
--- 179,185 ----
fseek(utmp,utmp_pos,0);
fwrite((char *)u, sizeof(struct utmp),1,utmp);
fclose(utmp);
+ release_privs();
madeutent = 1;
return(utmp_pos);
}
***************
*** 228,239 ****
--- 234,247 ----
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,259 ****
--- 258,269 ----
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);
***************
*** 305,311 ****
{
int pid;
struct utmp *u;
!
utmpname(UTMP);
setutent();
pid = getpid();
--- 315,322 ----
{
int pid;
struct utmp *u;
!
! get_privs();
utmpname(UTMP);
setutent();
pid = getpid();
***************
*** 333,338 ****
--- 344,350 ----
endutent();
}
}
+ release_privs();
}
#endif /* BSD */