zsh-workers
 help / color / mirror / code / Atom feed
* [PATCH] Silence compilation warnings about setuid, setgid
@ 2018-05-07 11:18 Sebastian Gniazdowski
  2018-06-13 11:49 ` Eitan Adler
  0 siblings, 1 reply; 11+ messages in thread
From: Sebastian Gniazdowski @ 2018-05-07 11:18 UTC (permalink / raw)
  To: Zsh hackers list


[-- Attachment #1.1: Type: text/plain, Size: 1690 bytes --]

Hello,
on a Linux box I see:

options.c:772:2: warning: ignoring return value of ‘setuid’, declared with
attribute warn_unused_res
ult [-Wunused-result]
  setuid(getuid());
  ^~~~~~~~~~~~~~~~
options.c:773:2: warning: ignoring return value of ‘setgid’, declared with
attribute warn_unused_res
ult [-Wunused-result]
  setgid(getgid());
  ^~~~~~~~~~~~~~~~

Looking at the source, the reported calls are "extra" ones, they are
followed by proper setuid, setgid calls. I've found some way out from this
situation, of using the report value and reporting it (gmail paste, proper
patch is attached):

diff --git a/Src/options.c b/Src/options.c
index 590652ea9..e085af796 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -769,13 +769,23 @@ dosetopt(int optno, int value, int force, char
*new_opts)
     } else if(optno == PRIVILEGED && !value) {
        /* unsetting PRIVILEGED causes the shell to make itself
unprivileged */
 #ifdef HAVE_SETUID
-       setuid(getuid());
-       setgid(getgid());
+       int uerr = 0, gerr = 0;
+
+       if(setuid(getuid())) {
+           uerr = errno;
+       }
+       if(setgid(getgid())) {
+           gerr = errno;
+       }
         if (setuid(getuid())) {
             zwarn("failed to change user ID: %e", errno);
+            if (uerr)
+                zwarn("(error of additional preceding setuid() call: %e)",
uerr);
             return -1;
        } else if (setgid(getgid())) {
             zwarn("failed to change group ID: %e", errno);
+            if (gerr)
+                zwarn("(error of additional preceding setgid() call: %e)",
gerr);
             return -1;
         }
 #else

[-- Attachment #1.2: Type: text/html, Size: 2082 bytes --]

[-- Attachment #2: setuid.diff.txt --]
[-- Type: text/plain, Size: 968 bytes --]

diff --git a/Src/options.c b/Src/options.c
index 590652ea9..e085af796 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -769,13 +769,23 @@ dosetopt(int optno, int value, int force, char *new_opts)
     } else if(optno == PRIVILEGED && !value) {
 	/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
 #ifdef HAVE_SETUID
-	setuid(getuid());
-	setgid(getgid());
+	int uerr = 0, gerr = 0;
+
+	if(setuid(getuid())) {
+	    uerr = errno;
+	}
+	if(setgid(getgid())) {
+	    gerr = errno;
+	}
         if (setuid(getuid())) {
             zwarn("failed to change user ID: %e", errno);
+            if (uerr)
+                zwarn("(error of additional preceding setuid() call: %e)", uerr);
             return -1;
 	} else if (setgid(getgid())) {
             zwarn("failed to change group ID: %e", errno);
+            if (gerr)
+                zwarn("(error of additional preceding setgid() call: %e)", gerr);
             return -1;
         }
 #else

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-05-07 11:18 [PATCH] Silence compilation warnings about setuid, setgid Sebastian Gniazdowski
@ 2018-06-13 11:49 ` Eitan Adler
  2018-06-13 13:10   ` Peter Stephenson
  0 siblings, 1 reply; 11+ messages in thread
From: Eitan Adler @ 2018-06-13 11:49 UTC (permalink / raw)
  To: Sebastian Gniazdowski; +Cc: Zsh hackers list

On 7 May 2018 at 04:18, Sebastian Gniazdowski <sgniazdowski@gmail.com> wrote:
> Hello,
> on a Linux box I see:
> Looking at the source, the reported calls are "extra" ones, they are
> followed by proper setuid, setgid calls. I've found some way out from this
> situation, of using the report value and reporting it (gmail paste, proper
> patch is attached):
>

>  #ifdef HAVE_SETUID
> -       setuid(getuid());
> -       setgid(getgid());

While we're touching this code can we please correct the order of
setuid and setgid?

setgid must be called before setuid. If setuid is called first, on
some platforms, it no longer has privs to call setgid aymore.

See https://wiki.sei.cmu.edu/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges
for additional details


-- 
Eitan Adler


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-13 11:49 ` Eitan Adler
@ 2018-06-13 13:10   ` Peter Stephenson
  2018-06-13 15:08     ` Bart Schaefer
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Stephenson @ 2018-06-13 13:10 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, 13 Jun 2018 04:49:39 -0700
Eitan Adler <lists@eitanadler.com> wrote:
> On 7 May 2018 at 04:18, Sebastian Gniazdowski
> <sgniazdowski@gmail.com> wrote:
> > Hello,
> > on a Linux box I see:
> > Looking at the source, the reported calls are "extra" ones, they are
> > followed by proper setuid, setgid calls. I've found some way out
> > from this situation, of using the report value and reporting it
> > (gmail paste, proper patch is attached):
> >  
> 
> >  #ifdef HAVE_SETUID
> > -       setuid(getuid());
> > -       setgid(getgid());  
> 
> While we're touching this code can we please correct the order of
> setuid and setgid?
> 
> setgid must be called before setuid. If setuid is called first, on
> some platforms, it no longer has privs to call setgid aymore.

