2

My java-based installer couldn't copy itself to target dir eating all disk space and I thought it was a java bug, but then I reproduced it with plain dd.

When I try to read my own executable using a large enough buffer (131072), the read operation suddenly returns value greater than the actual file size and never returns EOF:

DD=/media/distr/dd
(
/bin/cp /bin/dd $DD
$DD bs=131071 if=$DD of=/dev/null count=20
$DD bs=131072 if=$DD of=/dev/null count=20
)
0+1 records in
0+1 records out
55256 bytes (55 kB) copied, 0.00211071 s, 26.2 MB/s
20+0 records in
20+0 records out
2621440 bytes (2.6 MB) copied, 0.0194318 s, 135 MB/s

It only happens when both samba server and cifs mount run on Oracle Linux 6.6 with samba 3.6.23-12.0.1.el6.

What is it? A kernel, cifs or samba bug?

strace of dd:

[root@ec-stage-db-2 ~]# strace $DD bs=131072 if=$DD of=/dev/null count=20
execve("/mnt/dd", ["/mnt/dd", "bs=131072", "if=/mnt/dd", "of=/dev/null", "count=20"], [/* 32 vars */]) = 0
brk(0)                                  = 0x13e8000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172ee000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=79239, ...}) = 0
mmap(NULL, 79239, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcc172da000
close(3)                                = 0
open("/lib64/librt.so.1", O_RDONLY)     = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@!\3002=\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=47104, ...}) = 0
mmap(0x3d32c00000, 2128816, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3d32c00000
mprotect(0x3d32c07000, 2093056, PROT_NONE) = 0
mmap(0x3d32e06000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x3d32e06000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\356\3011=\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1926760, ...}) = 0
mmap(0x3d31c00000, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3d31c00000
mprotect(0x3d31d8a000, 2097152, PROT_NONE) = 0
mmap(0x3d31f8a000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18a000) = 0x3d31f8a000
mmap(0x3d31f8f000, 18696, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3d31f8f000
close(3)                                = 0
open("/lib64/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340]\0002=\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=145896, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172d9000
mmap(0x3d32000000, 2212848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3d32000000
mprotect(0x3d32017000, 2097152, PROT_NONE) = 0
mmap(0x3d32217000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x3d32217000
mmap(0x3d32219000, 13296, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3d32219000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172d8000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172d7000
arch_prctl(ARCH_SET_FS, 0x7fcc172d8700) = 0
mprotect(0x3d32e06000, 4096, PROT_READ) = 0
mprotect(0x3d31f8a000, 16384, PROT_READ) = 0
mprotect(0x3d32217000, 4096, PROT_READ) = 0
mprotect(0x3d3161f000, 4096, PROT_READ) = 0
munmap(0x7fcc172da000, 79239)           = 0
set_tid_address(0x7fcc172d89d0)         = 39608
set_robust_list(0x7fcc172d89e0, 0x18)   = 0
futex(0x7fffa32a778c, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7fffa32a778c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7fcc172d8700) = -1 EAGAIN (Resource temporarily unavailable)
rt_sigaction(SIGRTMIN, {0x3d32005c60, [], SA_RESTORER|SA_SIGINFO, 0x3d3200f710}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x3d32005cf0, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x3d3200f710}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
rt_sigaction(SIGUSR1, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGUSR1, {0x401be0, [INT USR1], SA_RESTORER, 0x3d31c326a0}, NULL, 8) = 0
rt_sigaction(SIGINT, {0x401bd0, [INT USR1], SA_RESTORER|SA_NODEFER|SA_RESETHAND, 0x3d31c326a0}, NULL, 8) = 0
brk(0)                                  = 0x13e8000
brk(0x1409000)                          = 0x1409000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=99158576, ...}) = 0
mmap(NULL, 99158576, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcc11446000
close(3)                                = 0
open("/mnt/dd", O_RDONLY)               = 3
dup2(3, 0)                              = 0
close(3)                                = 0
lseek(0, 0, SEEK_CUR)                   = 0
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
dup2(3, 1)                              = 1
close(3)                                = 0
mmap(NULL, 143360, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc11423000
read(0, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0\340\32@\0\0\0\0\0"..., 131072) = 131072
write(1, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0\340\32@\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
close(0)                                = 0
close(1)                                = 0
open("/usr/share/locale/locale.alias", O_RDONLY) = 0
fstat(0, {st_mode=S_IFREG|0644, st_size=2512, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcc172ed000
read(0, "# Locale name alias data base.\n#"..., 4096) = 2512
read(0, "", 4096)                       = 0
close(0)                                = 0
munmap(0x7fcc172ed000, 4096)            = 0
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = 0
fstat(0, {st_mode=S_IFREG|0644, st_size=435, ...}) = 0
mmap(NULL, 435, PROT_READ, MAP_PRIVATE, 0, 0) = 0x7fcc172ed000
close(0)                                = 0
write(2, "20+0 records in\n20+0 records out"..., 3320+0 records in
20+0 records out
) = 33
write(2, "2621440 bytes (2.6 MB) copied", 292621440 bytes (2.6 MB) copied) = 29
write(2, ", 0.0245485 s, 107 MB/s\n", 24, 0.0245485 s, 107 MB/s
) = 24
close(2)                                = 0
exit_group(0)                           = ?
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
basin
  • 2,051

2 Answers2

0

Assuming you couldn't reproduce this problem with another file system on the same machine, it has to be a samba bug.

Whether it's a client or a server problem is a bit of a moot point, but I would guess that it has to do with the same file being mapped for execution and opened for reading, which is probably handled incorrectly, because read call should not return anything beyond eof. Wrong file metadata (i.e. size) may also cause such behavior.

mkalkov
  • 157
0

Complete test script. I can't report the bug, because I'd have to pay for that.

#!/bin/bash

set -e

# systemd
#SMB_START="systemctl start smbd.service nmbd.service"
#SMB_RELOAD="systemctl reload smbd.service"

# initscripts
SMB_START="service smb start"
SMB_RELOAD="service smb reload"

cleanup() {
echo cleanup... >&2
sed -i -n -e "/# added by test-samba-bug BEGIN/b m10; p; b" -e :m10 -e n -e "/# added by test-samba-bug END/b" -e "b m10" /etc/samba/smb.conf
umount -f /tmp/test-samba-bug-mnt 2>/dev/null || true
rm -rf /tmp/test-samba-bug /tmp/test-samba-bug-mnt
}

cleanup

trap cleanup EXIT

mkdir -p /tmp/test-samba-bug /tmp/test-samba-bug-mnt
chcon -R -t samba_share_t /tmp/test-samba-bug 2>/dev/null || true

>>/etc/samba/smb.conf cat <<EOF
# added by test-samba-bug BEGIN
[test-samba-bug]
        path = /tmp/test-samba-bug
        public = yes
# added by test-samba-bug END
EOF

# service smb stop
$SMB_START
$SMB_RELOAD

mount -t cifs -oguest //localhost/test-samba-bug /tmp/test-samba-bug-mnt

command cp /bin/dd /tmp/test-samba-bug/

DD=/tmp/test-samba-bug-mnt/dd

#$DD bs=131071 if=$DD of=/dev/null count=20
$DD bs=131072 if=$DD of=/tmp/test-samba-bug/copied count=20

echo comparing copied file contents
cmp /bin/dd /tmp/test-samba-bug/copied || {
echo "test failed" >&2
exit 1
}
basin
  • 2,051