From Bugzilla Helper: User-Agent: Mozilla/4.76 [en] (X11; U; Linux 2.4.2-2 i686) Description of problem: If filea exists with permissions 444, the command $ mv fileb filea renames fiileb to filea without warning. Previous versions of RH (6.2) ask: mv: overwrite `filea', overriding mode 0444? which is the expected response in any version of Unix with which I am familiar. How reproducible: Always Steps to Reproduce: 1. Create "file1" with text "This is file 1." 2. Create "file2" with text "This is file 2." 3. chmod 444 file1 file2 4. mv file1 file2 Actual Results: $ cat file2 This is file 1. Expected Results: $ mv file1 file2 mv: overwrite 'file2', overriding mode 0444? n $ cat file2 This is file 2. Additional info:
I have tracked this down a little more, and sent a request to the bug-fileutils also, but it looks to me like it may be a GLIBC issue. I did something similar, performing the following (as non-root): touch foo1 foo2 chmod 400 foo1 foo2 mv foo1 foo2 On RH6.2, it generates the abovementioned warning. on RH7.3, it does the move blindly. Cp and Rm perform correctly (on both systems). Doing straces on both systems, yields the only apparent difference being a stat() call prior to the move (which is done using rename(2)). Looking at the sources for both versions, and building them, they both call a function called euidaccess (or something very similar, don't have the code in front of me right now), which is conditionally compiled based upon whether libc has it or not. In both versions, libc has it, so the local version is not used. Euidaccess is similar to the access(2) system call, except that it does things based upon the effective user id (because of suid programs), and the behavior apparently changed between versions of libc in RH. The code differences in MV and the fileutils code which calls it wouldn't account for the extra stat (or lack thereof), or the behavioral difference. Straces follow: ################################## ################################## ################################## ################################## Fileutils 4.0p strace: execve("/bin/mv", ["mv", "foo1", "foo2"], [/* 26 vars */]) = 0 brk(0) = 0x80531f0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40014000 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=34685, ...}) = 0 old_mmap(NULL, 34685, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000 close(3) = 0 open("/lib/libc.so.6", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0755, st_size=4101324, ...}) = 0 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\210\212"..., 4096) = 4096 old_mmap(NULL, 1001564, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x4001e000 mprotect(0x4010b000, 30812, PROT_NONE) = 0 old_mmap(0x4010b000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xec000) = 0x4010b000 old_mmap(0x4010f000, 14428, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4010f000 close(3) = 0 mprotect(0x4001e000, 970752, PROT_READ|PROT_WRITE) = 0 mprotect(0x4001e000, 970752, PROT_READ|PROT_EXEC) = 0 munmap(0x40015000, 34685) = 0 personality(PER_LINUX) = 0 getpid() = 17107 brk(0) = 0x80531f0 brk(0x8053228) = 0x8053228 brk(0x8054000) = 0x8054000 open("/usr/share/locale/locale.alias", O_RDONLY) = 3 fstat64(0x3, 0xbfffb6ac) = -1 ENOSYS (Function not implemented) fstat(3, {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000 read(3, "# Locale name alias data base.\n#"..., 4096) = 2265 read(3, "", 4096) = 0 close(3) = 0 munmap(0x40015000, 4096) = 0 open("/usr/share/i18n/locale.alias", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en_US/LC_MESSAGES", O_RDONLY) = 3 fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 close(3) = 0 open("/usr/share/locale/en_US/LC_MESSAGES/SYS_LC_MESSAGES", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=44, ...}) = 0 old_mmap(NULL, 44, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000 close(3) = 0 open("/usr/share/locale/en_US/LC_MONETARY", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=93, ...}) = 0 old_mmap(NULL, 93, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40016000 close(3) = 0 open("/usr/share/locale/en_US/LC_COLLATE", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=29970, ...}) = 0 old_mmap(NULL, 29970, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40113000 close(3) = 0 brk(0x8055000) = 0x8055000 open("/usr/share/locale/en_US/LC_TIME", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=508, ...}) = 0 old_mmap(NULL, 508, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000 close(3) = 0 open("/usr/share/locale/en_US/LC_NUMERIC", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=27, ...}) = 0 old_mmap(NULL, 27, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40018000 close(3) = 0 open("/usr/share/locale/en_US/LC_CTYPE", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=87756, ...}) = 0 old_mmap(NULL, 87756, PROT_READ, MAP_PRIVATE, 3, 0) = 0x4011b000 close(3) = 0 geteuid() = 500 umask(0) = 02 stat("foo2", {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 lstat("foo1", {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 lstat("foo2", {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 access("foo2", W_OK) = -1 EACCES (Permission denied) open("/usr/share/locale/en_US/LC_MESSAGES/fileutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/LC_MESSAGES/fileutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) write(2, "mv: overwrite `foo2\', overriding"..., 44mv: overwrite `foo2', overriding mode 0400? ) = 44 fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40019000 ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0 read(0, "\n", 1024) = 1 brk(0x8056000) = 0x8056000 _exit(1) = ? ################################## ################################## ################################## ################################## The strace for the 4.1 fileutils is the following: execve("/bin/mv", ["mv", "foo1", "foo2"], [/* 30 vars */]) = 0 uname({sys="Linux", node="dellunix.gotwisner.net", ...}) = 0 brk(0) = 0x8053a04 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=118112, ...}) = 0 old_mmap(NULL, 118112, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40014000 close(3) = 0 open("/lib/i686/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`u\1B4\0"..., 1024) = 1024 fstat64(3, {st_mode=S_IFREG|0755, st_size=1401027, ...}) = 0 old_mmap(0x42000000, 1264928, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x42000000 mprotect(0x4212c000, 36128, PROT_NONE) = 0 old_mmap(0x4212c000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12c000) = 0x4212c000 old_mmap(0x42131000, 15648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x42131000 close(3) = 0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40031000 munmap(0x40014000, 118112) = 0 brk(0) = 0x8053a04 brk(0x8053a34) = 0x8053a34 brk(0x8054000) = 0x8054000 geteuid32() = 500 umask(0) = 02 stat64("foo2", {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 brk(0x8055000) = 0x8055000 lstat64("foo1", {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 lstat64("foo2", {st_mode=S_IFREG|0400, st_size=0, ...}) = 0 rename("foo1", "foo2") = 0 _exit(0) = ?
The severity of this bug should be HI because it causes data to be lost (it removes the files that are marked as read-only)
Fixed in 4.1.9-10
Thanks for the fix. Where do I get it? I checked your updates site for both RH7.1 (which the original poster uses) and RH7.3 (which I use). I prefer source to binary. The Rawhide tree indicates fileutils-4.1.9-9.src.rpm, not 4.1.9-10. Ditto for the x386 tree.