Right now Drupal is unusable with filesystem (POSIX) ACLs. It's been broken for years. This was previously #944582: ./sites/default/files directory permission check is incorrect during install AND status report (affects Docker on Windows) and #1333390: file_prepare_directory() / is_writable() on Linux don't support ACLs which are/were doomed to failure.

Steps to reproduce in Drupal 7 (change apache to your web server user):

  1. Build a clean Drupal 7 development environment
  2. In /sites/default:
    • mkdir files
    • chmod -R 700 files
    • setfacl -R -m user:apache:rwx files/
    • setfacl -Rd -m user:apache:rwx files/
  3. Install Drupal
  4. Do anything that calls file_prepare_directory('public://', FILE_CREATE_DIRECTORY). For instance, install the IMCE module and open its file browser from your "My Account" page.

Anything that calls file_prepare_directory('public://', FILE_CREATE_DIRECTORY) will fail, claiming that the directory (sites/default/files) is not writable.

CommentFileSizeAuthor
#88 drupal-writable-executable-fix-7.99.patch6.26 KBorlitzky
#87 drupal-writable-executable-fix-7.98.patch6.26 KBorlitzky
#86 drupal-writable-executable-fix-7.96.patch6.26 KBorlitzky
#83 drupal-writable-executable-fix-7.93.patch6.26 KBorlitzky
#82 drupal-writable-executable-fix-7.90.patch6.26 KBorlitzky
#81 drupal-writable-executable-fix-7.87.patch6.26 KBorlitzky
#80 drupal-writable-executable-fix-7.83.patch6.26 KBorlitzky
#76 drupal-writable-executable-fix-7.79.patch6.22 KBorlitzky
#75 drupal-writable-executable-fix-7.77.patch6.22 KBorlitzky
#74 drupal-writable-executable-fix-7.74.patch6.22 KBorlitzky
#71 drupal-writable-executable-fix-7.70.patch6.22 KBorlitzky
#68 drupal-writable-executable-fix-7.68.patch6.22 KBorlitzky
#67 drupal-writable-executable-fix-7.65.patch6.22 KBorlitzky
#66 drupal-writable-executable-fix-7.64.patch6.22 KBorlitzky
#64 drupal-writable-executable-fix-7.61.patch6.22 KBorlitzky
#55 drupal-writable-executable-fix-1899126-55.patch6.29 KBjstoller
#52 drupal-writable-executable-fix-7.56.patch6.29 KBorlitzky
#51 drupal-writable-executable-fix-7.55.patch6.29 KBorlitzky
#49 drupal-writable-executable-fix-7.51.patch6.28 KBorlitzky
#47 drupal-writable-executable-fix-7.50.patch6.28 KBorlitzky
#42 drupal-writable-executable-fix-7.37.patch6.28 KBorlitzky
#41 drupal-writable-executable-fix-7.36.patch6.28 KBorlitzky
#40 drupal-writable-executable-fix-7.35.patch6.28 KBorlitzky
#36 drupal-writable-executable-fix-7.33.patch6.28 KBorlitzky
#33 drupal-writable-executable-fix-7.30.patch6.28 KBorlitzky
#32 drupal-writable-executable-fix-7.29.patch6.28 KBorlitzky
#30 drupal-writable-executable-fix-7.28.patch6.27 KBorlitzky
#27 drupal-writable-executable-fix-7.25.patch6.26 KBorlitzky
#26 drupal-writable-executable-fix-7.24.patch6.29 KBorlitzky
#25 drupal-writable-executable-fix-7.23.patch5.69 KBorlitzky
#23 drupal-writable-executable-fix-7.22.patch5.69 KBorlitzky
#18 issue #1899126 (Screenshot from 2013-02-28).png318.78 KBjoates
#17 issue #1899126 (Screenshot from 2013-02-28 15:37:45).png318.78 KBjoates
#4 drupalcore-add_wrappers_to_fix_permission_checks-1899126-04.patch7.6 KBjuan.brein
drupal-writable-executable-fix-7.19.patch5.69 KBorlitzky
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

star-szr’s picture

Version: 7.x-dev » 8.x-dev
Issue tags: +Novice, +Needs manual testing, +Needs backport to D7

Thanks @mjorlitzky, at a glance this looks pretty good. This needs to be fixed in 8.x first then backported to 7.x per the backport policy.

