Update functions should not invoke hooks however,
$permissions = user_permission_get_modules();
Quoting David Rothstein from #717834-15: The dependencies declared in core's hook_update_dependencies() implementations aren't actually correct
Reading through all the update functions, I think the biggest problem we're going to have in straightening this all out is with user_update_7006(). That function calls user_permission_get_modules() which in turn invokes hook_permission() in all enabled modules in order to try to get module-permission relationships that it can store in the database. But several hook_permission() implementations in core have dynamic permissions (node, taxonomy, etc) and therefore rely on API functions that aren't likely to work well during the update without a complicated set of dependencies in place. So basically, there's a good chance that user_update_7006() is at the heart of all our problems.
I've ignored all that for now, because user_update_7006() seems flawed anyway. People are supposed to disable contrib modules during the D6->D7 update so most hook_permission() implementations aren't ever going to be picked up by the above procedure. I think we might want to replace that update code with something totally different (e.g. code that runs on cache flushes and looks for new modules then, for example).
There's no issue open for this (the update dependencies patch is skipping trying to deal with it), so I'm opening one. Critical for two reasons:
1. Any module with dynamic permissions that is enabled while this function runs needs to be updated to the point where calling their hook_permission() implementation actually works without throwing fatal errors - this has been part of the cause of our upgrade path woes.
2. Dynamic permissions may depend on other modules that are disabled (for example modules that provide node types), so they won't get picked up by this.
3. Contrib modules are supposed to be disabled when this runs, so that won't get fixed either.
There is no way to figure this out without invoking the hooks, so I agree with David's suggestion that we look at doing this differently - for example on cron, module enable/disable or similar.