lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CADFqbuxiMz3Sexkqc19Pugkj8F_n+cuykFL2WEHjU9H6bPAJ4g@mail.gmail.com>
Date:	Sat, 24 Oct 2015 01:18:11 +0100
From:	Sigurd Næss <sigurdkn@...il.com>
To:	linux-kernel@...r.kernel.org
Subject: lseek(fd, 0, SEEK_CUR) returns unexpected result for O_APPEND file on
 linux 2.6.32-431.29.2

Below is a description of a simple test case that causes lseek(fd, 0,
SEEK_CUR) to return an unexpectedly small result on one of my
computers, with linux 2.6.32-431.29.2, but none of the others. I'm
posting it on the off chance that this is (or was) a kernel bug, and
not some problem on my end.

The program below creates a file containing the string
"01234", closes it, then opens it for appending, writes "a"
to it (which should be appended, creating "01234a"), truncates
it to the current position in the file (the end, and hence a no-op),
and finally writes "b", resulting in "01234ab".

This is indeed the result on most systems I've run it on, for example
$ uname -a Linux regulus.uio.no 2.6.32-573.7.1.el6.x86_64 #1 SMP Thu
Sep 10 13:42:16 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
$ gcc -o append_bug{,.c}
$ ./append_bug; cat foo.txt; echo
$01234ab

However, on one system with linux 2.6.32-431.29.2, the program gives
unexpected results because lseek returns 1 rather than the expected 6,
resulting in the output "0b".
$ uname -a Linux nekkar.uio.no 2.6.32-431.29.2.el6.x86_64 #1 SMP Sun
Jul 27 15:55:46 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
$ gcc -o append_bug{,.c}
$ ./append_bug; cat foo.txt; echo
0b

$ cat append_bug.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char ** argv)
{
int f; off_t n;
f = open("foo.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);
write(f, "01234", 5);
close(f);

f = open("foo.txt", O_WRONLY|O_APPEND);
write(f, "a", 1);
n = lseek(f, 0, SEEK_CUR);
ftruncate(f, n);
write(f, "b", 1);
close(f);
}

The version of gcc used was the rather old 4.4.7, but the compiler
version appears to be irrelevant - the executable from the
computer that exhibits the behavior does not do so when run
on e.g. my linux 2.6.32-573.7.1 computer. I reproduce the same
problem with icc. It occurs uniformly across all the 2.6.32-431.29.2
computers I have access to.

Could this be a kernel bug that was fixed between these
linux versions? If so, my google and lkml searches have not
turned up any mention of it (thought I did find patch that mentions
a marginally similar-sounding issue (https://lkml.org/lkml/2008/11/10/369).

The behavior was originally discovered when a colleague of mine
experienced that using shell redirection to append stdout of a fortran
program compiled with ifort resulted in the output file being truncated.
E.g. fortprog >> foo.txt would truncate rather than appending.
The strange write, lseek, ftruncate, write procedure used in
this program is a replica of ifort behavior, which only results in
incorrect results in the presence of this bug.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