bug-coreutils
[Top][All Lists]
Advanced

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

Re: some other problems with chmod-safer.c, chown.c, etc.


From: Paul Eggert
Subject: Re: some other problems with chmod-safer.c, chown.c, etc.
Date: Sun, 01 Jan 2006 23:56:31 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

I installed the following to make coreutils act like FreeBSD with
respect to when chmod() is invoked, along the lines I suggested
earlier today.  I noticed several other places where chmod can safely
be replaced by lchmod, and did those too, as that makes the programs
slightly safer in the presence of directories that are writeable by
attackers.  When in doubt I left chmods alone, though.

If there's something amiss with this please let me know; it's easy
enough to back out the change.

We could get fancier and use fchmod for readable directories and for
readable or writeable regular files, falling back on lchmod for
everything else; but this still suffers from the same race conditions
that lchmod suffers from, and I'm not sure it's worth the hassle.

2006-01-01  Paul Eggert  <address@hidden>

        * NEWS: Document that mkfifo and mknod -m no longer set special bits.
        * doc/coreutils.texi, perm.texi: Clarify file mode bits versus
        file permission bits.
        * doc/coreutils.texi (mkfifo invocation, mknod invocation): -m
        affects only file permission bits.
        * lib/chmod-safer.c, chmod-safer.h: Remove.
        * lib/lchmod.h: New file.
        * lib/mkdir-p.c: Include lchmod.h, lchown.h.
        (make_dir_parents): Use lchown rather than chown, and
        lchmod rather than chmod.
        * m4/chmod-safer.m4: Remove.
        * m4/lchmod.m4: New file.
        * m4/jm-macros.m4 (gl_MACROS): Require gl_FUNC_LCHMOD.
        Don't require gl_CHDIR_SAFER.
        * src/copy.c: Include lchmod.h.
        (copy_internal): Use lchmod rather than chmod.
        * src/cp.c: Include lchmod.h.
        (re_protect, make_dir_parents_private): Use lchmod rather than chmod.
        * src/mkdir.c: Include lchmod.h.
        (usage): Clarify -m's operation.
        (main): Use lchmod rather than chmod.  Don't use lchmod unless the
        new mode contains bits outside the 777 range.
        * src/mkfifo.c (usage): Clarify -m's operation.
        (main): If -m is given, don't invoke chmod; use umask 0 instead.
        Report an error if -m asks for bits outside the 777 range.
        * src/mknod.c (usage, main): Likewise.

        * src/mkdir.c, src/mkfifo.c, src/mknod.c: Undo 2005-12-19 changes.

Index: NEWS
===================================================================
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.354
diff -p -u -r1.354 NEWS
--- NEWS        15 Dec 2005 12:24:54 -0000      1.354
+++ NEWS        2 Jan 2006 07:27:03 -0000
@@ -23,6 +23,9 @@ GNU coreutils NEWS                      
   if your locale settings appear to be messed up.  This change
   attempts to have the default be the best of both worlds.
 
+  mkfifo and mknod no longer set special mode bits (setuid, setgid,
+  and sticky) with the -m option.
+
   sort now reports incompatible options (e.g., -i and -n) rather than
   silently ignoring one of them.
 
Index: doc/coreutils.texi
===================================================================
RCS file: /fetish/cu/doc/coreutils.texi,v
retrieving revision 1.303
diff -p -u -r1.303 coreutils.texi
--- doc/coreutils.texi  29 Dec 2005 21:45:32 -0000      1.303
+++ doc/coreutils.texi  2 Jan 2006 07:27:06 -0000
@@ -5683,7 +5683,7 @@ uniquely identifies each file within a p
 @opindex --format
 @opindex long ls @r{format}
 @opindex verbose ls @r{format}
-In addition to the name of each file, print the file type, permissions,
+In addition to the name of each file, print the file type, file mode bits,
 number of hard links, owner name, group name, size, and
 timestamp (@pxref{Formatting file timestamps}), normally
 the modification time.
@@ -5702,7 +5702,7 @@ The @var{blocks} computed counts each ha
 this is arguably a deficiency.
 
 @cindex permissions, output by @command{ls}
-The permissions listed are similar to symbolic mode specifications
+The file mode bits listed are similar to symbolic mode specifications
 (@pxref{Symbolic Modes}).  But @command{ls} combines multiple bits into the
 third character of each set of permissions as follows:
 @table @samp
@@ -5727,14 +5727,14 @@ If the executable bit is set and none of
 Otherwise.
 @end table
 
-Following the permission bits is a single character that specifies
+Following the file mode bits is a single character that specifies
 whether an alternate access method such as an access control list
-applies to the file. When the character following the permissions is a
-space, there is no alternate access method. When it is a printing
+applies to the file.  When the character following the file mode bits is a
+space, there is no alternate access method.  When it is a printing
 character, then there is such a method.
 
 For a file with an extended access control list, a @samp{+} character is
-listed. Basic access control lists are equivalent to the permissions
+listed.  Basic access control lists are equivalent to the permissions
 listed, and are not considered an alternate access method.
 
 @item -n
@@ -6572,7 +6572,7 @@ of one or more of the following strings:
 
 @table @samp
 @itemx mode
-Preserve the permission attributes, including access control lists.
+Preserve the file mode bits and access control lists.
 @itemx ownership
 Preserve the owner and group.  On most modern systems,
 only the super-user may change the owner of a file, and regular users
@@ -6594,7 +6594,7 @@ Using @option{--preserve} with no @var{a
 to @option{--preserve=mode,ownership,timestamps}.
 
 In the absence of this option, each destination file is created with the
-permissions of the corresponding source file, minus the bits set in the
+mode bits of the corresponding source file, minus the bits set in the
 umask and minus the set-user-ID and set-group-ID bits.
 @xref{File permissions}.
 
@@ -7057,7 +7057,7 @@ environment variable is set.
 @pindex install
 @cindex copying files and setting attributes
 
address@hidden copies files while setting their permission modes and, if
address@hidden copies files while setting their file mode bits and, if
 possible, their owner and group.  Synopses:
 
 @example
@@ -7128,7 +7128,7 @@ may be either a group name or a numeric 
 @opindex -m
 @opindex --mode
 @cindex permissions of installed files, setting
-Set the permissions for the installed file or directory to @var{mode},
+Set the file mode bits for the installed file or directory to @var{mode},
 which can be either an octal number, or a symbolic mode as in
 @command{chmod}, with @samp{a=} (no access allowed to anyone) as the
 point of departure (@pxref{File permissions}).
@@ -7898,8 +7898,8 @@ everyone) for the point of the departure
 @opindex -p
 @opindex --parents
 @cindex parent directories, creating
-Make any missing parent directories for each argument.  The mode for parent
-directories is set to the umask modified by @samp{u+wx}.
+Make any missing parent directories for each argument.  The file permission
+bits of parent directories are set to the umask modified by @samp{u+wx}.
 Ignore arguments corresponding to existing directories.
 
 @item -v
@@ -7944,7 +7944,8 @@ The program accepts the following option
 @cindex modes of created FIFOs, setting
 Set the mode of created FIFOs to @var{mode}, which is symbolic as in
 @command{chmod} and uses @samp{a=rw} (read and write allowed for everyone)
-for the point of departure.  @xref{File permissions}.
+for the point of departure.  @var{mode} should specify only file
+permission bits.  @xref{File permissions}.
 
 @end table
 
@@ -8015,6 +8016,7 @@ The program accepts the following option
 @opindex --mode
 Set the mode of created files to @var{mode}, which is symbolic as in
 @command{chmod} and uses @samp{a=rw} as the point of departure.
address@hidden should specify only file permission bits.
 @xref{File permissions}.
 
 @end table
@@ -8567,7 +8569,7 @@ line, @command{chmod} changes the permis
 In contrast, @command{chmod} ignores symbolic links encountered during
 recursive directory traversals.
 
-If used, @var{mode} specifies the new permissions.
+If used, @var{mode} specifies the new file mode bits.
 For details, see the section on @ref{File permissions}.
 If you really want @var{mode} to have a leading @samp{-}, you should
 use @option{--} first, e.g., @samp{chmod -- -w file}.  Typically,
