Hi,
I found a bug in truncate function, which leads to data loss.
You can easily reproduce it using the following tiny C++ example :
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <cerrno>
int main() {
int error=0;
int fd = open("trunc.tmp", O_CREAT|O_TRUNC|O_WRONLY);
if(fd<0) {
printf("open WR failed: %s\n",strerror(errno));
error++;
}
if(pwrite(fd, "1\n2\n3\n4\n5\n", 10, 0)<=0) {
printf("write failed: %s\n",strerror(errno));
error++;
}
close(fd);
fd = open("trunc.tmp", O_RDONLY);
if(fd<0) {
printf("open RD failed: %s\n",strerror(errno));
error++;
}
if(ftruncate(fd, 6)>=0) {
printf("ftruncate on the read-only fd succeeded, but should have failed !\n");
error++;
}
if(truncate("trunc.tmp", 8)<0) {
printf("truncate on the read-only opened path failed: %s\n",strerror(errno));
error++;
}
close(fd);
if(truncate("trunc.tmp", 6)<0) {
printf("truncate on the closed path failed: %s\n",strerror(errno));
error++;
}
printf("Errors : %d\n",error);
return 0;
}
This will produce the following and corrupt trunc.tmp :
truncate on the read-only opened path failed: Input/output error
truncate on the closed path failed: Input/output error
Errors : 2
Encfs will log the following :
VERBOSE op: truncate : /tmp/encfs_test/ciphertext/qQD8mBQ1SItyykZ7MCh8xLle [encfs.cpp:150]
VERBOSE streamRead(data, 10, IV) [CipherFileIO.cpp:340]
VERBOSE Called streamWrite [CipherFileIO.cpp:407]
ERROR Assert failed: canWrite [RawFileIO.cpp:216]
ERROR withFileNode: error caught in truncate: canWrite [encfs.cpp:176]
VERBOSE created FileNode for /tmp/encfs_test/ciphertext/qQD8mBQ1SItyykZ7MCh8xLle [DirNode.cpp:675]
VERBOSE op: truncate : /tmp/encfs_test/ciphertext/qQD8mBQ1SItyykZ7MCh8xLle [encfs.cpp:150]
ERROR Assert failed: fd >= 0 [RawFileIO.cpp:202]
ERROR withFileNode: error caught in truncate: fd >= 0 [encfs.cpp:176]
In other words :
ftruncate should only truncate write-opened fds.
truncate should always truncate.
Ben
Hi,
I found a bug in
truncatefunction, which leads to data loss.You can easily reproduce it using the following tiny C++ example :
This will produce the following and corrupt
trunc.tmp:Encfs will log the following :
In other words :
ftruncateshould only truncate write-opened fds.truncateshould always truncate.Ben