Presumably that's a trivial swap?  I don't know if we need both
setgid()s before both setuid()s, because I don't know why they're
repeated --- but if the second case is simply to test for an error that's
not a big deal since if it worked properly there won't be one.

I didn't look at the original patch before now --- the obvious way to
fix it would simply be a cast to void.  There's no comment about why the
code is like that, so perhaps retaining the error number is safer.
However, I think it's just confusing except in the (few?)  cases where
the error number is different the first time.  I ended up with this...

diff --git a/Src/options.c b/Src/options.c
index 590652e..14d9c3c 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -769,15 +769,24 @@ dosetopt(int optno, int value, int force, char *new_opts)
     } else if(optno == PRIVILEGED && !value) {
 	/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
 #ifdef HAVE_SETUID
-	setuid(getuid());
-	setgid(getgid());
-        if (setuid(getuid())) {
-            zwarn("failed to change user ID: %e", errno);
-            return -1;
-	} else if (setgid(getgid())) {
+	int uerr = 0, gerr = 0;
+
+	errno = 0;
+	if (setgid(getgid()))
+	    gerr = errno;
+	if (setuid(getuid()))
+	    uerr = errno;
+	if (setgid(getgid())) {
             zwarn("failed to change group ID: %e", errno);
+            if (gerr && gerr != errno)
+                zwarn("(error of additional preceding setgid() call: %e)", gerr);
             return -1;
-        }
+        } else if (setuid(getuid())) {
+            zwarn("failed to change user ID: %e", errno);
+            if (uerr && uerr != errno)
+                zwarn("(error of additional preceding setuid() call: %e)", uerr);
+            return -1;
+	}
 #else
         zwarn("setuid not available");
         return -1;


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-13 13:10   ` Peter Stephenson
@ 2018-06-13 15:08     ` Bart Schaefer
  2018-06-13 15:16       ` Peter Stephenson
  2018-06-13 17:13       ` Eitan Adler
  0 siblings, 2 replies; 11+ messages in thread
From: Bart Schaefer @ 2018-06-13 15:08 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

On Wed, Jun 13, 2018 at 6:10 AM, Peter Stephenson
<p.stephenson@samsung.com> wrote:
> On Wed, 13 Jun 2018 04:49:39 -0700
> Eitan Adler <lists@eitanadler.com> wrote:
>>
>> setgid must be called before setuid. If setuid is called first, on
>> some platforms, it no longer has privs to call setgid aymore.
>
> Presumably that's a trivial swap?  I don't know if we need both
> setgid()s before both setuid()s, because I don't know why they're
> repeated --- but if the second case is simply to test for an error that's
> not a big deal since if it worked properly there won't be one.

IIRC there are some cases in which setgid/setuid fail silently, i.e.,
without changing anything but without setting errno.  The second calls
are to double-check that the first one was not rogue in that way.

This may have been isolated to a 1990s-era OS that is no longer at
issue.  Either way there's no particular reason to save and report
errno from the first call.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-13 15:08     ` Bart Schaefer
@ 2018-06-13 15:16       ` Peter Stephenson
  2018-06-13 17:13       ` Eitan Adler
  1 sibling, 0 replies; 11+ messages in thread
From: Peter Stephenson @ 2018-06-13 15:16 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, 13 Jun 2018 08:08:27 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> IIRC there are some cases in which setgid/setuid fail silently, i.e.,
> without changing anything but without setting errno.  The second calls
> are to double-check that the first one was not rogue in that way.
> 
> This may have been isolated to a 1990s-era OS that is no longer at
> issue.  Either way there's no particular reason to save and report
> errno from the first call.

Thanks, I'll change to a cast to void.

pws


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-13 15:08     ` Bart Schaefer
  2018-06-13 15:16       ` Peter Stephenson
@ 2018-06-13 17:13       ` Eitan Adler
  2018-06-13 17:19         ` Peter Stephenson
  1 sibling, 1 reply; 11+ messages in thread
From: Eitan Adler @ 2018-06-13 17:13 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Peter Stephenson, Zsh hackers list

On 13 June 2018 at 08:08, Bart Schaefer <schaefer@brasslantern.com> wrote:
> This may have been isolated to a 1990s-era OS that is no longer at
> issue.  Either way there's no particular reason to save and report
> errno from the first call.

See https://wiki.sei.cmu.edu/confluence/display/c/POS37-C.+Ensure+that+privilege+relinquishment+is+successful
I'm not sure what current systems have these issues, but explicitly
checking the results of getuid after priv-drop is still considered a
"good idea"



-- 
Eitan Adler


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-13 17:13       ` Eitan Adler
@ 2018-06-13 17:19         ` Peter Stephenson
  2018-06-13 18:41           ` dana
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Stephenson @ 2018-06-13 17:19 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, 13 Jun 2018 10:13:53 -0700
Eitan Adler <lists@eitanadler.com> wrote:

> On 13 June 2018 at 08:08, Bart Schaefer <schaefer@brasslantern.com>
> wrote:
> > This may have been isolated to a 1990s-era OS that is no longer at
> > issue.  Either way there's no particular reason to save and report
> > errno from the first call.  
> 
> See
> https://wiki.sei.cmu.edu/confluence/display/c/POS37-C.+Ensure+that+privilege+relinquishment+is+successful
> I'm not sure what current systems have these issues, but explicitly
> checking the results of getuid after priv-drop is still considered a
> "good idea"

There's no question of not testing the final result, the question is
whether we need the result of the first one that might erroneously
report success.  I've now get this.

pws

diff --git a/Src/options.c b/Src/options.c
index 590652e..a6e3216 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -769,15 +769,25 @@ dosetopt(int optno, int value, int force, char *new_opts)
     } else if(optno == PRIVILEGED && !value) {
 	/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
 #ifdef HAVE_SETUID
-	setuid(getuid());
-	setgid(getgid());
-        if (setuid(getuid())) {
-            zwarn("failed to change user ID: %e", errno);
-            return -1;
-	} else if (setgid(getgid())) {
+	errno = 0;
+	/*
+	 * Set the GID first as if we set the UID to non-privileged it
+	 * might be impossible to restore the GID.
+	 *
+	 * Some OSes (possibly no longer around) have been known to
+	 * fail silently the first time, so we attempt the change twice.
+	 * If it fails we are guaranteed to pick this up the second
+	 * time, so ignore the first time.
+	 */
+	(void)setgid(getgid());
+	(void)setuid(getuid());
+	if (setgid(getgid())) {
             zwarn("failed to change group ID: %e", errno);
             return -1;
-        }
+        } else if (setuid(getuid())) {
+            zwarn("failed to change user ID: %e", errno);
+            return -1;
+	}
 #else
         zwarn("setuid not available");
         return -1;


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-13 17:19         ` Peter Stephenson
@ 2018-06-13 18:41           ` dana
  2018-06-14  8:41             ` Peter Stephenson
  0 siblings, 1 reply; 11+ messages in thread
From: dana @ 2018-06-13 18:41 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

On 13 Jun 2018, at 12:19, Peter Stephenson <p.stephenson@samsung.com> wrote:
>+	(void)setgid(getgid());

Casting to void doesn't actually silence this warning with (at least some
versions of) GCC/glibc. If the function has the warn_unused_result attribute,
you have to (a) disable the warning entirely, (b) actually use the result
somehow, or (c) use some hack like this:
http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/ignore-value.h

dana


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-13 18:41           ` dana
@ 2018-06-14  8:41             ` Peter Stephenson
  2018-06-14 10:31               ` dana
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Stephenson @ 2018-06-14  8:41 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, 13 Jun 2018 13:41:25 -0500
dana <dana@dana.is> wrote:
> On 13 Jun 2018, at 12:19, Peter Stephenson <p.stephenson@samsung.com>
> wrote:
> >+	(void)setgid(getgid());  
> 
> Casting to void doesn't actually silence this warning with (at least
> some versions of) GCC/glibc. If the function has the
> warn_unused_result attribute, you have to (a) disable the warning
> entirely, (b) actually use the result somehow, or (c) use some hack
> like this:
> http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/ignore-value.h

