bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: chmod set-gid/set-uid behavior change issues


From: Paul Eggert
Subject: Re: chmod set-gid/set-uid behavior change issues
Date: Tue, 25 Jul 2006 11:53:02 -0700
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

address@hidden (Bob Proulx) writes:

> Contrary to the statement above my testing shows that FreeBSD chmod
> does not behave this way.

OK, thanks, clearly NEWS (at least :-) needs to get fixed.

The behavior I observe on OpenBSD 3.9 is that sometimes the setgid bit
is preserved, and sometimes not.  For example, mkdir preserves it but
chmod does not (the working directory is setgid here):

   30-alkaid $ mkdir -m 777 d
   31-alkaid $ ls -ld d
   drwxrwsrwx  2 eggert  eggert  512 Jul 25 10:36 d
   32-alkaid $ chmod 777 d
   33-alkaid $ ls -ld d
   drwxrwxrwx  2 eggert  eggert  512 Jul 25 10:36 d

This is clearly inconsistent.

Solaris 10 is more consistent, in that mkdir and chmod both
preserve the setgid bit:

   1006-moa $ mkdir -m 777 d
   1007-moa $ ls -ld d
   drwxrwsrwx   2 eggert   faculty      512 Jul 25 11:22 d
   1008-moa $ chmod 777 d
   1009-moa $ ls -ld d
   drwxrwsrwx   2 eggert   faculty      512 Jul 25 11:22 d

However, the behavior with "chmod 777" contradicts what FreeBSD and
HP-UX do for "chmod 500".

Clearly there is no consistency here across systems, which gives us a
bit of freedom to decide what is the best thing to do for GNU.

> I don't think it is a good idea to make
>
>   chmod 500 dir
>
> behave differently than
>
>   chmod 0500 dir
>
> That simply seems too subtle and will be too confusing to most people.

It is a bit subtle, and if there is consensus on this I'd be willing
to remove this feature.  However, in normal use it is more convenient
if "chmod 755 DIR" preserves the setgid bit.  Also, it is more
consistent with what Solaris does, since Solaris "chmod 755 DIR"
preserves setgid.

If we remove this feature, I'd like to change things to be 100%
consistent with Solaris, and to preserve the setgid bit even if the
user says "chmod 0755 DIR".  (Of course this will require changing
tests/cp/fail-perm again, since "chmod 0500 DIR" will also preserve
setgid.  :-) However, I would argue that this is more confusing than
what we've got right now, since "chmod 0755 DIR" clearly requests to
clear the setgid bit.

Perhaps Jim has an opinion?

In the meantime I installed the following, since the documentation
needs to get fixed even if we change nothing else, and changing the
test case won't hurt even if we change the implementation back to the
old way.

2006-07-25  Paul Eggert  <address@hidden>

        * NEWS: Clarify the "chmod 0500" news, and correct the vague
        statements about compatibility with BSD.
        * doc/perm.texi (Directory Setuid and Setgid): Explain that this is a
        GNU extension, and that other systems behave differently here.
        * tests/cp/fail-perm: Use "chmod 0500" rather than "chmod 500".
        Problem report and fix from Bob Proulx.

--- NEWS        21 Jul 2006 08:58:00 -0000      1.394
+++ NEWS        25 Jul 2006 18:37:23 -0000
@@ -26,13 +26,21 @@ GNU coreutils NEWS                      
   basename and dirname now treat // as different from / on platforms
   where the two are distinct.
 
-  chmod, install, and mkdir now leave a directory's set-user-ID and
-  set-group-ID bits alone unless you explicitly request otherwise.
-  This is for compatibility with BSD and other systems.  For example,
+  chmod, install, and mkdir now preserve a directory's set-user-ID and
+  set-group-ID bits unless you explicitly request otherwise.  E.g.,
   `chmod 755 DIR' and `chmod u=rwx,go=rx DIR' now preserve DIR's
-  set-user-ID and set-group-ID bits instead of clearing them.  If
-  you want to clear the bits you can mention them explicitly, e.g.,
-  `chmod 0755 DIR' and `chmod a-s,u=rwx,go=rx DIR'.
+  set-user-ID and set-group-ID bits instead of clearing them, and
+  similarly for `mkdir -m 755 DIR' and `mkdir -m u=rwx,go=rx DIR'.  To
+  clear the bits, mention them explicitly, e.g., `chmod 0755 DIR' or
+  `mkdir -m a-s,u=rwx,go=rx DIR'.  This change is for convenience on
+  systems where these bits inherit from parents.  Unfortunately other
+  operating systems are not consistent here, and portable scripts
+  cannot assume the bits are set, cleared, or preserved, even when the
+  bits are explicitly mentioned.  For example, OpenBSD 3.9 `mkdir -m
+  777 D' preserves D's setgid bit but `chmod 777 D' clears it.
+  Conversely, Solaris 10 `mkdir -m 777 D', `mkdir -m g-s D', and
+  `chmod 0777 D' all preserve D's setgid bit, and you must use
+  something like `chmod g-s D' to clear it.
 
   `cp --link --no-dereference' now works also on systems where the
   link system call cannot create a hard link to a symbolic link.
--- doc/perm.texi       23 Jul 2006 01:26:56 -0000      1.18
+++ doc/perm.texi       25 Jul 2006 18:37:23 -0000
@@ -537,7 +537,7 @@ bits of new subdirectories.  These mecha
 more easily, by lessening the need to use @command{chmod} or
 @command{chown} to share new files.
 
-These convenience mechanisms rely on the set-group-ID and set-user-ID
+These convenience mechanisms rely on the set-user-ID and set-group-ID
 bits of directories.  If commands like @command{chmod} and
 @command{mkdir} routinely cleared these bits on directories, the
 mechanisms would be less convenient and it would be harder to share
@@ -557,11 +557,11 @@ mkdir -m 755 c
 mkdir -m u=rwx,go=rx d
 @end example
 
-If you want to clear these bits, you must mention them explicitly in
-the symbolic or numeric modes, e.g.:
+If you want to try to clear these bits, you must mention them
+explicitly in the symbolic or numeric modes, e.g.:
 
 @example
-# These commands clear the set-user-ID
+# These commands try to clear the set-user-ID
 # and set-group-ID bits of the subdirectories.
 mkdir a b
 chmod 0755 a
@@ -569,3 +569,7 @@ chmod a-s,u=rwx,go=rx b
 mkdir -m 0755 c
 mkdir -m a-s,u=rwx,go=rx d
 @end example
+
+This behavior is a @acronym{GNU} extension.  Portable scripts should
+not rely on requests to set or clear these bits on directories, as
address@hidden allows implementations to ignore these requests.
--- tests/cp/fail-perm  28 May 2006 12:11:35 -0000      1.10
+++ tests/cp/fail-perm  25 Jul 2006 18:37:23 -0000
@@ -20,7 +20,7 @@ cd $tmp || framework_failure=1
 mkdir D D/D || framework_failure=1
 touch D/a || framework_failure=1
 chmod 0 D/a || framework_failure=1
-chmod 500 D || framework_failure=1
+chmod 0500 D || framework_failure=1
 
 if test $framework_failure = 1; then
   echo 'failure in testing framework'




reply via email to

[Prev in Thread] Current Thread [Next in Thread]