The 8.x patch from #944582-56: ./sites/default/files directory permission check is incorrect during install AND status report (affects Docker on Windows) will need to be rerolled against 8.x minus the installer changes.

Instructions for rerolling patches.

star-szr’s picture

Issue tags: +Needs reroll

Tagging, this would still need a forward port/reroll to apply to 8.x.

joates’s picture

Assigned: Unassigned » joates
Status: Needs review » Needs work

i will reroll this patch against 8.x

juan.brein’s picture

Assigned: joates » juan.brein
Status: Needs work » Needs review
FileSize
7.6 KB

We worked on this in the Drupal Spring London with Pasive and joates. We basically took the patch provided for D7 in this issue summary and ported it to D8 up to date. Thanks to Joates to guide us through the process!

Cameron Tod’s picture

Status: Needs review » Reviewed & tested by the community

Code looks great!

Damien Tournoud’s picture

Status: Reviewed & tested by the community » Needs work

Many things look wrong in there.

First, the original post mentions that Drupal is broken when ACLs are in use, but doesn't mention why checking the execute bit (which has nothing to do with ACLs) would fix anything. Other then parsing the ACLs manually, the only way to check if you can write a file in a given directory is to try to write it, and that's what #1333390: file_prepare_directory() / is_writable() on Linux don't support ACLs actually tried to do.

Second, using drupal_realpath() without checking the return value is *really wrong*. Remote stream wrappers do not implement ->realpath(), so this is going to return FALSE.

Third, I don't see at all why this is necessary, because both is_executable() and is_writable() are basically wrappers around stat() and as a consequence they *actually work* with stream wrappers (as long as they implement ->stat()).

Finally, I doubt is_executable() on a directory returns what you expect it to return on Windows.

joates’s picture

ty for the feedback.

possible alternative to drupal_realpath() (deprecated) is discussed here..
#1201024: drupal_realpath() should describe when it should be used

[edit] in the case of a remote resource ... [/edit]
returning FALSE is certainly not useful, should probably at least test for this & log an error when it occurs.

juan.brein’s picture

Hi Damien and Joates. Thank you guys for the feedback. As far as I can tell at this point this issue should have never existed? Would you suggest another alterantive or we'll just rely on the fact that drupal does not support ACLs full stop.

Please let me know as I'm new at drupal issues so sincerely I don't know how to proceed from here.

Cheers!

Juan B

Berdir’s picture

From reading Damien's response, I think the first thing to do here is to provide detailed, reproducable steps on how to get Drupal to fail when it should work.

orlitzky’s picture

Steps to reproduce in drupal-7.20 (swap apache with your website user):

  1. Download the drupal tarball, extract it.
  2. Do whatever you need to do in settings.php
  3. In sites/default,
    1. mkdir files
    2. chmod 700 files
    3. setfacl -m user:apache:rwx files/
    4. setfacl -d -m user:apache:rwx files/
  4. Install Drupal (minimal)
  5. Download and install IMCE
  6. Open the file browser from your "My Account" page.

IMCE will fail, claiming that the directory (sites/default/files) is not writable. This is due to file_prepare_directory('public://', FILE_CREATE_DIRECTORY) failing, and is fixed by the patch which modifies file_prepare_directory().

juan.brein’s picture

Thanks, I'll try this on D8 and get back with the results here.

joates’s picture

Assigned: Unassigned » juan.brein
Priority: Normal » Major
Status: Needs review » Needs work
Issue tags: +Novice, +Needs reroll

in response to #10 Posted by mjorlitzky..

it would be more constructive if we can all agree that this is an 8.x issue now,
there is no 8.x release of IMCE

Revised guidelines to re-create the bug:

  1. build a clean Drupal 8 development environment
  2. In sites/default,
    • chown -R nobody files
    • chmod -R 700 files
    • setfacl -R -m user:apache:rwx files/
    • setfacl -Rd -m user:apache:rwx files/
  3. Install Drupal 8
  4. Add a new Article (uploading an image should fail).

Notes:

  • change apache in step 2. for the username of your httpd server.
  • step 4. needs to be confirmed or an alternative method proposed.

[edit]
// 28-Feb-2013
Modified the instructions to implement full excluded file access to the entire files/ sub-tree (user = nobody)
and added recursive ACL permissions as Drupal needs to store file uploads in several sub-folder locations.
[/edit]