Something like the following therefore ought to work generally.
Disabling an explicit cast to void is pretty broken behaviour, so I'm
gradually losing interest if for some reason this doesn't work.

pws

diff --git a/Src/options.c b/Src/options.c
index 590652e..600b649 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -769,15 +769,32 @@ dosetopt(int optno, int value, int force, char *new_opts)
     } else if(optno == PRIVILEGED && !value) {
 	/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
 #ifdef HAVE_SETUID
-	setuid(getuid());
-	setgid(getgid());
-        if (setuid(getuid())) {
-            zwarn("failed to change user ID: %e", errno);
-            return -1;
-	} else if (setgid(getgid())) {
+	int ignore_err;
+	errno = 0;
+	/*
+	 * Set the GID first as if we set the UID to non-privileged it
+	 * might be impossible to restore the GID.
+	 *
+	 * Some OSes (possibly no longer around) have been known to
+	 * fail silently the first time, so we attempt the change twice.
+	 * If it fails we are guaranteed to pick this up the second
+	 * time, so ignore the first time.
+	 *
+	 * Some versions of gcc make it hard to ignore the results the
+	 * first time, hence the following.  (These are probably not
+	 * systems that require the doubled calls.)
+	 */
+	ignore_err = setgid(getgid());
+	(void)ignore_err;
+	ignore_err = setuid(getuid());
+	(void)ignore_err;
+	if (setgid(getgid())) {
             zwarn("failed to change group ID: %e", errno);
             return -1;
-        }
+        } else if (setuid(getuid())) {
+            zwarn("failed to change user ID: %e", errno);
+            return -1;
+	}
 #else
         zwarn("setuid not available");
         return -1;


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-14  8:41             ` Peter Stephenson
@ 2018-06-14 10:31               ` dana
  2018-06-14 10:40                 ` Peter Stephenson
  0 siblings, 1 reply; 11+ messages in thread
From: dana @ 2018-06-14 10:31 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

On 14 Jun 2018, at 03:41, Peter Stephenson <p.stephenson@samsung.com> wrote:
>+	ignore_err = setgid(getgid());
>+	(void)ignore_err;

FWIW, that does seem to shut it up.

dana


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Silence compilation warnings about setuid, setgid
  2018-06-14 10:31               ` dana
@ 2018-06-14 10:40                 ` Peter Stephenson
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Stephenson @ 2018-06-14 10:40 UTC (permalink / raw)
  To: Zsh hackers list

On Thu, 14 Jun 2018 05:31:49 -0500
dana <dana@dana.is> wrote:

> On 14 Jun 2018, at 03:41, Peter Stephenson <p.stephenson@samsung.com>
> wrote:
> >+	ignore_err = setgid(getgid());
> >+	(void)ignore_err;  
> 
> FWIW, that does seem to shut it up.

Yeah, that's basically what the GNU workaround did, translated into
standard C... hopefully standard enough for everyone.

pws



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-06-14 10:40 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-07 11:18 [PATCH] Silence compilation warnings about setuid, setgid Sebastian Gniazdowski
2018-06-13 11:49 ` Eitan Adler
2018-06-13 13:10   ` Peter Stephenson
2018-06-13 15:08     ` Bart Schaefer
2018-06-13 15:16       ` Peter Stephenson
2018-06-13 17:13       ` Eitan Adler
2018-06-13 17:19         ` Peter Stephenson
2018-06-13 18:41           ` dana
2018-06-14  8:41             ` Peter Stephenson
2018-06-14 10:31               ` dana
2018-06-14 10:40                 ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).