1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-07-26 18:48:55 +02:00

(main) Avoid a minor race condition when `-m MODE' is specified, by using

open, fchown, and close rather than just chown.  To do that reliably
(even with an overly restrictive umask), ensure that each
mknod call uses a mode including at least owner-read access.

(main): When `-m MODE' is specified, exit nonzero if
the subsequent chown (or equivalent open,fchown,close) fails.
This commit is contained in:
Jim Meyering
2005-12-19 18:18:03 +00:00
parent 52893ffd2a
commit fa6cfcb9ce
+16 -7
View File
@@ -19,10 +19,12 @@
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <getopt.h>
#include <sys/types.h>
#include "system.h"
#include "chmod-safer.h"
#include "error.h"
#include "modechange.h"
#include "quote.h"
@@ -88,10 +90,12 @@ int
main (int argc, char **argv)
{
mode_t newmode;
mode_t tmp_mode;
const char *specified_mode;
int optc;
int expected_operands;
mode_t node_type;
mode_t node_type IF_LINT (= 0);
dev_t device = 0;
initialize_main (&argc, &argv);
program_name = argv[0];
@@ -127,6 +131,11 @@ main (int argc, char **argv)
free (change);
}
/* 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. */
@@ -183,7 +192,6 @@ 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)
@@ -201,7 +209,7 @@ main (int argc, char **argv)
error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
#endif
if (mknod (argv[optind], newmode | node_type, device) != 0)
if (mknod (argv[optind], tmp_mode | node_type, device) != 0)
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
}
break;
@@ -210,7 +218,8 @@ main (int argc, char **argv)
#ifndef S_ISFIFO
error (EXIT_FAILURE, 0, _("fifo files not supported"));
#else
if (mkfifo (argv[optind], newmode))
node_type = S_IFIFO;
if (mkfifo (argv[optind], tmp_mode))
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
#endif
break;
@@ -226,9 +235,9 @@ main (int argc, char **argv)
if (specified_mode)
{
if (chmod (argv[optind], newmode))
error (0, errno, _("cannot set permissions of %s"),
quote (argv[optind]));
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);