Project

General

Profile

Actions

Bug #58962

open

ftruncate fails with EACCES on a read-only file created with write permissions

Added by Bruno Passeri about 1 year ago. Updated 1 day ago.

Status:
New
Priority:
Normal
Assignee:
Category:
Correctness/Safety
Target version:
% Done:

0%

Source:
Tags:
Backport:
reef,quincy,pacific
Regression:
No
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Component(FS):
ceph-fuse
Labels (FS):
Pull request ID:
Crash signature (v1):
Crash signature (v2):

Description

When creating a new file with write permissions, with mode set to read-only such as 400 or 444, ftruncate fails with EACCES. This has been a problem recently discovered, that has been around since at least August 2020. I have confirmed this with ceph-fuse, but I'm unsure if the same problem exists within the Linux Ceph kernel driver.

The snippet I used to test this behaviour:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

void print(char *verb, int perms) {
  fprintf(stdout, "%s with permissions %o: error #%d %s\n", verb, perms, errno, strerror(errno));
}

int main(int argc, char *argv[]) {
  const char *fn = "./ceph/testfile";
  const int permissions[2] = { 0666, 0444 };
  int fd;
  int i;
  for (i = 0; i < 2; i++) {
    if ((fd = open(fn, O_CREAT | O_WRONLY, permissions[i])) < 0) {
      print("Can't create", permissions[i]);
    } else {
      if (ftruncate(fd, 0) != 0) {
        print("Can't truncate", permissions[i]);
      } else {
        print("Succesfully truncated", permissions[i]);
      }
      close(fd);
      unlink(fn);
    }
  }
}

The expected output since both files are created with write permissions would be to complete successfully, but the second operation results in failure instead:

$ ./ceph-test
Succesfully truncated with permissions 666: error #0 Success
Can't truncate with permissions 444: error #13 Permission denied
Additionally, the EACCES return value is invalid as per the standards, because either we have a valid writable file descriptor, or it should return EBADF/EINVAL:

I'll also leave a link to the relevant discussion with Node/libuv where we encountered this problem, which has additional information albeit tangential: https://github.com/libuv/libuv/issues/3919

Actions

Also available in: Atom PDF