madden (04/25/83)
As distributed in December, `82, 4.1a BSD alters the behavior of setgid programs by making it impossible for them to use setgid(getgid()) to forego any special file access privileges that they may have acquired from being setgid. This happens because, when such a program is exec'ed, the bit corresponding to the effective gid is set in the group mask (u.u_grps) of the process. Unfortunately, when a setgid is performed, the appropriate bit cannot be reset since there is no way to know whether it was set because of the privileges of the user or because the code file was setgid. Since setgid programs have been useful here in the creation of code with limited special privileges and since the new 4.1a code causes the undesirable effect that those privileges are passed on to offspring, I've applied the attached change to the system here. The patch operates by removing the code in exec which sets the bit in u.u_grps for the setgid group. Instead, it provides setgid access by adding to 'access' the old 4.1 code which checks for a match between the target file's gid and the effective gid of the calling process. Although this approach may be slightly less clean than the distributed 4.1a code, it allows setgid to work in the old, more reasonable, manner. Jim Madden sdcsvax!madden The changes: ------- sys1.c ------- *************** *** 379,384 u.u_uid = uid; u.u_procp->p_uid = uid; u.u_gid = gid; if (gid < NGRPS) u.u_grps[gid / (sizeof (int) * 8)] |= 1 << (gid % (sizeof (int) * 8)); --- 379,385 ----- u.u_uid = uid; u.u_procp->p_uid = uid; u.u_gid = gid; + #ifndef OLD_SETGID if (gid < NGRPS) u.u_grps[gid / (sizeof (int) * 8)] |= 1 << (gid % (sizeof (int) * 8)); *************** *** 382,387 if (gid < NGRPS) u.u_grps[gid / (sizeof (int) * 8)] |= 1 << (gid % (sizeof (int) * 8)); } else psignal(u.u_procp, SIGTRAP); u.u_tsize = ts; --- 383,389 ----- if (gid < NGRPS) u.u_grps[gid / (sizeof (int) * 8)] |= 1 << (gid % (sizeof (int) * 8)); + #endif } else psignal(u.u_procp, SIGTRAP); u.u_tsize = ts; ------- fio.c ------- *************** *** 190,195 if(u.u_uid != ip->i_uid) { #endif m >>= 3; if (ip->i_gid >= NGRPS || ((u.u_grps[ip->i_gid / (sizeof (int)*8)] & (1 << ip->i_gid % (sizeof (int)*8))) == 0)) --- 190,200 ----- if(u.u_uid != ip->i_uid) { #endif m >>= 3; + #ifdef OLD_SETGID + if (ip->i_gid != u.u_gid && (ip->i_gid >= NGRPS || + ((u.u_grps[ip->i_gid / (sizeof (int)*8)] & + (1 << ip->i_gid % (sizeof (int)*8))) == 0))) + #else if (ip->i_gid >= NGRPS || ((u.u_grps[ip->i_gid / (sizeof (int)*8)] & (1 << ip->i_gid % (sizeof (int)*8))) == 0)) *************** *** 193,198 if (ip->i_gid >= NGRPS || ((u.u_grps[ip->i_gid / (sizeof (int)*8)] & (1 << ip->i_gid % (sizeof (int)*8))) == 0)) m >>= 3; } if ((ip->i_mode&m) != 0) --- 198,204 ----- if (ip->i_gid >= NGRPS || ((u.u_grps[ip->i_gid / (sizeof (int)*8)] & (1 << ip->i_gid % (sizeof (int)*8))) == 0)) + #endif m >>= 3; } if ((ip->i_mode&m) != 0)