Okay, so it turns out that:
(1) the man pages don't say this, but we do in fact need write permission to set xattr on a file, implying that we probably shouldn't keep translating READONLY to Unix permission bits,
(2) FILE_WRITE_ATTRIBUTES applies to FILE_SUPERSEDE but not FILE_OVERWRITE_IF, making that weird corner case work. This isn't really correct, though: as the tests show, both FILE_SUPERSEDE and FILE_OVERWRITE_IF are supposed to replace the file's attributes (contradicting the comment in server/file.c). The actual difference is apparently that FILE_OVERWRITE_IF will respect READONLY, but FILE_SUPERSEDE won't. (But on the other hand, trying to open a read-only file with FILE_SUPERSEDE and GENERIC_WRITE still fails???)
The thing is that those tests really are a corner case. By making that change we're only breaking the case where we're opening with FILE_SUPERSEDE but not FILE_WRITE_DATA, which is doubly rare because
(1) kernelbase doesn't even translate anything to FILE_SUPERSEDE, only FILE_OVERWRITE(_IF);
(2) it seems quite unlikely that an application would open a file to truncate it without also opening it for write access.
In light of that I'd propose we use logic that makes sense in the server rather than worry about that test, and hence do one of two things:
(a) require write access for O_TRUNC, but don't require it for FILE_WRITE_ATTRIBUTES—basically the same thing that this patch series already does, but with the aforementioned suggestion. Mark tests 16 and 17 as todo, because they don't really matter. This isn't really correct, because writing attributes *does* require POSIX write access, but I don't think it risks regressions—it just means we return success for opening files where we otherwise couldn't, and then we'll still return failure from NtSetAttributesFile() et al.
(b) Stop stripping POSIX write access from files with READONLY. Rely on xattr to store that. (Or perhaps, stop stripping POSIX write access *if* we can store with xattr.) This is more correct in general, although it's an open question whether the difference will ever actually matter. It arguably loses something in terms of host integration, although I also wonder whether that matters. I feel like there was a discussion about this earlier, but I've forgotten what or where it was...