Index: doc/perm.texi
===================================================================
RCS file: /fetish/cu/doc/perm.texi,v
retrieving revision 1.13
retrieving revision 1.15
diff -p -u -r1.13 -r1.15
--- doc/perm.texi       13 Nov 2005 18:57:17 -0000      1.13
+++ doc/perm.texi       2 Jan 2006 07:42:35 -0000       1.15
@@ -1,6 +1,5 @@
-Each file has a set of @dfn{permissions} that control the kinds of
-access that users have to that file.  The permissions for a file are
-also called its @dfn{access mode}.  They can be represented either in
+Each file has a set of @dfn{file mode bits} that control the kinds of
+access that users have to that file.  They can be represented either in
 symbolic form or as an octal number.
 
 @menu
@@ -12,6 +11,10 @@ symbolic form or as an octal number.
 @node Mode Structure
 @section Structure of File Permissions
 
+The file mode bits have two parts: the @dfn{file permission bits},
+which control ordinary access to the file, and @dfn{special mode
+bits}, which affect only some files.
+
 There are three kinds of permissions that a user can have for a file:
 
 @enumerate
@@ -50,8 +53,8 @@ file system the file is created on, and 
 can change the owner and group of a file by using the @command{chown} and
 @command{chgrp} commands.
 
-In addition to the three sets of three permissions listed above, a
-file's permissions have three special components, which affect only
+In addition to the three sets of three permissions listed above, the
+file mode bits have three special components, which affect only
 executable files (programs) and, on some systems, directories:
 
 @enumerate
@@ -78,9 +81,9 @@ swap device so it will load more quickly
 @dfn{sticky bit}.
 @end enumerate
 
-In addition to the permissions listed above, there may be file attributes
-specific to the file system, e.g: access control lists (ACLs), whether a
-file is compressed, whether a file can be modified (immutability), whether
+In addition to the file mode bits listed above, there may be file attributes
+specific to the file system, e.g., access control lists (ACLs), whether a
+file is compressed, whether a file can be modified (immutability), and whether
 a file can be dumped.  These are usually set using programs
 specific to the file system.  For example:
 @c should probably say a lot more about ACLs... someday
@@ -96,7 +99,7 @@ On FreeBSD the file permissions (``flags
 file system are set using @command{chrflags}.
 @end table
 
-Although a file's permission ``bits'' allow an operation on that file,
+Even if a file's permission bits allow an operation on that file,
 that operation may still fail, because:
 
 @itemize
@@ -115,9 +118,9 @@ may have just run @code{chmod a+w FILE}.
 @section Symbolic Modes
 
 @cindex symbolic modes
address@hidden modes} represent changes to files' permissions as
address@hidden modes} represent changes to files' mode bits as
 operations on single-character symbols.  They allow you to modify either
-all or selected parts of files' permissions, optionally based on
+all or selected parts of files' mode bits, optionally based on
 their previous values, and perhaps on the current @code{umask} as well
 (@pxref{Umask and Protection}).
 
@@ -137,7 +140,7 @@ symbolic modes.
 @menu
 * Setting Permissions::          Basic operations on permissions.
 * Copying Permissions::          Copying existing permissions.
-* Changing Special Permissions:: Special permissions.
+* Changing Special Mode Bits::   Special mode bits.
 * Conditional Executability::    Conditionally affecting executability.
 * Multiple Changes::             Making multiple changes.
 * Umask and Protection::              The effect of the umask.
@@ -275,34 +278,34 @@ it to mode 666 (@samp{rw-rw-rw-}).  If t
 (@samp{rwxr--r-x}).  The @samp{-} and @samp{=} operations work
 analogously.
 
address@hidden Changing Special Permissions
address@hidden Changing Special Permissions
address@hidden Changing Special Mode Bits
address@hidden Changing Special Mode Bits
 
address@hidden changing special permissions
address@hidden changing special mode bits
 In addition to changing a file's read, write, and execute permissions,
-you can change its special permissions.  @xref{Mode Structure}, for a
-summary of these permissions.
+you can change its special mode bits.  @xref{Mode Structure}, for a
+summary of these special mode bits.
 
-To change a file's permission to set the user ID on execution, use
+To change the file mode bits to set the user ID on execution, use
 @samp{u} in the @var{users} part of the symbolic mode and
address@hidden in the @var{permissions} part.
address@hidden instead of the @var{permissions} part.
 
