From 8250c5c168f07549ed646e6848e6dda118271e23 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 26 Dec 2019 09:16:19 +0000 Subject: Improve PRIVILEGED fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix retval handling in bin_setopt() - Don't skip_setuid / skip_setgid. It's not our place to optimize away noops (that might not even _be_ noops; they might change the saved uid…). - Remove HAVE_* guard checks around functions that are used unguarded elsewhere. - Use bsd-setres_id.c from OpenSSH to provide setresuid() / setresgid() everywhere, and thus simplify the ifdef soup. Fix some preëxisting bugs in the macro definitions of setuid() (do we still need that one?). - Fix zwarning() format codes for variadic arguments type safety - Restored a comment from HEAD - Fix failure modes around initgroups() - Compared privilege restoration code with OpenSSH's permanently_drop_uid() and updated as needed - Add E01 PRIVILEGED sanity checks --- Src/zsh_system.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 17 deletions(-) (limited to 'Src/zsh_system.h') diff --git a/Src/zsh_system.h b/Src/zsh_system.h index 85e198f2e..161b073b4 100644 --- a/Src/zsh_system.h +++ b/Src/zsh_system.h @@ -468,30 +468,90 @@ struct timespec { # define setpgrp setpgid #endif -/* can we set the user/group id of a process */ +/* compatibility wrappers */ -#ifndef HAVE_SETUID +/* Our strategy is as follows: + * + * - Ensure that either setre[ug]id() or set{e,}[ug]id() is available. + * - If setres[ug]id() are missing, provide them in terms of either + * setre[ug]id() or set{e,}[ug]id(), whichever is available. + * - Provide replacement setre[ug]id() or set{e,}[ug]id() if they are not + * available natively. + * + * There isn't a circular dependency because, right off the bat, we check that + * there's an end condition, and #error out otherwise. + */ +#if !defined(HAVE_SETREUID) && !(defined(HAVE_SETEUID) && defined(HAVE_SETUID)) + /* + * If you run into this error, you have two options: + * - Teach zsh how to do the equivalent of setreuid() on your system + * - Remove support for PRIVILEGED option, and then remove the #error. + */ +# error "Don't know how to change UID" +#endif +#if !defined(HAVE_SETREGID) && !(defined(HAVE_SETEGID) && defined(HAVE_SETGID)) + /* See above comment. */ +# error "Don't know how to change GID" +#endif + +/* Provide setresuid(). */ +#ifndef HAVE_SETRESUID +int setresuid(uid_t, uid_t, uid_t); +# define HAVE_SETRESUID +# define ZSH_IMPLEMENT_SETRESUID # ifdef HAVE_SETREUID -# define setuid(X) setreuid(X,X) -# define setgid(X) setregid(X,X) -# define HAVE_SETUID +# define ZSH_HAVE_NATIVE_SETREUID # endif #endif -/* can we set the effective user/group id of a process */ +/* Provide setresgid(). */ +#ifndef HAVE_SETRESGID +int setresgid(gid_t, gid_t, gid_t); +# define HAVE_SETRESGID +# define ZSH_IMPLEMENT_SETRESGID +# ifdef HAVE_SETREGID +# define ZSH_HAVE_NATIVE_SETREGID +# endif +#endif +/* Provide setreuid(). */ +#ifndef HAVE_SETREUID +# define setreuid(X, Y) setresuid((X), (Y), -1) +# define HAVE_SETREUID +#endif + +/* Provide setregid(). */ +#ifndef HAVE_SETREGID +# define setregid(X, Y) setresgid((X), (Y), -1) +# define HAVE_SETREGID +#endif + +/* Provide setuid(). */ +/* ### TODO: Either remove this (this function has been standard since 1985), + * ### or rewrite this without multiply-evaluating the argument */ +#ifndef HAVE_SETUID +# define setuid(X) setreuid((X), (X)) +# define HAVE_SETUID +#endif + +/* Provide setgid(). */ +#ifndef HAVE_SETGID +/* ### TODO: Either remove this (this function has been standard since 1985), + * ### or rewrite this without multiply-evaluating the argument */ +# define setgid(X) setregid((X), (X)) +# define HAVE_SETGID +#endif + +/* Provide seteuid(). */ #ifndef HAVE_SETEUID -# ifdef HAVE_SETREUID -# define seteuid(X) setreuid(-1,X) -# define setegid(X) setregid(-1,X) -# define HAVE_SETEUID -# else -# ifdef HAVE_SETRESUID -# define seteuid(X) setresuid(-1,X,-1) -# define setegid(X) setresgid(-1,X,-1) -# define HAVE_SETEUID -# endif -# endif +# define seteuid(X) setreuid(-1, (X)) +# define HAVE_SETEUID +#endif + +/* Provide setegid(). */ +#ifndef HAVE_SETEGID +# define setegid(X) setregid(-1, (X)) +# define HAVE_SETEGID #endif #ifdef HAVE_SYS_RESOURCE_H -- cgit 1.4.1