Bug 143834 - Compiling a content extension fails when user's home directory is on a different volume from /var/tmp
Summary: Compiling a content extension fails when user's home directory is on a differ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Brady Eidson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-16 11:42 PDT by Brady Eidson
Modified: 2015-04-16 17:54 PDT (History)
4 users (show)

See Also:


Attachments
Patch v1 (3.60 KB, patch)
2015-04-16 13:00 PDT, Brady Eidson
no flags Details | Formatted Diff | Diff
Patch v2 (3.58 KB, patch)
2015-04-16 13:12 PDT, Brady Eidson
oliver: review-
Details | Formatted Diff | Diff
Patch v3 - MMAP and tighter permissions (4.02 KB, patch)
2015-04-16 15:26 PDT, Brady Eidson
no flags Details | Formatted Diff | Diff
Patch v4 - Fallback to NSFileManager (3.78 KB, patch)
2015-04-16 16:01 PDT, Brady Eidson
andersca: review-
Details | Formatted Diff | Diff
Patch v5 (3.37 KB, patch)
2015-04-16 16:21 PDT, Brady Eidson
no flags Details | Formatted Diff | Diff
Patch v6 (3.28 KB, patch)
2015-04-16 16:23 PDT, Brady Eidson
no flags Details | Formatted Diff | Diff
Patch v7 (6.28 KB, patch)
2015-04-16 16:32 PDT, Brady Eidson
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Brady Eidson 2015-04-16 11:42:00 PDT
Compiling a content extension fails when user's home directory is on a different volume from /var/tmp

When compiling the extension to a temporary file, the extension is then moved to ~/Library via "rename", but rename() fails when moving across volumes.

In the case where rename() fails due to a cross-device error, fallback to the standard "copy file contents then delete the old file" mechanism.
Comment 1 Brady Eidson 2015-04-16 13:00:21 PDT
Created attachment 250942 [details]
Patch v1
Comment 2 Alex Christensen 2015-04-16 13:09:02 PDT
Comment on attachment 250942 [details]
Patch v1

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

> Source/WebCore/platform/posix/FileSystemPOSIX.cpp:84
> +    // Open the file for writing only, creating it, and failing if it already exists.
> +    int outModeFlags = O_WRONLY | O_CREAT | O_EXCL;

Why do we want to fail if it already exists?  Shouldn't moveFile overwrite any existing file?
Comment 3 Brady Eidson 2015-04-16 13:10:11 PDT
Will be asking for the eyes of multiple reviewers.
Comment 4 Brady Eidson 2015-04-16 13:11:50 PDT
(In reply to comment #2)
> Comment on attachment 250942 [details]
> Patch v1
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=250942&action=review
> 
> > Source/WebCore/platform/posix/FileSystemPOSIX.cpp:84
> > +    // Open the file for writing only, creating it, and failing if it already exists.
> > +    int outModeFlags = O_WRONLY | O_CREAT | O_EXCL;
> 
> Why do we want to fail if it already exists?  Shouldn't moveFile overwrite
> any existing file?

In general we're quite conservative in our FS operations in WebCore/Kit.

But I suppose the semantics of rename() are that the old file at the target location is first unlinked.

In that this supports rename(), I'll make that change.
Comment 5 Brady Eidson 2015-04-16 13:12:44 PDT
Created attachment 250944 [details]
Patch v2
Comment 6 Brady Eidson 2015-04-16 13:14:11 PDT
(Yes, I understand that the semantics of `mv` are also to overwrite the target file by default, but moveFile itself is not being exposed to clients. If it were I'd likely include an "overwrite?" option that defaults to false)
Comment 7 Oliver Hunt 2015-04-16 13:15:34 PDT
Comment on attachment 250942 [details]
Patch v1

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

You should probably just mmap the source file and then blat it down in a single write. Code should end up simpler as well. I'm also concerned about permission elevation as mentioned inline.

> Source/WebCore/platform/posix/FileSystemPOSIX.cpp:89
> +    outFD = open(newPath.data(), outModeFlags, outPermissionFlags);

Why are we making the extension world readable?
Comment 8 Oliver Hunt 2015-04-16 13:16:46 PDT
Comment on attachment 250944 [details]
Patch v2

R- for reasons attached to the last patch
Comment 9 Brady Eidson 2015-04-16 13:18:50 PDT
(In reply to comment #7)
> Comment on attachment 250942 [details]
> Patch v1
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=250942&action=review
> 
> You should probably just mmap the source file and then blat it down in a
> single write. Code should end up simpler as well. I'm also concerned about
> permission elevation as mentioned inline.
> 

That's a good idea!

> > Source/WebCore/platform/posix/FileSystemPOSIX.cpp:89
> > +    outFD = open(newPath.data(), outModeFlags, outPermissionFlags);
> 
> Why are we making the extension world readable?

I was wearing two hats - Fixing content extensions, and writing a more general purpose function.

I agree, no need for world (or even group!) readability *right now*.
Comment 10 Brady Eidson 2015-04-16 15:26:16 PDT
Created attachment 250954 [details]
Patch v3 - MMAP and tighter permissions
Comment 11 Brady Eidson 2015-04-16 15:43:01 PDT
Comment on attachment 250954 [details]
Patch v3 - MMAP and tighter permissions

NM Anders wants us to not provide a POSIX impl and use NSFileManager instead.
Comment 12 Brady Eidson 2015-04-16 16:01:27 PDT
Created attachment 250964 [details]
Patch v4 - Fallback to NSFileManager
Comment 13 WebKit Commit Bot 2015-04-16 16:04:03 PDT
Attachment 250964 [details] did not pass style-queue:


ERROR: Source/WebCore/platform/FileSystem.cpp:102:  Tab found; better to use spaces  [whitespace/tab] [1]
ERROR: Source/WebCore/platform/FileSystem.cpp:103:  Tab found; better to use spaces  [whitespace/tab] [1]
Total errors found: 2 in 5 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 14 Anders Carlsson 2015-04-16 16:07:27 PDT
Comment on attachment 250964 [details]
Patch v4 - Fallback to NSFileManager

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

> Source/WebCore/platform/mac/FileSystemMac.mm:73
> +    NSError *error = nil;
> +    [[NSFileManager defaultManager] moveItemAtPath:(NSString *)oldPath toPath:(NSString *)newPath error:&error];

The right way to test for success is to check the return value, not whether error is nil or not (that's not guaranteed).

This should use the moveItemAtURL:toURL:error: method (Together with -[NSURL fileURLWithPath:].

> Source/WebCore/platform/posix/FileSystemPOSIX.cpp:94
> +    int result = rename(oldPathFsRep.data(), newPathFsRep.data());
> +    if (!result)
> +        return true;
> +
> +    if (errno != EXDEV)
> +        return false;
> +
> +    // The paths exist on different devices so a simple rename will not work.
> +    // We have to manually move the file.
> +    return moveFile(oldPath, newPath);
>  }

Instead of modifying the behavior of renameFile, I think you should just make whoever calls renameFile call moveFile instead.
Comment 15 Brady Eidson 2015-04-16 16:11:06 PDT
(In reply to comment #14)
> Comment on attachment 250964 [details]
> Patch v4 - Fallback to NSFileManager
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=250964&action=review
> 
> > Source/WebCore/platform/mac/FileSystemMac.mm:73
> > +    NSError *error = nil;
> > +    [[NSFileManager defaultManager] moveItemAtPath:(NSString *)oldPath toPath:(NSString *)newPath error:&error];
> 
> The right way to test for success is to check the return value, not whether
> error is nil or not (that's not guaranteed).

Fair enough.

> 
> This should use the moveItemAtURL:toURL:error: method (Together with -[NSURL
> fileURLWithPath:].

Since we already have fully qualified paths, it seems wasteful to use the URL form unless it actually has advantages other than "urls seem nicer".

> 
> > Source/WebCore/platform/posix/FileSystemPOSIX.cpp:94
> > +    int result = rename(oldPathFsRep.data(), newPathFsRep.data());
> > +    if (!result)
> > +        return true;
> > +
> > +    if (errno != EXDEV)
> > +        return false;
> > +
> > +    // The paths exist on different devices so a simple rename will not work.
> > +    // We have to manually move the file.
> > +    return moveFile(oldPath, newPath);
> >  }
> 
> Instead of modifying the behavior of renameFile, I think you should just
> make whoever calls renameFile call moveFile instead.

There's only one caller.

Maybe renameFile should just be the NSFileManager version on Mac.
Comment 16 Brady Eidson 2015-04-16 16:21:45 PDT
Created attachment 250971 [details]
Patch v5
Comment 17 Brady Eidson 2015-04-16 16:23:58 PDT
Created attachment 250973 [details]
Patch v6
Comment 18 Anders Carlsson 2015-04-16 16:25:38 PDT
Comment on attachment 250973 [details]
Patch v6

Sorry for being unclear. Here's what I think we should do:

- renameFile should keep its semantics of being an atomic POSIX rename.
- The WebKit2 call to renameFile should be a call to moveFile instead.
Comment 19 Brady Eidson 2015-04-16 16:27:49 PDT
(In reply to comment #18)
> Comment on attachment 250973 [details]
> Patch v6
> 
> Sorry for being unclear. Here's what I think we should do:
> 
> - renameFile should keep its semantics of being an atomic POSIX rename.
> - The WebKit2 call to renameFile should be a call to moveFile instead.

If we do that, renameFile will be dead code. Single call site in WK2 is the only caller.

I'll nuke it and make WK2 use moveFile instead.
Comment 20 Brady Eidson 2015-04-16 16:32:06 PDT
Created attachment 250977 [details]
Patch v7
Comment 21 Brady Eidson 2015-04-16 16:32:59 PDT
(In reply to comment #19)
> (In reply to comment #18)
> If we do that, renameFile will be dead code. Single call site in WK2 is the
> only caller.

In addition, that call site only compiles on Mac/iOS right now, so we only need the NSFileManager version of the call.
Comment 22 WebKit Commit Bot 2015-04-16 17:54:23 PDT
Comment on attachment 250977 [details]
Patch v7

Clearing flags on attachment: 250977

Committed r182932: <http://trac.webkit.org/changeset/182932>
Comment 23 WebKit Commit Bot 2015-04-16 17:54:26 PDT
All reviewed patches have been landed.  Closing bug.