-To change a file's permission to set the group ID on execution, use
+To change the file mode bits to set the group ID on execution, use
 @samp{g} in the @var{users} part of the symbolic mode and
address@hidden in the @var{permissions} part.
address@hidden instead of the @var{permissions} part.
 
-To change a file's permission to set the restricted deletion flag or sticky 
bit,
-omit the @var{users} part of the symbolic mode (or use @samp{a}) and put
address@hidden in the @var{permissions} part.
+To change the file mode bits to set the restricted deletion flag or sticky bit,
+omit the @var{users} part of the symbolic mode (or use @samp{a}) and use
address@hidden instead of the @var{permissions} part.
 
-For example, to add set-user-ID permission to a program,
+For example, to set the set-user-ID mode bit of a program,
 you can use the mode:
 
 @example
 u+s
 @end example
 
-To remove both set-user-ID and set-group-ID permission from
+To remove both set-user-ID and set-group-ID mode bits from
 it, you can use the mode:
 
 @example
@@ -320,7 +323,7 @@ The combination @samp{o+s} has no effect
 the combinations @samp{u+t} and @samp{g+t} have no effect, and
 @samp{o+t} acts like plain @samp{+t}.
 
-The @samp{=} operator is not very useful with special permissions; for
+The @samp{=} operator is not very useful with special mode bits; for
 example, the mode:
 
 @example
@@ -356,7 +359,7 @@ anyone could execute them before.
 @cindex multiple changes to permissions
 The format of symbolic modes is actually more complex than described
 above (@pxref{Setting Permissions}).  It provides two ways to make
-multiple changes to files' permissions.
+multiple changes to files' mode bits.
 
 The first way is to specify multiple @var{operation} and
 @var{permissions} parts after a @var{users} part in the symbolic mode.
@@ -396,7 +399,7 @@ u=rwx,g=rx,o=
 @end example
 
 @noindent
