Opened 10 years ago

Last modified 2 years ago

#230 assigned defect

chmod() fails on HPFS386 in UnixEAs mode if the file is read-only

Reported by: dmik Owned by: bird
Priority: normal Milestone:
Component: libc-backend Version: 0.6
Severity: normal Keywords: chmod hpfs386


The following test cases shows the problem:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int main()
    int fd = open("test", O_RDONLY | O_CREAT | O_EXCL,
                  S_IRUSR | S_IRGRP | S_IROTH);
    if (fd == -1)
        return 1;

    if (chmod("test", S_IRUSR | S_IRGRP | S_IROTH) == -1)
    return 0;

This does not happen on HPFS or on JFS (e.g. chmod() succeeds in this case).

Attachments (1)

chmod_HPFS386.diff (3.8 KB) - added by dmik 10 years ago.

Download all attachments as: .zip

Change History (8)

comment:1 Changed 10 years ago by dmik

Attached is a trivial fix that resets the FILE_READONLY bit before doing EAs.

Changed 10 years ago by dmik

Attachment: chmod_HPFS386.diff added

comment:2 Changed 10 years ago by bird

Component: baselayoutlibc-backend
Keywords: chmod hpfs386 added
Milestone: libc-0.6.4

Note to self: Add a hpfs386 check to the fs.c code as well.

comment:3 Changed 9 years ago by dmik

JFYI, there is a bunch of similar problems. For example, DosQueryFileInfo?(FIL_QUERYEASIZE) on a file opened with OPEN_ACCESS_WRITEONLY will also return ERROR_ACCESS_DENIED on HPFS386. The logic of the people who did that is understandable (they treat EAs as part of file data) but questionable. IMHO, EAs is the extension to the the standard attributes (DOS attributes, size, time, etc.) that can be read and modified regardless of whether the file is opened in read-only or write-only mode, and that makes more sense.

comment:4 Changed 9 years ago by bird

Status: newassigned

comment:5 Changed 6 years ago by Yuri Dario

Milestone: libc-0.6.6

comment:6 Changed 2 years ago by dmik

Note that there is also another related problem: calling DosQueryPathInfo(FIL_QUERYEASIZE) on a file which is open will fail with ERROR_SHARING_VIOLATION (32) on any file system, not only HPFS386. This breaks the following code which is perfectly valid on Linux:

int fd = open("foobar", O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0666);
// sometime later while fd is still open...
chmod("foobar", 0777);

Under kLIBC this expectedly fails with EACCESS. There is a workaround that may be applied in kLIBC: use DosQUeryFileInfo which succeeds in such a case. But in order to do so chmod needs to walk through the open file descriptor list to see if there is an open file for the given file path in the current process. Until then, the original Linux source needs to be changed to explicitly use fchmod that takes a file descriptor instead of a path as an argument (which is of course the proper way to do such a thing even on Linux since it's obviously faster).

comment:7 Changed 2 years ago by dmik

See for a real life example.

Note: See TracTickets for help on using tickets.