tftpd: Use setres*id() if available

POSIX apparently doesn't clearly specify the behavior of the saved ID
when calling setre*id(). If the system has setres*id() then use it to
make absolutely sure that the ID changes cannot be undone.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2024-05-29 18:10:41 -07:00
parent 99112f0206
commit 5e8d5c24b2
2 changed files with 10 additions and 4 deletions

View file

@ -86,7 +86,9 @@ AC_CHECK_FUNCS(setsid)
AC_CHECK_FUNCS(recvmsg)
AC_CHECK_FUNCS(ftruncate)
AC_CHECK_FUNCS(setreuid)
AC_CHECK_FUNCS(setresuid)
AC_CHECK_FUNCS(setregid)
AC_CHECK_FUNCS(setresgid)
AC_CHECK_FUNCS(initgroups)
AC_CHECK_FUNCS(setgroups)
AC_CHECK_FUNCS(sigaction)

View file

@ -1011,16 +1011,20 @@ int main(int argc, char **argv)
#endif
}
#ifdef HAVE_SETREGID
#ifdef HAVE_SETRESGID
setrv = setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid);
#elif defined(HAVE_SETREGID)
setrv = setregid(pw->pw_gid, pw->pw_gid);
#else
setrv = setegid(pw->pw_gid) || setgid(pw->pw_gid);
#endif
if (setrv && errno == EPERM) {
setrv = 0; /* Already restricted */
setrv = 0; /* Assume already restricted by system policy */
}
#ifdef HAVE_SETREUID
#ifdef HAVE_SETRESUID
setrv = setrv || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
#elif defined(HAVE_SETREUID)
setrv = setrv || setreuid(pw->pw_uid, pw->pw_uid);
#else
/* Important: setuid() must come first */
@ -1028,7 +1032,7 @@ int main(int argc, char **argv)
(geteuid() != pw->pw_uid && seteuid(pw->pw_uid));
#endif
if (setrv && errno == EPERM) {
setrv = 0; /* Already restricted */
setrv = 0; /* Assume already restricted by system policy */
}
if (setrv) {