orlitzky’s picture

You don't really need IMCE to reproduce the issue in 8.x (if it exists). Just call file_prepare_directory('public://', FILE_CREATE_DIRECTORY) somewhere and see if it works. IMCE is just the reason why this is a complete show-stopper for us.

Damien Tournoud’s picture

Ok, I see what's happening. PHP has a special case for local files in which it uses access(2) or the equivalent Windows call. This supports ACLs. If called on a stream-wrapper, it defaults to a (very complicated) process based on the stat(2) structure returned by the stream-wrapper implementation.

More precisely it checks part of the .mode structure depending on:

  • If the current user (as returned by getuid(2)) is the same as the .uid in the stat, it uses the "user" part of the mode;
  • If current group (as returned by getgid(2)) or the supplementary groups (as returned by getgroups(2) is the same as the .gid in the stat, it uses the "group" part of the mode;
  • Else, it falls back to the "others" part of the mode.

So, one way of moving forward here, would be to modify the stat implementation in our local streamwrapper to fake the mode by calling is_readable(), is_writable() and is_executable() manually, and return the proper structure.

clemens.tolboom’s picture

joates’s picture

Status: Needs review » Needs work

Re #14: thanks Damien for locating what seems to be the root cause of this..

  • removing Novice tag
  • priority normal seems more appropriate
  • need a patch to "modify the stat implementation in our local streamwrapper" ?

from core/lib/Drupal/Core/StreamWrapper/LocalStream.php, line 472

<?php
public function url_stat($uri, $flags) {
  $this->uri = $uri;
  $path = $this->getLocalPath();
  // Suppress warnings if requested or if the file or directory does not
  // exist. This is consistent with PHP's plain filesystem stream wrapper.
  if ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) {
    return @stat($path);
  }
  else {
    return stat($path);
  }
}
?>
joates’s picture

Assigned: juan.brein » Unassigned
Priority: Major » Normal
Status: Needs work » Needs review
Issue tags: -Novice, -Needs reroll
FileSize
318.78 KB

in response to #9 and #12..

