It's all a challenge whether you have fine-grained permissions or coarse-grained permissions.
With coarse-grained permissions you end up needing proxies, which is nice because you can do whatever you want in terms of business logic, but also very much not nice because you have to write the proxies and the client code to talk to them, and then you have to keep maintaining and extending them.
Either way you have to do audits and static analysis looking for escalation vectors, and that's strictly harder -but not insurmountable- with fine-grained permissions.
So I think fine-grained permissions win.
I've implemented (and I'm trying to get approval to publish a paper on) a cross between RBAC-style and SMACK-style labeled security (where the labels are literal human-readable strings, not MLS-style bitmaps + levels) for application-level authorization, but it's very fast and should work in-kernel too if anyone wanted to make it work there. This system lets you have authorization as fine- or coarse-grained as you want by using many distinct labels (fine-grained) or few labels (coarse-grained) to label the application (or kernel) objects with.