diff options
author | Damien Miller <djm@mindrot.org> | 2003-06-05 09:53:31 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2003-06-05 09:53:31 +1000 |
commit | 5fe46a45c834bf2e336d979e2ae755b94e01d707 (patch) | |
tree | e65443bf5183b99f97a28f7209011f60c2a620e0 /uidswap.c | |
parent | 0f68486a7673885ba2834af80fd14f1e3be16e8f (diff) |
- (djm) Implement paranoid priv dropping checks, based on:
"SetUID demystified" - Hao Chen, David Wagner and Drew Dean
Proceedings of USENIX Security Symposium 2002
Diffstat (limited to 'uidswap.c')
-rw-r--r-- | uidswap.c | 47 |
1 files changed, 47 insertions, 0 deletions
@@ -143,16 +143,63 @@ restore_uid(void) | |||
143 | void | 143 | void |
144 | permanently_set_uid(struct passwd *pw) | 144 | permanently_set_uid(struct passwd *pw) |
145 | { | 145 | { |
146 | uid_t old_uid = getuid(); | ||
147 | gid_t old_gid = getgid(); | ||
148 | |||
146 | if (temporarily_use_uid_effective) | 149 | if (temporarily_use_uid_effective) |
147 | fatal("permanently_set_uid: temporarily_use_uid effective"); | 150 | fatal("permanently_set_uid: temporarily_use_uid effective"); |
148 | debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid, | 151 | debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid, |
149 | (u_int)pw->pw_gid); | 152 | (u_int)pw->pw_gid); |
153 | |||
154 | #if defined(HAVE_SETRESGID) | ||
155 | if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) | ||
156 | fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); | ||
157 | #elif defined(HAVE_SETREGID) | ||
158 | if (setregid(pw->pw_gid, pw->pw_gid) < 0) | ||
159 | fatal("setregid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); | ||
160 | #else | ||
150 | if (setegid(pw->pw_gid) < 0) | 161 | if (setegid(pw->pw_gid) < 0) |
151 | fatal("setegid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); | 162 | fatal("setegid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); |
152 | if (setgid(pw->pw_gid) < 0) | 163 | if (setgid(pw->pw_gid) < 0) |
153 | fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); | 164 | fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); |
165 | #endif | ||
166 | |||
167 | #if defined(HAVE_SETRESUID) | ||
168 | if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) | ||
169 | fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); | ||
170 | #elif defined(HAVE_SETRESUID) | ||
171 | if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) | ||
172 | fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); | ||
173 | #else | ||
174 | # ifndef SETEUID_BREAKS_SETUID | ||
154 | if (seteuid(pw->pw_uid) < 0) | 175 | if (seteuid(pw->pw_uid) < 0) |
155 | fatal("seteuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); | 176 | fatal("seteuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); |
177 | # endif | ||
156 | if (setuid(pw->pw_uid) < 0) | 178 | if (setuid(pw->pw_uid) < 0) |
157 | fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); | 179 | fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); |
180 | #endif | ||
181 | |||
182 | /* Try restoration of GID if changed (test clearing of saved gid) */ | ||
183 | if (old_gid != pw->pw_gid && | ||
184 | (setgid(old_gid) != -1 || setegid(old_gid) != -1)) | ||
185 | fatal("%s: was able to restore old [e]gid"); | ||
186 | |||
187 | /* Verify GID drop was successful */ | ||
188 | if (getgid() != pw->pw_gid || getegid() != pw->pw_gid) { | ||
189 | fatal("%s: egid incorrect gid:%u egid:%u (should be %u)", | ||
190 | __func__, (u_int)getgid(), (u_int)getegid(), | ||
191 | (u_int)pw->pw_gid); | ||
192 | } | ||
193 | |||
194 | /* Try restoration of UID if changed (test clearing of saved uid) */ | ||
195 | if (old_uid != pw->pw_uid && | ||
196 | (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) | ||
197 | fatal("%s: was able to restore old [e]uid"); | ||
198 | |||
199 | /* Verify UID drop was successful */ | ||
200 | if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) { | ||
201 | fatal("%s: euid incorrect uid:%u euid:%u (should be %u)", | ||
202 | __func__, (u_int)getuid(), (u_int)geteuid(), | ||
203 | (u_int)pw->pw_uid); | ||
204 | } | ||
158 | } | 205 | } |