after setting chmod 700 files
you can clearly see from the terminal that my normal user (joates) is group member but cannot gain access.
getfacl shows the ACL permissions (as described in #12)
(screenshot attachment not working?)

on a fresh install of D8 using default configuration (public:// streamwrapper) i am able to upload an image without error.

joates’s picture

Status: Needs work » Needs review
FileSize
318.78 KB

try again with the screenshot..

link: http://i.imgur.com/G0s2i99.png

afterwards i realised that having www-data as the directory owner is not too helpful :-p

so i did a chown -R joates:joates files cleared cache and tried again to upload the image, and it did indeed FAIL to upload the file
(which sort of feels like causing it to fail when it *should* fail, but maybe i don't understand ACLs correctly -- does setfacl in the top folder apply to every child ?)
Update: even with recursive ACL the file upload still fails.

link: http://i.imgur.com/FesrnJV.png

joates’s picture

can someone with superior ACL sysadmin skills to me please confirm that it seems that Drupal is not providing support for ACLs ?
(perhaps due to the situation Damien describes in #14)

and maybe change the title of this issue if that is the case :)

star-szr’s picture

Assigned: juan.brein » Unassigned
Priority: Major » Normal
Status: Needs work » Needs review
Issue tags: -Novice, -Needs reroll

@joates - Thanks for all your work on this issue. Could you please update the issue summary with the steps to reproduce, that way others can update them too and you don't have to keep editing your comments :)

joates’s picture

Issue summary: View changes

Updated issue summary.

joates’s picture

ok

orlitzky’s picture

The current steps to reproduce probably won't work I'm afraid. Uploading files—in and of itself—has always worked. The filesystem ACLs do really allow you to write the file, so if you try to do it, it will work.

The problem is when Drupal does its heuristic to determine, "will I be able to write this file if the user tries to do it?" That test is currently broken, so the answer is "no" even though it should be "yes" (thanks to the ACL).

orlitzky’s picture

Updated patch for 7.22.

Status: Needs review » Needs work

The last submitted patch, drupal-writable-executable-fix-7.22.patch, failed testing.

orlitzky’s picture

Updated patch for 7.23.

orlitzky’s picture

Issue summary: View changes

Updated issue summary.

orlitzky’s picture

Updated patch for 7.24.

orlitzky’s picture

Updated patch for 7.25.

orlitzky’s picture

The patch for 7.25 applies cleanly to 7.26.

orlitzky’s picture

And to 7.27.

orlitzky’s picture

YesCT’s picture

Issue summary: View changes
orlitzky’s picture

orlitzky’s picture

gold.eagle’s picture

mjorlitzky: Just wanted to say "Thank you". We download this patch regularly, whenever we update Core.

orlitzky’s picture

gold.eagle: glad someone else is making use of it!

orlitzky’s picture

YesCT’s picture

Version: 8.0.x-dev » 7.x-dev

to run the tests ... change the version. (you can change it back)

YesCT’s picture

Status: Needs work » Needs review
YesCT’s picture

Version: 7.x-dev » 8.0.x-dev
Status: Needs review » Needs work

back to 8.0.x which needs a patch to work on that.

orlitzky’s picture

orlitzky’s picture

orlitzky’s picture

dooug’s picture

RTBC++

This patch worked for me against the latest 7.38. It solved the problem I reported here: #2509188: The directory public://pictures does not exist or is not writable.

Is this ticket a backport of the mess in this ticket: #944582: ./sites/default/files directory permission check is incorrect during install AND status report (affects Docker on Windows)?

orlitzky’s picture

It's not a backport, just a cleanup. The patches on that issue tried to solve two problems at once, and people were arguing about the half that I don't care about. So, I split off the part that fixes the permission checks and posted the patch here.

But then someone told me I had to fix it in drupal-8.x before we could apply the patch to drupal-7.x where it's actually broken. And this was back when drupal-8.x was completely broken and couldn't be installed. Then the issue got updated with an incorrect description, and incorrect steps to reproduce. I don't have time to deal with that -- I'm just going to keep updating the patch for drupal-7.x for the rest of my life.

dooug’s picture

Well, Thank you, @orlitzky! Thanks for the quick response and providing a solution amidst that chaotic ticket. And thank you in advance for your life-long service of re-rolling this patch ;)

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

orlitzky’s picture

FileSize
6.28 KB

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

orlitzky’s picture

FileSize
6.29 KB
orlitzky’s picture

jstoller’s picture

Given that no one has successfully reproduced this in Drupal 8 in the last four-and-a-half years, or indicated that it is still a problem in that version, I'm going to go out on a limb and bump this back down to Drupal 7. I've updated the issue description to reflect that.

Personally, I've experienced these errors on my local dev environment and the patch fixes it.

@orlitzky keep fighting the good fight! :-)

Status: Needs review » Needs work

The last submitted patch, 52: drupal-writable-executable-fix-7.56.patch, failed testing. View results

jstoller’s picture

Status: Needs work » Needs review
FileSize
6.29 KB

Re-uploading @orlitzky's patch from #52, so it'll test with the correct version of Drupal.

jstoller’s picture

Status: Needs review » Reviewed & tested by the community

That's better! Since this has been thoroughly tested by multiple people for several years now, I'm marking it RTBC.

David_Rothstein’s picture

Version: 7.x-dev » 8.4.x-dev
Status: Reviewed & tested by the community » Needs review
Issue tags: +Needs backport to D7

This almost certainly does affect Drupal 8, since the code in https://api.drupal.org/api/drupal/includes%21file.inc/function/file_prep... and https://api.drupal.org/api/drupal/core%21includes%21file.inc/function/fi... (as well as other places that call is_writable()/is_executable()) is virtually the same. If this isn't an issue in Drupal 8, someone would need to explain specifically why.

I also don't understand why this was split off from #944582: ./sites/default/files directory permission check is incorrect during install AND status report (affects Docker on Windows). Comparing the patches in the two issues, they are almost exactly the same - the primary difference is that the other issue changes the writable/executable checks to use the new system in more places than this one does. I do not understand the rationale for fixing this in only some places but not others, and especially don't see why there should be two open issues that are duplicating each other's work. So I think this could be closed as a duplicate of the issue. (Or alternatively, it could be repurposed as the Drupal 7 backport of that issue, and postponed on getting it fixed in Drupal 8 first.)

orlitzky’s picture

This is a seven-year-old "Drupal doesn't work at all" bug -- if you think closing it as a duplicate of another *unfixed* bug will help, then go for it. I'll keep posting patches until I don't have to any more.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ramzypro’s picture

Verified that the patch for 5.6 still works with 5.7.

The difference between this ticket and the other is that this one regularly has patches that keep our site up and running. Myself and my colleagues (who run on AFS servers using ACLs) RELY on orlitzky's patches to keep our sites up and running. The other thread seems so caught up with posts that do not understand the issue, and patches that do nothing. Someone running with an ACL-enabled system needs to be actively involved in constructing solutions to this problem.

Also - thank you orlitzky for your tireless efforts, we would be writing our own patches every Drupal release if not for your work.

orlitzky’s picture

It really hasn't been that much work, but I appreciate the shout-out. I think I'm in the same boat as everyone else. We use ACLs on our web servers, and without this patch, file uploads simply don't work. This patch fixes it and has been tested on hundreds of sites, for how many years now? I'm not even sure what problem is being fixed on the other ticket these days.

slydevil’s picture

Version: 8.5.x-dev » 7.x-dev
Murz’s picture

Thanks, provided patch solves the problem with file permission check in Drupal. So will this patch be applied to Drupal 8.x core? Can anybody else review it and provide for applying?

orlitzky’s picture

ramzypro’s picture

It appears that the patch for 7.61 no longer applies for 7.63. Any chance this will be updated soon? Appreciated!

EDIT: The patch for 7.61 does work!

orlitzky’s picture

orlitzky’s picture

orlitzky’s picture

magapov’s picture

I am so happy to find the patch for 7.68, it also works for 7.69 flawlessly. I think we need to buy @orlitzky coffee and cake.

jstoller’s picture

Status: Needs review » Reviewed & tested by the community

Let’s try this one more time. Marking RTBC.

orlitzky’s picture

jstoller’s picture

@orlitzky your previous patch still applied for me. Are there any changes in this one that I should be aware of?

orlitzky’s picture

Nothing important, I just rebased the patch to apply cleanly without unexpected offsets or fuzz. When the patch applies but not cleanly, it leaves around backups in the form of .orig files that you don't want.

orlitzky’s picture

orlitzky’s picture

orlitzky’s picture

izmeez’s picture

This was added to #3192080: [meta] Priorities for 2021-04-07 release of Drupal 7 that will be copied into the meta issue for the next release. Not sure if it will help moving toward a commit.

Fabianx’s picture

Title: Add wrappers to fix permission checks » [D7] Add wrappers to fix permission checks
Status: Reviewed & tested by the community » Postponed
Issue tags: -Needs backport to D7

Unfortunately per the backport-policy, this needs to go into D9 first:

See: https://www.drupal.org/project/drupal/issues/944582

And the patch there is identical to this one.

izmeez’s picture

This is an example of when the policy makes no sense. As the D9 issue summary says:

This can cause various hard-to-troubleshoot permission-related errors with the files directory, including on Docker environments.

So, why let it persist for the over 160,000 D7 sites?

Anyway, the patch is here for those that want to use it. Hopefully, it will remain on the priority list for the future when D9 catches up.

orlitzky’s picture

orlitzky’s picture

FileSize
6.26 KB
orlitzky’s picture

orlitzky’s picture

poker10’s picture

@orlitzky Thanks for the reroll, but I think that it was not needed, because the patch in #82 still applies. It would be best to concentrate our efforts on the D10 patch so that we can get back to this.

orlitzky’s picture

@poker10 the reason I reroll them is because, with GNU patch at least, any unexpected offsets or "fuzz" will leave *.orig files laying around in your public drupal directory. It's sloppy, but more importantly, if you're using diff/patch to update drupal, runs the risk of accidentally copying those *.orig files into all of your sites.

Finally, if there's a little but of fuzz between version A and version B, the patch will still apply. But if there's also fuzz between version B and C, the patch for version A will stop working. By constantly updating the patch, I ensure that there's always a minimal amount of fuzz so that I can at least apply the thing with patch instead of having to re-edit the source files manually. In other words, the only reason the latest patch still applies is because I "pointlessly" rerolled earlier ones :)

orlitzky’s picture

FileSize
6.26 KB
orlitzky’s picture

FileSize
6.26 KB
orlitzky’s picture

FileSize
6.26 KB