Skip to content

Instantly share code, notes, and snippets.

@thomas-holmes
Last active October 4, 2019 20:55
Show Gist options
  • Save thomas-holmes/711bcdb28e2b8e6d1c39c1d99d292af7 to your computer and use it in GitHub Desktop.
Save thomas-holmes/711bcdb28e2b8e6d1c39c1d99d292af7 to your computer and use it in GitHub Desktop.

To reproduce this bug the file must be in an OverlayFS mount. The following steps will create one and then demonstrate the bug.

On a host using linux-aws 4.4.0-1054 run the following reproduction steps:

Install packages libacl1-dev, build-essential, and gcc.

Included is a C program that reproduces the bug and two scripts. Run them in order.

  • make-overlay.sh: creates directories in /tmp and mounts /tmp/overlay as an overlay filesystem
  • test.sh: compiles the c program and executes it. additionally attempts to read the file and checks its permissions after the program exits.
#include <acl/libacl.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/acl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void) {
int ret;
int fd = open("/tmp/overlay/animal", O_RDWR|O_CREAT|O_EXCL, 0000);
if (fd < 0) {
printf("open failed\n");
return 1;
}
acl_t acl = acl_from_mode(0644);
if (acl == NULL) {
printf("acl_from_mode failed\n");
return 1;
}
ret = acl_set_fd(fd, acl);
if (ret < 0) {
printf("acl_set_fd failed");
return 1;
}
// It works, apparently. But not really.
struct stat st;
if (fstat(fd, &st) < 0) {
printf("fstat failed\n");
return 1;
}
// reports 100644
printf("st_mode is %o\n", st.st_mode);
ret = close(fd);
if (ret < 0) {
printf("close failed\n");
return 1;
}
// fails to open
fd = open("/tmp/overlay/animal", O_RDONLY);
if (fd < 0) {
printf("open failed: %d\n", fd);
return 1;
}
}
#!/usr/bin/env bash
# setup directories for our overlay filesystem
mkdir /tmp/lower /tmp/upper /tmp/overlay /tmp/workdir
# mount the overlay filesystem
sudo mount -t overlay -o lowerdir=/tmp/lower,upperdir=/tmp/upper,workdir=/tmp/workdir none /tmp/overlay
#!/usr/bin/env bash
# compile the test program, run it, and try to inspect the files afterwards
gcc -Wl,--no-as-needed -lacl -o boom boom.c && rm -f /tmp/overlay/animal && ./boom; { cat /tmp/overlay/animal; ls -al /tmp/overlay/animal; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment