palainp / mirage-sshfs

ISC License
21 stars 1 forks source link

Writes in the middle of files #5

Closed palainp closed 2 years ago

palainp commented 3 years ago

With a mounted disk.img I encountered a problem when I needed to write to the middle of files. For example, the second echo command is supposed to erase the entire file and does not:

$ echo 1234567890 > test.txt
$ echo -n KO > test.txt && cat test.txt 
KO34567890

The two echo commands send SSH_FXP_OPEN then SSH_FXP_LSTAT then SSH_FXP_WRITE then SSH_FXP_CLOSE. As far as I think I can't tell the difference (from the server side) if the user's intention is to delete the file with a shell redirect or if the user just wants to update some bytes like with this program:

#include <stdio.h>
#include <assert.h>
#include <string.h>

int main()
{
    char* str = "KO";
    size_t l = strlen(str);
    FILE* fd = fopen("test.txt", "w+");

    assert(fd != NULL);
    //assert(fseek(fd, 3, SEEK_SET) != -1); // with this active we can see a SSH_FXP_READ before the WRITE
    assert(fwrite(str, sizeof(char), l, fd) == l);
    assert(fflush(fd) == 0);
    assert(fclose(fd) == 0);

    return 0;
}
palainp commented 3 years ago

There is in fact a sligh difference, my do a LSTAT before openning the file, not sure if this will be done with any shells. This trace correspond to echo -n KO > test.txt:

2021-11-02 16:30:23 +01:00: DBG [sshfs_protocol] [SSH_FXP_LSTAT 12] for '/test.txt'
2021-11-02 16:30:23 +01:00: DBG [sshfs_protocol] [SSH_FXP_OPEN 13] for '/test.txt' attrs=4
2021-11-02 16:30:23 +01:00: DBG [sshfs_protocol] [SSH_FXP_LSTAT 14] for '/test.txt'
2021-11-02 16:30:23 +01:00: DBG [sshfs_protocol] [SSH_FXP_WRITE 15] '/test.txt' @0 (2)
2021-11-02 16:30:23 +01:00: DBG [sshfs_protocol] [SSH_FXP_CLOSE 16] for /test.txt
2021-11-02 16:30:23 +01:00: DBG [sshfs_protocol] [SSH_FXP_LSTAT 17] for '/'

This one to cat test.txt:

2021-11-02 16:30:57 +01:00: DBG [sshfs_protocol] [SSH_FXP_LSTAT 18] for '/test.txt'
2021-11-02 16:30:57 +01:00: DBG [sshfs_protocol] [SSH_FXP_OPEN 19] for '/test.txt' attrs=4
2021-11-02 16:30:57 +01:00: DBG [sshfs_protocol] [SSH_FXP_LSTAT 20] for '/test.txt'
2021-11-02 16:30:57 +01:00: DBG [sshfs_protocol] [SSH_FXP_READ 21] for '/test.txt' @0 (4096)
2021-11-02 16:30:57 +01:00: DBG [sshfs_protocol] [SSH_FXP_CLOSE 22] for /test.txt
2021-11-02 16:30:57 +01:00: DBG [sshfs_protocol] [SSH_FXP_LSTAT 23] for '/'

And finaly ./testw (which is the result of the compilation of the C program):

2021-11-02 16:31:08 +01:00: DBG [sshfs_protocol] [SSH_FXP_OPEN 29] for '/test.txt' attrs=4
2021-11-02 16:31:08 +01:00: DBG [sshfs_protocol] [SSH_FXP_LSTAT 30] for '/test.txt'
2021-11-02 16:31:08 +01:00: DBG [sshfs_protocol] [SSH_FXP_WRITE 31] '/test.txt' @0 (2)
2021-11-02 16:31:08 +01:00: DBG [sshfs_protocol] [SSH_FXP_CLOSE 32] for /test.txt
palainp commented 2 years ago

Update: I was wrongly using attrs instead of pflags. The issue is solved :shame: