Bug 220358

Summary: [macOS] Reset user directory suffix before getting sandbox directory
Product: WebKit Reporter: Per Arne Vollan <pvollan>
Component: WebKit Misc.Assignee: Per Arne Vollan <pvollan>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, bfulgham, commit-queue, ddkilzer, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=222233
Bug Depends on: 220487    
Bug Blocks:    
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

Description Per Arne Vollan 2021-01-06 04:50:33 PST
Reset user directory suffix before getting sandbox data vault directory. We do not want to include the user directory suffix, since the compiled sandbox should be shared by all WebKit processes of the same type. Also, creating the data vault directory can fail under some circumstances if the user directory suffix is not empty.
Comment 1 Per Arne Vollan 2021-01-06 04:51:00 PST
<rdar://problem/57616019>
Comment 2 Per Arne Vollan 2021-01-06 05:00:35 PST
Created attachment 417079 [details]
Patch
Comment 3 Alexey Proskuryakov 2021-01-06 09:36:45 PST
Comment on attachment 417079 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=417079&action=review

> Source/WebKit/ChangeLog:11
> +        Reset user directory suffix before getting sandbox data vault directory. We do not want to include the user directory suffix,
> +        since the compiled sandbox should be shared by all WebKit processes of the same type. Also, creating the data vault directory
> +        can fail under some circumstances if the user directory suffix is not empty.

I do not understand what "all WebKit processes of the same type" means. Surely WebKit processes for different applications have different sandbox profiles?