-sets all of the non-special permissions for the file explicitly.  (It
+sets all of the permission bits for the file explicitly.  (It
 gives users who are not in the file's group no permission at all for
 it.)
 
@@ -457,7 +460,7 @@ the file to all users.
 @section Numeric Modes
 
 @cindex numeric modes
address@hidden file permissions, numeric
address@hidden file mode bits, numeric
 @cindex octal numbers for file modes
 As an
 alternative to giving a symbolic mode, you can give an octal (base 8)
@@ -466,20 +469,20 @@ This number is always interpreted in oct
 leading 0, as you do in C.  Mode 0055 is the same as mode 55.
 
 A numeric mode is usually shorter than the corresponding symbolic
-mode, but it is limited in that it cannot take into account a file's
-previous permissions; it can only set them absolutely.
+mode, but it is limited in that it cannot take into account the
+previous file mode bits; it can only set them absolutely.
 
 The permissions granted to the user,
 to other users in the file's group,
 and to other users not in the file's group each require three
 bits, which are represented as one octal digit.  The three special
-permissions also require one bit each, and they are as a group
+mode bits also require one bit each, and they are as a group
 represented as another octal digit.  Here is how the bits are arranged,
 starting with the lowest valued bit:
 
 @example
 Value in  Corresponding
-Mode      Permission
+Mode      Mode Bit
 
           Other users not in the file's group:
    1      Execute
@@ -496,7 +499,7 @@ Mode      Permission
  200      Write
  400      Read
 
-          Special permissions:
+          Special mode bits:
 1000      Restricted deletion flag or sticky bit
 2000      Set group ID on execution
 4000      Set user ID on execution
Index: lib/mkdir-p.c
===================================================================
RCS file: /fetish/cu/lib/mkdir-p.c,v
retrieving revision 1.18
diff -p -u -r1.18 mkdir-p.c
--- lib/mkdir-p.c       23 Dec 2005 18:15:33 -0000      1.18
+++ lib/mkdir-p.c       2 Jan 2006 06:12:20 -0000
@@ -42,6 +42,8 @@
 #include "chdir-safer.h"
 #include "dirname.h"
 #include "error.h"
+#include "lchmod.h"
+#include "lchown.h"
 #include "quote.h"
 #include "save-cwd.h"
 #include "stat-macros.h"
@@ -195,7 +197,7 @@ make_dir_parents (char const *arg,
                error (0, 0, verbose_fmt_string, quote (dir));
 
              if ((owner != (uid_t) -1 || group != (gid_t) -1)
-                 && chown (basename_dir, owner, group)
+                 && lchown (basename_dir, owner, group)
 #if defined AFS && defined EPERM
                  && errno != EPERM
 #endif
@@ -302,7 +304,7 @@ make_dir_parents (char const *arg,
 
       if (owner != (uid_t) -1 || group != (gid_t) -1)
        {
-         if (chown (fixup_permissions_dir, owner, group) != 0
+         if (lchown (fixup_permissions_dir, owner, group) != 0
 #ifdef AFS
              && errno != EPERM
 #endif
@@ -319,7 +321,7 @@ make_dir_parents (char const *arg,
         required to honor only the file permission bits.  In particular,
         it need not honor the `special' bits, so if MODE includes any
         special bits, set them here.  */
-      if ((mode & ~S_IRWXUGO) && chmod (fixup_permissions_dir, mode) != 0)
+      if ((mode & ~S_IRWXUGO) && lchmod (fixup_permissions_dir, mode) != 0)
        {
          error (0, errno, _("cannot change permissions of %s"),
                 quote (full_dir));
@@ -343,7 +345,7 @@ make_dir_parents (char const *arg,
     {
       leading_dirs->dirname_end[0] = '\0';
       if ((cwd_problem && *full_dir != '/')
-         || chmod (full_dir, parent_mode) != 0)
+         || lchmod (full_dir, parent_mode) != 0)
        {
          error (0, (cwd_problem ? 0 : errno),
                 _("cannot change permissions of %s"), quote (full_dir));
Index: m4/jm-macros.m4
===================================================================
RCS file: /fetish/cu/m4/jm-macros.m4,v
retrieving revision 1.236
diff -p -u -r1.236 jm-macros.m4
--- m4/jm-macros.m4     21 Dec 2005 10:21:04 -0000      1.236
+++ m4/jm-macros.m4     2 Jan 2006 06:12:20 -0000
@@ -50,6 +50,7 @@ AC_DEFUN([gl_MACROS],
 
   AC_REQUIRE([gl_FUNC_DIRFD])
   AC_REQUIRE([AC_FUNC_ACL])
+  AC_REQUIRE([gl_FUNC_LCHMOD])
   AC_REQUIRE([gl_FUNC_LCHOWN])
   AC_REQUIRE([gl_FUNC_RMDIR_NOTEMPTY])
   AC_REQUIRE([gl_FUNC_CHOWN])
@@ -180,7 +181,6 @@ AC_DEFUN([gl_MACROS],
   AC_REQUIRE([gl_DIACRIT])
   AC_REQUIRE([gl_TYPE_SOCKLEN_T])
   AC_REQUIRE([gl_FPRINTFTIME])
-  AC_REQUIRE([gl_CHMOD_SAFER])
   AC_REQUIRE([gl_CHDIR_SAFER])
 ])
 
Index: src/copy.c
===================================================================
RCS file: /fetish/cu/src/copy.c,v
retrieving revision 1.193
diff -p -u -r1.193 copy.c
--- src/copy.c  17 Dec 2005 10:33:33 -0000      1.193
+++ src/copy.c  2 Jan 2006 06:12:20 -0000
@@ -44,6 +44,7 @@
 #include "getpagesize.h"
 #include "hash.h"
 #include "hash-pjw.h"
+#include "lchmod.h"
 #include "quote.h"
 #include "same.h"
 #include "savedir.h"
@@ -1499,7 +1500,7 @@ copy_internal (char const *src_name, cha
              dst_mode = dst_sb.st_mode;
              restore_dst_mode = true;
 
-             if (chmod (dst_name, dst_mode | S_IRWXU))
+             if (lchmod (dst_name, dst_mode | S_IRWXU) != 0)
                {
                  error (0, errno, _("setting permissions for %s"),
                         quote (dst_name));
@@ -1740,7 +1741,7 @@ copy_internal (char const *src_name, cha
     }
   else if (restore_dst_mode)
     {
-      if (chmod (dst_name, dst_mode))
+      if (lchmod (dst_name, dst_mode) != 0)
        {
          error (0, errno, _("preserving permissions for %s"),
                 quote (dst_name));
Index: src/cp.c
===================================================================
RCS file: /fetish/cu/src/cp.c,v
retrieving revision 1.217
diff -p -u -r1.217 cp.c
--- src/cp.c    28 Dec 2005 10:22:41 -0000      1.217
+++ src/cp.c    2 Jan 2006 06:12:21 -0000
@@ -30,6 +30,7 @@
 #include "error.h"
 #include "dirname.h"
 #include "filenamecat.h"
+#include "lchmod.h"
 #include "quote.h"
 #include "quotearg.h"
 #include "stat-time.h"
@@ -335,7 +336,7 @@ re_protect (char const *const_dst_name, 
        }
       else if (p->restore_mode)
        {
-         if (chmod (dst_name, p->mode))
+         if (lchmod (dst_name, p->mode) != 0)
            {
              error (0, errno, _("failed to preserve permissions for %s"),
                     quote (dst_name));
@@ -466,7 +467,7 @@ make_dir_parents_private (char const *co
                      new->mode = stats.st_mode;
                      new->restore_mode = true;
 
-                     if (chmod (dir, stats.st_mode | S_IRWXU))
+                     if (lchmod (dir, stats.st_mode | S_IRWXU) != 0)
                        {
                          error (0, errno, _("setting permissions for %s"),
                                 quote (dir));
Index: src/mkdir.c
===================================================================
RCS file: /fetish/cu/src/mkdir.c,v
retrieving revision 1.102
diff -p -u -r1.102 mkdir.c
--- src/mkdir.c 19 Dec 2005 18:17:16 -0000      1.102
+++ src/mkdir.c 2 Jan 2006 06:12:21 -0000
@@ -23,9 +23,9 @@
 #include <sys/types.h>
 
 #include "system.h"
-#include "chmod-safer.h"
 #include "dirname.h"
 #include "error.h"
+#include "lchmod.h"
 #include "mkdir-p.h"
 #include "modechange.h"
 #include "quote.h"
@@ -65,7 +65,7 @@ Create the DIRECTORY(ies), if they do no
 Mandatory arguments to long options are mandatory for short options too.\n\
 "), stdout);
       fputs (_("\
-  -m, --mode=MODE   set permission mode (as in chmod), not rwxrwxrwx - umask\n\
+  -m, --mode=MODE   set file mode (as in chmod), not a=rwx - umask\n\
   -p, --parents     no error if existing, make parent directories as needed\n\
   -v, --verbose     print a message for each created directory\n\
 "), stdout);
@@ -80,7 +80,6 @@ int
 main (int argc, char **argv)
 {
   mode_t newmode;
-  mode_t tmp_mode;
   mode_t parent_mode IF_LINT (= 0);
   const char *specified_mode = NULL;
   const char *verbose_fmt_string = NULL;
@@ -144,11 +143,6 @@ main (int argc, char **argv)
        umask (umask_value);
     }
 
-  /* This is the mode we'll use in the mknod or mkfifo call.
-     If it doesn't include S_IRUSR, use S_IRUSR so the final
-     open-for-fchmod will succeed.  */
-  tmp_mode = (newmode & S_IRUSR) ? newmode : S_IRUSR;
-
   for (; optind < argc; ++optind)
     {
       char *dir = argv[optind];
@@ -168,7 +162,7 @@ main (int argc, char **argv)
        }
       else
        {
-         ok = (mkdir (dir, tmp_mode) == 0);
+         ok = (mkdir (dir, newmode) == 0);
 
          if (! ok)
            error (0, errno, _("cannot create directory %s"), quote (dir));
@@ -177,15 +171,13 @@ main (int argc, char **argv)
 
          /* mkdir(2) is required to honor only the file permission bits.
             In particular, it needn't do anything about `special' bits,
-            so if any were set in newmode, apply them with chmod.
-            This extra step is necessary in some cases when the containing
-            directory has a default ACL.  */
+            so if any were set in newmode, apply them with lchmod.  */
 
          /* Set the permissions only if this directory has just
             been created.  */
 
-         if (ok && specified_mode
-             && chmod_safer (dir, newmode, 0, S_IFDIR) != 0)
+         if (ok && specified_mode && (newmode & ~S_IRWXUGO)
+             && lchmod (dir, newmode) != 0)
            {
              error (0, errno, _("cannot set permissions of directory %s"),
                     quote (dir));
Index: src/mkfifo.c
===================================================================
RCS file: /fetish/cu/src/mkfifo.c,v
retrieving revision 1.79
diff -p -u -r1.79 mkfifo.c
--- src/mkfifo.c        19 Dec 2005 18:16:07 -0000      1.79
+++ src/mkfifo.c        2 Jan 2006 06:12:21 -0000
@@ -23,7 +23,6 @@
 #include <sys/types.h>
 
 #include "system.h"
-#include "chmod-safer.h"
 #include "error.h"
 #include "modechange.h"
 #include "quote.h"
@@ -62,7 +61,7 @@ Create named pipes (FIFOs) with the give
 Mandatory arguments to long options are mandatory for short options too.\n\
 "), stdout);
       fputs (_("\
-  -m, --mode=MODE   set permission mode (as in chmod), not a=rw - umask\n\
+  -m, --mode=MODE   set file permission bits to MODE, not a=rw - umask\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -76,8 +75,7 @@ int
 main (int argc, char **argv)
 {
   mode_t newmode;
-  mode_t tmp_mode;
-  const char *specified_mode;
+  char const *specified_mode = NULL;
   int exit_status = EXIT_SUCCESS;
   int optc;
 
@@ -89,8 +87,6 @@ main (int argc, char **argv)
 
   atexit (close_stdout);
 
-  specified_mode = NULL;
-
 #ifndef S_ISFIFO
   error (EXIT_FAILURE, 0, _("fifo files not supported"));
 #else
@@ -122,33 +118,17 @@ main (int argc, char **argv)
        error (EXIT_FAILURE, 0, _("invalid mode"));
       newmode = mode_adjust (newmode, change, umask (0));
       free (change);
+      if (newmode & ~S_IRWXUGO)
+       error (EXIT_FAILURE, 0,
+              _("mode must specify only file permission bits"));
     }
 
-  /* This is the mode we'll use in the mknod or mkfifo call.
-     If it doesn't include S_IRUSR, use S_IRUSR so the final
-     open-for-fchmod will succeed.  */
-  tmp_mode = (newmode & S_IRUSR) ? newmode : S_IRUSR;
-
   for (; optind < argc; ++optind)
-    {
-      int fail = mkfifo (argv[optind], tmp_mode);
-      if (fail)
+    if (mkfifo (argv[optind], newmode) != 0)
+      {
        error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
-
-      /* If the containing directory happens to have a default ACL, chmod
-        ensures the file mode permission bits are still set as desired.  */
-
-      if (fail == 0 && specified_mode)
-       {
-         fail = chmod_safer (argv[optind], newmode, 0, S_IFIFO);
-         if (fail)
-           error (0, errno, _("cannot set permissions of fifo %s"),
-                  quote (argv[optind]));
-       }
-
-      if (fail)
        exit_status = EXIT_FAILURE;
-    }
+      }
 
   exit (exit_status);
 #endif
Index: src/mknod.c
===================================================================
RCS file: /fetish/cu/src/mknod.c,v
retrieving revision 1.91
diff -p -u -r1.91 mknod.c
--- src/mknod.c 28 Dec 2005 10:22:41 -0000      1.91
+++ src/mknod.c 2 Jan 2006 06:12:21 -0000
@@ -23,7 +23,6 @@
 #include <sys/types.h>
 
 #include "system.h"
-#include "chmod-safer.h"
 #include "error.h"
 #include "modechange.h"
 #include "quote.h"
@@ -63,7 +62,7 @@ Create the special file NAME of the give
 Mandatory arguments to long options are mandatory for short options too.\n\
 "), stdout);
       fputs (_("\
-  -m, --mode=MODE   set permission mode (as in chmod), not a=rw - umask\n\
+  -m, --mode=MODE   set file permission bits to MODE, not a=rw - umask\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -89,12 +88,10 @@ int
 main (int argc, char **argv)
 {
   mode_t newmode;
-  mode_t tmp_mode;
-  const char *specified_mode;
+  char const *specified_mode = NULL;
   int optc;
   int expected_operands;
-  mode_t node_type IF_LINT (= 0);
-  dev_t device = 0;
+  mode_t node_type;
 
   initialize_main (&argc, &argv);
   program_name = argv[0];
@@ -104,8 +101,6 @@ main (int argc, char **argv)
 
   atexit (close_stdout);
 
-  specified_mode = NULL;
-
   while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
     {
       switch (optc)
@@ -128,13 +123,11 @@ main (int argc, char **argv)
        error (EXIT_FAILURE, 0, _("invalid mode"));
       newmode = mode_adjust (newmode, change, umask (0));
       free (change);
+      if (newmode & ~S_IRWXUGO)
+       error (EXIT_FAILURE, 0,
+              _("mode must specify only file permission bits"));
     }
 
-  /* This is the mode we'll use in the mknod or mkfifo call.
-     If it doesn't include S_IRUSR, use S_IRUSR so the final
-     open-for-fchmod will succeed.  */
-  tmp_mode = (newmode & S_IRUSR) ? newmode : S_IRUSR;
-
   /* If the number of arguments is 0 or 1,
      or (if it's 2 or more and the second one starts with `p'), then there
      must be exactly two operands.  Otherwise, there must be four.  */
@@ -191,6 +184,7 @@ main (int argc, char **argv)
        char const *s_major = argv[optind + 2];
        char const *s_minor = argv[optind + 3];
        uintmax_t i_major, i_minor;
+       dev_t device;
 
        if (xstrtoumax (s_major, NULL, 0, &i_major, NULL) != LONGINT_OK
            || i_major != (major_t) i_major)
@@ -208,7 +202,7 @@ main (int argc, char **argv)
          error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
 #endif
 
-       if (mknod (argv[optind], tmp_mode | node_type, device) != 0)
+       if (mknod (argv[optind], newmode | node_type, device) != 0)
          error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
       }
       break;
@@ -217,8 +211,7 @@ main (int argc, char **argv)
 #ifndef S_ISFIFO
       error (EXIT_FAILURE, 0, _("fifo files not supported"));
 #else
-      node_type = S_IFIFO;
-      if (mkfifo (argv[optind], tmp_mode))
+      if (mkfifo (argv[optind], newmode) != 0)
        error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
 #endif
       break;
@@ -228,16 +221,5 @@ main (int argc, char **argv)
       usage (EXIT_FAILURE);
     }
 
-  /* Perform an explicit chmod to ensure the file mode permission bits
-     are set as specified.  This extra step is necessary in some cases
-     when the containing directory has a default ACL.  */
-
-  if (specified_mode)
-    {
-      if (chmod_safer (argv[optind], newmode, device, node_type) != 0)
-       error (EXIT_FAILURE, errno, _("cannot set permissions of %s"),
-              quote (argv[optind]));
-    }
-
   exit (EXIT_SUCCESS);
 }
--- /dev/null   2005-09-24 22:00:15.000000000 -0700
+++ lib/lchmod.h        2006-01-01 22:06:30.000000000 -0800
@@ -0,0 +1,35 @@
+/* Provide a replacement for lchmod on hosts that lack it.
+
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Written by Paul Eggert.  */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef HAVE_LCHMOD
+
+/* The lchmod replacement follows symbolic links.  Callers should take
+   this into account; lchmod should be applied only to arguments that
+   are known to not be symbolic links.  On hosts that lack lchmod,
+   this can lead to race conditions between the check and the
+   invocation of lchmod, but we know of no workarounds that are
+   reliable in general.  You might try requesting support for lchmod
+   from your operating system supplier.  */
+
+# define lchmod chmod
+#endif
--- /dev/null   2005-09-24 22:00:15.000000000 -0700
+++ m4/lchmod.m4        2006-01-01 21:24:27.000000000 -0800
@@ -0,0 +1,15 @@
+#serial 1
+
+dnl Copyright (C) 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+dnl Provide a replacement for lchmod on hosts that lack it.
+
+AC_DEFUN([gl_FUNC_LCHMOD],
+[
+  AC_LIBSOURCES([lchmod.h])
+  AC_CHECK_FUNCS_ONCE([lchmod])
+])




reply via email to

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