8de3884106
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.
191 lines
3.8 KiB
Plaintext
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 */
|