From bd8683d0fd36893c18e7271faaa3b9ea67df0695 Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Fri, 2 Dec 2022 11:53:35 +0000 Subject: [PATCH] add tests and compat for setresuid and setresgid --- compat/Makefile | 2 ++ compat/setresgid.c | 32 +++++++++++++++++++++++++ compat/setresuid.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ configure | 15 ++++++++++++ have/Makefile | 2 ++ have/setresgid.c | 8 +++++++ have/setresuid.c | 8 +++++++ 7 files changed, 127 insertions(+) create mode 100644 compat/setresgid.c create mode 100644 compat/setresuid.c create mode 100644 have/setresgid.c create mode 100644 have/setresuid.c diff --git a/compat/Makefile b/compat/Makefile index 57db3ea..e98fdd6 100644 --- a/compat/Makefile +++ b/compat/Makefile @@ -13,6 +13,8 @@ DISTFILES = Makefile \ reallocarray.c \ recallocarray.c \ setproctitle.c \ + setresgid.c \ + setresuid.c \ strlcat.c \ strlcpy.c \ strtonum.c \ diff --git a/compat/setresgid.c b/compat/setresgid.c new file mode 100644 index 0000000..ec625cd --- /dev/null +++ b/compat/setresgid.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +int +setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + /* this is the only configuration tested */ + + if (rgid != egid || egid != sgid) + return -1; + + if (setregid(rgid, egid) == -1) + return -1; + + return 0; +} diff --git a/compat/setresuid.c b/compat/setresuid.c new file mode 100644 index 0000000..a033d99 --- /dev/null +++ b/compat/setresuid.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +int +setresuid(uid_t ruid, uid_t euid, uid_t suid) +{ + uid_t ouid; + int ret = -1; + + /* Allow only the tested configuration. */ + + if (ruid != euid || euid != suid) { + errno = ENOSYS; + return -1; + } + ouid = getuid(); + + if ((ret = setreuid(euid, euid)) == -1) + return -1; + + /* + * When real, effective and saved uids are the same and we have + * changed uids, sanity check that we cannot restore the old uid. + */ + + if (ruid == euid && euid == suid && ouid != ruid && + setuid(ouid) != -1 && seteuid(ouid) != -1) { + errno = EINVAL; + return -1; + } + + /* + * Finally, check that the real and effective uids are what we + * expect. + */ + if (getuid() != ruid || geteuid() != euid) { + errno = EACCES; + return -1; + } + + return ret; +} diff --git a/configure b/configure index 0127a01..55b6a99 100755 --- a/configure +++ b/configure @@ -258,6 +258,8 @@ runtest queue_h QUEUE_H || true runtest reallocarray REALLOCARRAY || true runtest recallocarray RECALLOCARRAY || true runtest setproctitle SETPROCTITLE || true +runtest setresgid SETRESGID "" -D_GNU_SOURCE || true +runtest setresuid SETRESUID "" -D_GNU_SOURCE || true runtest strlcat STRLCAT || true runtest strlcpy STRLCPY || true runtest strtonum STRTONUM || true @@ -343,6 +345,8 @@ cat <<__HEREDOC__ #define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} #define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY} #define HAVE_SETPROCTITLE ${HAVE_SETPROCTITLE} +#define HAVE_SETRESGID ${HAVE_SETRESGID} +#define HAVE_SETRESUID ${HAVE_SETRESUID} #define HAVE_STRLCAT ${HAVE_STRLCAT} #define HAVE_STRLCPY ${HAVE_STRLCPY} #define HAVE_STRTONUM ${HAVE_STRTONUM} @@ -359,6 +363,9 @@ __HEREDOC__ ${HAVE_STRLCPY} -eq 0 -o \ ${HAVE_STRTONUM} -eq 0 ] && echo "#include " +[ ${HAVE_SETRESGID} -eq 0 -o \ + ${HAVE_SETRESUID} -eq 0 ] && echo "#include " + if [ ${HAVE_ERR} -eq 0 ]; then echo "extern void err(int, const char*, ...);" echo "extern void errx(int, const char*, ...);" @@ -407,6 +414,14 @@ if [ ${HAVE_SETPROCTITLE} -eq 0 ]; then echo "extern void setproctitle(const char *fmt, ...);" COBJS="${COBJS} compat/setproctitle.o" fi +if [ ${HAVE_SETRESGID} -eq 0 ]; then + echo "extern int setresgid(gid_t, gid_t, gid_t);" + COBJS="${COBJS} compat/setresgid.o" +fi +if [ ${HAVE_SETRESUID} -eq 0 ]; then + echo "extern int setresuid(uid_t, uid_t, uid_t);" + COBJS="${COBJS} compat/setresuid.o" +fi if [ ${HAVE_STRLCAT} -eq 0 ]; then echo "extern size_t strlcat(char*, const char*, size_t);" COBJS="${COBJS} compat/strlcat.o" diff --git a/have/Makefile b/have/Makefile index 4ac7158..3aa1b97 100644 --- a/have/Makefile +++ b/have/Makefile @@ -19,6 +19,8 @@ DISTFILES = Makefile \ reallocarray.c \ recallocarray.c \ setproctitle.c \ + setresgid.c \ + setresuid.c \ strlcat.c \ strlcpy.c \ strtonum.c \ diff --git a/have/setresgid.c b/have/setresgid.c new file mode 100644 index 0000000..616458f --- /dev/null +++ b/have/setresgid.c @@ -0,0 +1,8 @@ +#include +#include + +int +main(void) +{ + return setresgid(-1, -1, -1) == -1; +} diff --git a/have/setresuid.c b/have/setresuid.c new file mode 100644 index 0000000..0f3f65c --- /dev/null +++ b/have/setresuid.c @@ -0,0 +1,8 @@ +#include +#include + +int +main(void) +{ + return setresuid(-1, -1, -1) == -1; +}