openbsd-ports/misc/fileutils/patches/patch-src_rm_c
brad fa86cd9348 A race condition in the recursive use of 'rm' and 'mv' in fileutils 4.1 and
earlier could allow local users to delete files and directories (as the user
running fileutils) if the user has write access to part of the tree being
moved or deleted.

http://online.securityfocus.com/archive/1/260936
2003-02-25 14:35:43 +00:00

60 lines
1.9 KiB
Plaintext

$OpenBSD: patch-src_rm_c,v 1.1 2003/02/25 14:35:43 brad Exp $
--- src/rm.c.orig Sun Apr 29 02:56:24 2001
+++ src/rm.c Mon Feb 24 23:21:17 2003
@@ -1,5 +1,5 @@
/* `rm' file deletion utility for GNU.
- Copyright (C) 88, 90, 91, 1994-2001 Free Software Foundation, Inc.
+ Copyright (C) 88, 90, 91, 1994-2002 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
@@ -184,20 +184,34 @@ main (int argc, char **argv)
remove_init ();
- for (; optind < argc; optind++)
- {
- struct File_spec fs;
- enum RM_status status;
-
- /* Stripping slashes is harmless for rmdir;
- if the arg is not a directory, it will fail with ENOTDIR. */
- strip_trailing_slashes (argv[optind]);
- fspec_init_file (&fs, argv[optind]);
- status = rm (&fs, 1, &x);
- assert (VALID_STATUS (status));
- if (status == RM_ERROR)
- fail = 1;
- }
+ {
+ struct stat cwd_sb;
+ struct dev_ino cwd_dev_ino;
+
+ /* FIXME: this lstat is not always necessary -- e.g., if there are no
+ directories, or if all directories arguments are specified via
+ absolute names. */
+ if (lstat (".", &cwd_sb))
+ error (EXIT_FAILURE, errno, _("cannot lstat `.'"));
+
+ cwd_dev_ino.st_dev = cwd_sb.st_dev;
+ cwd_dev_ino.st_ino = cwd_sb.st_ino;
+
+ for (; optind < argc; optind++)
+ {
+ struct File_spec fs;
+ enum RM_status status;
+
+ /* Stripping slashes is harmless for rmdir;
+ if the arg is not a directory, it will fail with ENOTDIR. */
+ strip_trailing_slashes (argv[optind]);
+ fspec_init_file (&fs, argv[optind]);
+ status = rm (&fs, 1, &x, &cwd_dev_ino);
+ assert (VALID_STATUS (status));
+ if (status == RM_ERROR)
+ fail = 1;
+ }
+ }
remove_fini ();