Also, I do not see how this can help <rdar://problem/57616019>, which is about trying to use an incorrect cache directory path, with a '/' instead of a '+'. How do we end up trying to use the slash?
Comment 4 Per Arne Vollan 2021-01-06 11:16:28 PST
(In reply to Alexey Proskuryakov from comment #3)
> Comment on attachment 417079 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=417079&action=review
> 
> > Source/WebKit/ChangeLog:11
> > +        Reset user directory suffix before getting sandbox data vault directory. We do not want to include the user directory suffix,
> > +        since the compiled sandbox should be shared by all WebKit processes of the same type. Also, creating the data vault directory
> > +        can fail under some circumstances if the user directory suffix is not empty.
> 
> I do not understand what "all WebKit processes of the same type" means.
> Surely WebKit processes for different applications have different sandbox
> profiles?
> 

The different WebKit process types I am thinking of is GPU, WebContent, and Networking. I believe each WebKit process type can share the same cached sandbox profile, which this patch ensures by having each type store their profile at the same location. This should be a performance optimization.

> Also, I do not see how this can help <rdar://problem/57616019>, which is
> about trying to use an incorrect cache directory path, with a '/' instead of
> a '+'. How do we end up trying to use the slash?

I believe we end up trying to use the slash, because the slash is present in the user directory suffix. This patch fixes this and the crash by resetting the suffix, making sure confstr returns the expected result.

Thanks for reviewing!
Comment 5 Alexey Proskuryakov 2021-01-06 17:37:40 PST
> I believe each WebKit process type can share the same cached sandbox profile, which this patch ensures by having each type store their profile at the same location.

This cannot work today because they all have different variables applied when compiling. Are you talking about a future goal?

> I believe we end up trying to use the slash, because the slash is present in the user directory suffix. This patch fixes this and the crash by resetting the suffix, making sure confstr returns the expected result.

Where does the unusual suffix come from? The crash happens in Networking process, so I don't understand what could possibly set it. Also, the suffix for networking process always has a '+' in it, which I don't see in the crash log. This is very mysterious.
Comment 6 Per Arne Vollan 2021-01-07 00:19:47 PST
(In reply to Alexey Proskuryakov from comment #5)
> > I believe each WebKit process type can share the same cached sandbox profile, which this patch ensures by having each type store their profile at the same location.
> 
> This cannot work today because they all have different variables applied
> when compiling. Are you talking about a future goal?
> 

That is a good point. Can the sandbox parameters be different for different apps hosting WebKit, though? Is there any way the embedding application can have any influence on the sandbox parameters? If not, I think we should be able to share the cached sandboxes between various embedding apps.

> > I believe we end up trying to use the slash, because the slash is present in the user directory suffix. This patch fixes this and the crash by resetting the suffix, making sure confstr returns the expected result.
> 
> Where does the unusual suffix come from? The crash happens in Networking
> process, so I don't understand what could possibly set it. Also, the suffix
> for networking process always has a '+' in it, which I don't see in the
> crash log. This is very mysterious.

Yes, this is very strange. I am currently looking into why we see the unusual user directory suffix.

Thanks for reviewing!
Comment 7 Alexey Proskuryakov 2021-01-07 09:29:42 PST
> Can the sandbox parameters be different for different
> apps hosting WebKit, though? 

They are expected to be different, e.g. each one has its own DARWIN_USER_CACHE_DIR; ENABLE_SANDBOX_MESSAGE_FILTER can be on or off.

> Is there any way the embedding application can
> have any influence on the sandbox parameters?

The bundle ID of the embedding application definitely does. It is OK for it to have other kinds of influence as long as we understand that the input can be malicious, and handle it defensively before enabling the sandbox.
Comment 8 Per Arne Vollan 2021-01-07 11:29:53 PST
(In reply to Alexey Proskuryakov from comment #7)
> > Can the sandbox parameters be different for different
> > apps hosting WebKit, though? 
> 
> They are expected to be different, e.g. each one has its own
> DARWIN_USER_CACHE_DIR; ENABLE_SANDBOX_MESSAGE_FILTER can be on or off.
> 
> > Is there any way the embedding application can
> > have any influence on the sandbox parameters?
> 
> The bundle ID of the embedding application definitely does. It is OK for it
> to have other kinds of influence as long as we understand that the input can
> be malicious, and handle it defensively before enabling the sandbox.

On second thought, I think the current patch is correct, since it does not cause WebKit processes to share profiles. It only makes them end up in the same folder for various apps, e.g. in the subfolder com.apple.WebKit.WebContent.Sandbox for the WebContent process. This is already usually the case, but this patch makes this consistent, also when the WebKit process has a user directory suffix set. What do you think?
Comment 9 Per Arne Vollan 2021-01-08 08:38:09 PST
I have verified locally that confstr correctly handles multiple updates of the user directory suffix with the function _set_user_dir_suffix().
Comment 10 Brent Fulgham 2021-01-08 15:41:33 PST
Comment on attachment 417079 [details]
Patch

R=me, based on Per Arne's latest testing.
Comment 11 Alexey Proskuryakov 2021-01-08 15:49:03 PST
Comment on attachment 417079 [details]
Patch

This wasn't even up for review...
Comment 12 EWS 2021-01-08 15:49:12 PST
Committed r271331: <https://trac.webkit.org/changeset/271331>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 417079 [details].
Comment 13 WebKit Commit Bot 2021-01-08 16:02:30 PST
Re-opened since this is blocked by bug 220487
Comment 14 David Kilzer (:ddkilzer) 2021-01-09 06:19:41 PST
Comment on attachment 417079 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=417079&action=review

> Source/WebCore/PAL/pal/spi/cocoa/CoreServicesSPI.h:28
> +extern "C" {

FYI, there are BEGIN_EXTERN_C and END_EXTERN_C macros in one of the WTF compiler headers, so I think we should be using those going forward.
Comment 15 Per Arne Vollan 2021-01-12 04:46:15 PST
(In reply to David Kilzer (:ddkilzer) from comment #14)
> Comment on attachment 417079 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=417079&action=review
> 
> > Source/WebCore/PAL/pal/spi/cocoa/CoreServicesSPI.h:28
> > +extern "C" {
> 
> FYI, there are BEGIN_EXTERN_C and END_EXTERN_C macros in one of the WTF
> compiler headers, so I think we should be using those going forward.

Will fix!

Thanks for reviewing!
Comment 16 Per Arne Vollan 2021-01-12 05:23:35 PST
Created attachment 417446 [details]
Patch
Comment 17 Per Arne Vollan 2021-01-12 05:26:29 PST
Created attachment 417447 [details]
Patch
Comment 18 Alexey Proskuryakov 2021-01-12 12:02:36 PST
Comment on attachment 417447 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=417447&action=review

> Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm:658
> +    _set_user_dir_suffix(FileSystem::fileSystemRepresentation(sandboxParameters.userDirectorySuffix()).data());

Does this put cache and temporary directories under the original suffix? Wouldn't that just crash for the same reason?

Also, I'm beginning to think that WebKit auxiliary processes should completely ignore the UI process suffix, not just for data vault. We never put cache and temporary files under UI process control, or otherwise implicitly inherit anything from UI process, and I don't see why we'd do that for processes that set the suffix. Perhaps we should talk to owners of this one to see what they are trying to achieve.
Comment 19 Per Arne Vollan 2021-01-12 12:20:02 PST
(In reply to Alexey Proskuryakov from comment #18)
> Comment on attachment 417447 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=417447&action=review
> 
> > Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm:658
> > +    _set_user_dir_suffix(FileSystem::fileSystemRepresentation(sandboxParameters.userDirectorySuffix()).data());
> 
> Does this put cache and temporary directories under the original suffix?
> Wouldn't that just crash for the same reason?
> 

This puts cache and temporary directory directly under the top level cache or temporary directory. For example, for the Networking process running under MiniBrowser, this will set the suffix to 'com.apple.WebKit.Networking+org.webkit.MiniBrowser', and the cache folder will be at '/var/folders/dd/wjn_0cz5593389p25ybpbml00000gn/C/com.apple.WebKit.Networking+org.webkit.MiniBrowser'.

This will not crash, since 'com.apple.WebKit.Networking+org.webkit.MiniBrowser' is a valid user directory suffix, which the system handles successfully.

This change does actually not change behavior, it just replaces a setenv with _set_user_dir_suffix.

> Also, I'm beginning to think that WebKit auxiliary processes should
> completely ignore the UI process suffix, not just for data vault. We never
> put cache and temporary files under UI process control, or otherwise
> implicitly inherit anything from UI process, and I don't see why we'd do
> that for processes that set the suffix. Perhaps we should talk to owners of
> this one to see what they are trying to achieve.

I think this patch makes us completely ignore the user directory suffix we inherit from the UI process, unless confstr is called before we reset the user directory suffix. Currently, there is no confstr call before the reset. This path is always taken on macOS, and makes sure we have an empty user directory suffix until we choose to set it ourselves with the above call to '_set_user_dir_suffix(FileSystem::fileSystemRepresentation(sandboxParameters.userDirectorySuffix()).data())', which will be the user directory suffix for the rest of the process lifetime.

We could consider resetting the user directory suffix even earlier to guard against confstr calls being added before we reset the user directory suffix. What do you think?
Comment 20 Alexey Proskuryakov 2021-01-12 12:31:59 PST
Comment on attachment 417447 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=417447&action=review

> Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm:705
> +    _set_user_dir_suffix(nullptr);

I'm still not sure from looking at the code if we can set this twice. This function itself support that, but dirhelper does not, as _dirhelper_init is only executed once, and sets state based forever.
Comment 21 Per Arne Vollan 2021-01-12 14:24:59 PST
(In reply to Alexey Proskuryakov from comment #20)
> Comment on attachment 417447 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=417447&action=review
> 
> > Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm:705
> > +    _set_user_dir_suffix(nullptr);
> 
> I'm still not sure from looking at the code if we can set this twice. This
> function itself support that, but dirhelper does not, as _dirhelper_init is
> only executed once, and sets state based forever.

In the debugger, I have verified that results from confstr are correct after multiple updates of the suffix with _set_user_dir_suffix.

Thanks for reviewing!
Comment 22 EWS 2021-01-12 14:47:19 PST
Committed r271417: <https://trac.webkit.org/changeset/271417>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 417447 [details].