3900 # 3901 /* 3902 */ 3903 3904 #include "../param.h" 3905 #include "../systm.h" 3906 #include "../user.h" 3907 #include "../proc.h" 3908 #include "../inode.h" 3909 #include "../reg.h" 3910 3911 /* 3912 * Priority for tracing 3913 */ 3914 #define IPCPRI (-1) 3915 3916 /* 3917 * Structure to access an array of integers. 3918 */ 3919 struct 3920 { 3921 int inta[]; 3922 }; 3923 /* ------------------------ */ 3924 3925 /* 3926 * Tracing variables. 3927 * Used to pass trace command from 3928 * parent to child being traced. 3929 * This data base cannot be 3930 * shared and is locked 3931 * per user. 3932 */ 3933 struct 3934 { 3935 int ip_lock; 3936 int ip_req; 3937 int ip_addr; 3938 int ip_data; 3939 } ipc; 3940 /* ------------------------ */ 3941 3942 /* 3943 * Send the specified signal to 3944 * all processes with 'tp' as its 3945 * controlling teletype. 3946 * Called by tty.c for quits and 3947 * interrupts. 3948 */ 3949 signal(tp, sig) 3950 { 3951 register struct proc *p; 3952 3953 for(p = &proc[0]; p < &proc[NPROC]; p++) 3954 if(p->p_ttyp == tp) 3955 psignal(p, sig); 3956 } 3957 /* ------------------------ */ 3958 3959 /* 3960 * Send the specified signal to 3961 * the specified process. 3962 */ 3963 psignal(p, sig) 3964 int *p; 3965 { 3966 register *rp; 3967 3968 if(sig >= NSIG) 3969 return; 3970 rp = p; 3971 if(rp->p_sig != SIGKIL) 3972 rp->p_sig = sig; 3973 if(rp->p_stat > PUSER) 3974 rp->p_stat = PUSER; 3975 if(rp->p_stat == SWAIT) 3976 setrun(rp); 3977 } 3978 /* ------------------------ */ 3979 3980 /* 3981 * Returns true if the current 3982 * process has a signal to process. 3983 * This is asked at least once 3984 * each time a process enters the 3985 * system. 3986 * A signal does not do anything 3987 * directly to a process; it sets 3988 * a flag that asks the process to 3989 * do something to itself. 3990 */ 3991 issig() 3992 { 3993 register n; 3994 register struct proc *p; 3995 3996 p = u.u_procp; 3997 if(n = p->p_sig) { 3998 if (p->p_flag&STRC) { 3999 stop(); 4000 if ((n = p->p_sig) == 0) 4001 return(0); 4002 } 4003 if((u.u_signal[n]&1) == 0) 4004 return(n); 4005 } 4006 return(0); 4007 } 4008 /* ------------------------ */ 4009 4010 /* 4011 * Enter the tracing STOP state. 4012 * In this state, the parent is 4013 * informed and the process is able to 4014 * receive commands from the parent. 4015 */ 4016 stop() 4017 { 4018 register struct proc *pp, *cp; 4019 4020 loop: 4021 cp = u.u_procp; 4022 if(cp->p_ppid != 1) 4023 for (pp = &proc[0]; pp < &proc[NPROC]; pp++) 4024 if (pp->p_pid == cp->p_ppid) { 4025 wakeup(pp); 4026 cp->p_stat = SSTOP; 4027 swtch(); 4028 if ((cp->p_flag&STRC)==0 || procxmt()) 4029 return; 4030 goto loop; 4031 } 4032 exit(); 4033 } 4034 /* ------------------------ */ 4035 4036 /* 4037 * Perform the action specified by 4038 * the current signal. 4039 * The usual sequence is: 4040 * if(issig()) 4041 * psig(); 4042 */ 4043 psig() 4044 { 4045 register n, p; 4046 register *rp; 4047 4048 rp = u.u_procp; 4049 n = rp->p_sig; 4050 rp->p_sig = 0; 4051 if((p=u.u_signal[n]) != 0) { 4052 u.u_error = 0; 4053 if(n != SIGINS && n != SIGTRC) 4054 u.u_signal[n] = 0; 4055 n = u.u_ar0[R6] - 4; 4056 grow(n); 4057 suword(n+2, u.u_ar0[RPS]); 4058 suword(n, u.u_ar0[R7]); 4059 u.u_ar0[R6] = n; 4060 u.u_ar0[RPS] =& ~TBIT; 4061 u.u_ar0[R7] = p; 4062 return; 4063 } 4064 switch(n) { 4065 4066 case SIGQIT: 4067 case SIGINS: 4068 case SIGTRC: 4069 case SIGIOT: 4070 case SIGEMT: 4071 case SIGFPT: 4072 case SIGBUS: 4073 case SIGSEG: 4074 case SIGSYS: 4075 u.u_arg[0] = n; 4076 if(core()) 4077 n =+ 0200; 4078 } 4079 u.u_arg[0] = (u.u_ar0[R0]<<8) | n; 4080 exit(); 4081 } 4082 /* ------------------------ */ 4083 4084 /* 4085 * Create a core image on the file "core" 4086 * If you are looking for protection glitches, 4087 * there are probably a wealth of them here 4088 * when this occurs to a suid command. 4089 * 4090 * It writes USIZE block of the 4091 * user.h area followed by the entire 4092 * data+stack segments. 4093 */ 4094 core() 4095 { 4096 register s, *ip; 4097 extern schar; 4098 4099 u.u_error = 0; 4100 u.u_dirp = "core"; 4101 ip = namei(&schar, 1); 4102 if(ip == NULL) { 4103 if(u.u_error) 4104 return(0); 4105 ip = maknode(0666); 4106 if(ip == NULL) 4107 return(0); 4108 } 4109 if(!access(ip, IWRITE) && 4110 (ip->i_mode&IFMT) == 0 && 4111 u.u_uid == u.u_ruid) { 4112 itrunc(ip); 4113 u.u_offset[0] = 0; 4114 u.u_offset[1] = 0; 4115 u.u_base = &u; 4116 u.u_count = USIZE*64; 4117 u.u_segflg = 1; 4118 writei(ip); 4119 s = u.u_procp->p_size - USIZE; 4120 estabur(0, s, 0, 0); 4121 u.u_base = 0; 4122 u.u_count = s*64; 4123 u.u_segflg = 0; 4124 writei(ip); 4125 } 4126 iput(ip); 4127 return(u.u_error==0); 4128 } 4129 /* ------------------------ */ 4130 4131 /* 4132 * grow the stack to include the SP 4133 * true return if successful. 4134 */ 4135 4136 grow(sp) 4137 char *sp; 4138 { 4139 register a, si, i; 4140 4141 if(sp >= -u.u_ssize*64) 4142 return(0); 4143 si = ldiv(-sp, 64) - u.u_ssize + SINCR; 4144 if(si <= 0) 4145 return(0); 4146 if(estabur(u.u_tsize, u.u_dsize, u.u_ssize+si, u.u_sep)) 4147 return(0); 4148 expand(u.u_procp->p_size+si); 4149 a = u.u_procp->p_addr + u.u_procp->p_size; 4150 for(i=u.u_ssize; i; i--) { 4151 a--; 4152 copyseg(a-si, a); 4153 } 4154 for(i=si; i; i--) 4155 clearseg(--a); 4156 u.u_ssize =+ si; 4157 return(1); 4158 } 4159 /* ------------------------ */ 4160 4161 /* 4162 * sys-trace system call. 4163 */ 4164 ptrace() 4165 { 4166 register struct proc *p; 4167 4168 if (u.u_arg[2] <= 0) { 4169 u.u_procp->p_flag =| STRC; 4170 return; 4171 } 4172 for (p=proc; p < &proc[NPROC]; p++) 4173 if (p->p_stat==SSTOP 4174 && p->p_pid==u.u_arg[0] 4175 && p->p_ppid==u.u_procp->p_pid) 4176 goto found; 4177 u.u_error = ESRCH; 4178 return; 4179 4180 found: 4181 while (ipc.ip_lock) 4182 sleep(&ipc, IPCPRI); 4183 ipc.ip_lock = p->p_pid; 4184 ipc.ip_data = u.u_ar0[R0]; 4185 ipc.ip_addr = u.u_arg[1] & ~01; 4186 ipc.ip_req = u.u_arg[2]; 4187 p->p_flag =& ~SWTED; 4188 setrun(p); 4189 while (ipc.ip_req > 0) 4190 sleep(&ipc, IPCPRI); 4191 u.u_ar0[R0] = ipc.ip_data; 4192 if (ipc.ip_req < 0) 4193 u.u_error = EIO; 4194 ipc.ip_lock = 0; 4195 wakeup(&ipc); 4196 } 4197 /* ------------------------ */ 4198 4199 /* 4200 * Code that the child process 4201 * executes to implement the command 4202 * of the parent process in tracing. 4203 */ 4204 procxmt() 4205 { 4206 register int i; 4207 register int *p; 4208 4209 if (ipc.ip_lock != u.u_procp->p_pid) 4210 return(0); 4211 i = ipc.ip_req; 4212 ipc.ip_req = 0; 4213 wakeup(&ipc); 4214 switch (i) { 4215 4216 /* read user I */ 4217 case 1: 4218 if (fuibyte(ipc.ip_addr) == -1) 4219 goto error; 4220 ipc.ip_data = fuiword(ipc.ip_addr); 4221 break; 4222 4223 /* read user D */ 4224 case 2: 4225 if (fubyte(ipc.ip_addr) == -1) 4226 goto error; 4227 ipc.ip_data = fuword(ipc.ip_addr); 4228 break; 4229 4230 /* read u */ 4231 case 3: 4232 i = ipc.ip_addr; 4233 if (i<0 || i >= (USIZE<<6)) 4234 goto error; 4235 ipc.ip_data = u.inta[i>>1]; 4236 break; 4237 4238 /* write user I (for now, always an error) */ 4239 case 4: 4240 if (suiword(ipc.ip_addr, 0) < 0) 4241 goto error; 4242 suiword(ipc.ip_addr, ipc.ip_data); 4243 break; 4244 4245 /* write user D */ 4246 case 5: 4247 if (suword(ipc.ip_addr, 0) < 0) 4248 goto error; 4249 suword(ipc.ip_addr, ipc.ip_data); 4250 break; 4251 4252 /* write u */ 4253 case 6: 4254 p = &u.inta[ipc.ip_addr>>1]; 4255 if (p >= u.u_fsav && p < &u.u_fsav[25]) 4256 goto ok; 4257 for (i=0; i<9; i++) 4258 if (p == &u.u_ar0[regloc[i]]) 4259 goto ok; 4260 goto error; 4261 ok: 4262 if (p == &u.u_ar0[RPS]) { 4263 /* assure user space */ 4264 ipc.ip_data =| 0170000; 4265 /* priority 0 */ 4266 ipc.ip_data =& ~0340; 4267 } 4268 *p = ipc.ip_data; 4269 break; 4270 4271 /* set signal and continue */ 4272 case 7: 4273 u.u_procp->p_sig = ipc.ip_data; 4274 return(1); 4275 4276 /* force exit */ 4277 case 8: 4278 exit(); 4279 4280 default: 4281 error: 4282 ipc.ip_req = -1; 4283 } 4284 return(0); 4285 } 4286 /* ------------------------ */ 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299