OSDN Git Service

Merge WebKit at r84325: Initial merge by git.
[android-x86/external-webkit.git] / Source / WebKit2 / Shared / mac / SandboxExtensionMac.mm
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "SandboxExtension.h"
28
29 #if ENABLE(WEB_PROCESS_SANDBOX)
30
31 #import "ArgumentDecoder.h"
32 #import "ArgumentEncoder.h"
33 #import "DataReference.h"
34 #import "WebKitSystemInterface.h"
35 #import <WebCore/FileSystem.h>
36 #import <sys/stat.h>
37 #import <wtf/text/CString.h>
38
39 using namespace WebCore;
40
41 namespace WebKit {
42
43 SandboxExtension::Handle::Handle()
44     : m_sandboxExtension(0)
45 {
46 }
47     
48 SandboxExtension::Handle::~Handle()
49 {
50     if (m_sandboxExtension) {
51         WKSandboxExtensionInvalidate(m_sandboxExtension);
52         WKSandboxExtensionDestroy(m_sandboxExtension);
53     }
54 }
55
56 void SandboxExtension::Handle::encode(CoreIPC::ArgumentEncoder* encoder) const
57 {
58     if (!m_sandboxExtension) {
59         encoder->encodeBytes(0, 0);
60         return;
61     }
62
63     size_t length = 0;
64     const char *serializedFormat = WKSandboxExtensionGetSerializedFormat(m_sandboxExtension, &length);
65     ASSERT(serializedFormat);
66
67     encoder->encodeBytes(reinterpret_cast<const uint8_t*>(serializedFormat), length);
68
69     // Encoding will destroy the sandbox extension locally.
70     WKSandboxExtensionDestroy(m_sandboxExtension);
71     m_sandboxExtension = 0;
72 }
73
74 bool SandboxExtension::Handle::decode(CoreIPC::ArgumentDecoder* decoder, Handle& result)
75 {
76     ASSERT(!result.m_sandboxExtension);
77
78     CoreIPC::DataReference dataReference;
79     if (!decoder->decodeBytes(dataReference))
80         return false;
81
82     if (dataReference.isEmpty())
83         return true;
84
85     result.m_sandboxExtension = WKSandboxExtensionCreateFromSerializedFormat(reinterpret_cast<const char*>(dataReference.data()), dataReference.size());
86     return true;
87 }
88
89 PassRefPtr<SandboxExtension> SandboxExtension::create(const Handle& handle)
90 {
91     if (!handle.m_sandboxExtension)
92         return 0;
93
94     return adoptRef(new SandboxExtension(handle));
95 }
96
97 static WKSandboxExtensionType wkSandboxExtensionType(SandboxExtension::Type type)
98 {
99     switch (type) {
100     case SandboxExtension::ReadOnly:
101         return WKSandboxExtensionTypeReadOnly;
102     case SandboxExtension::WriteOnly:
103         return WKSandboxExtensionTypeWriteOnly;
104     case SandboxExtension::ReadWrite:
105         return WKSandboxExtensionTypeReadWrite;
106     }
107
108     ASSERT_NOT_REACHED();
109     return WKSandboxExtensionTypeReadOnly;
110 }
111
112 static CString resolveSymlinksInPath(const CString& path)
113 {
114     struct stat statBuf;
115
116     // Check if this file exists.
117     if (!stat(path.data(), &statBuf)) {
118         char resolvedName[PATH_MAX];
119
120         return realpath(path.data(), resolvedName);
121     }
122
123     char* slashPtr = strrchr(path.data(), '/');
124     if (slashPtr == path.data())
125         return path;
126
127     size_t parentDirectoryLength = slashPtr - path.data();
128     if (parentDirectoryLength >= PATH_MAX)
129         return CString();
130
131     // Get the parent directory.
132     char parentDirectory[PATH_MAX];
133     memcpy(parentDirectory, path.data(), parentDirectoryLength);
134     parentDirectory[parentDirectoryLength] = '\0';
135
136     // Resolve it.
137     CString resolvedParentDirectory = resolveSymlinksInPath(CString(parentDirectory));
138     if (resolvedParentDirectory.isNull())
139         return CString();
140
141     size_t lastPathComponentLength = path.length() - parentDirectoryLength;
142     size_t resolvedPathLength = resolvedParentDirectory.length() + lastPathComponentLength;
143     if (resolvedPathLength >= PATH_MAX)
144         return CString();
145
146     // Combine the resolved parent directory with the last path component.
147     char* resolvedPathBuffer;
148     CString resolvedPath = CString::newUninitialized(resolvedPathLength, resolvedPathBuffer);
149     memcpy(resolvedPathBuffer, resolvedParentDirectory.data(), resolvedParentDirectory.length());
150     memcpy(resolvedPathBuffer + resolvedParentDirectory.length(), slashPtr, lastPathComponentLength);
151
152     return resolvedPath;
153 }
154
155 void SandboxExtension::createHandle(const String& path, Type type, Handle& handle)
156 {
157     ASSERT(!handle.m_sandboxExtension);
158
159     CString standardizedPath = resolveSymlinksInPath([[(NSString *)path stringByStandardizingPath] fileSystemRepresentation]);
160     handle.m_sandboxExtension = WKSandboxExtensionCreate(standardizedPath.data(), wkSandboxExtensionType(type));
161 }
162     
163 String SandboxExtension::createHandleForTemporaryFile(const String& prefix, Type type, Handle& handle)
164 {
165     ASSERT(!handle.m_sandboxExtension);
166     
167     Vector<char> path(PATH_MAX);
168     if (!confstr(_CS_DARWIN_USER_TEMP_DIR, path.data(), path.size()))
169         return String();
170     
171     // Shrink the vector.   
172     path.shrink(strlen(path.data()));
173     ASSERT(path.last() == '/');
174     
175     // Append the file name.    
176     path.append(prefix.utf8().data(), prefix.length());
177     path.append('\0');
178     
179     handle.m_sandboxExtension = WKSandboxExtensionCreate(fileSystemRepresentation(path.data()).data(), wkSandboxExtensionType(type));
180
181     if (!handle.m_sandboxExtension) {
182         return String();
183     }
184     return String(path.data());
185 }
186
187 SandboxExtension::SandboxExtension(const Handle& handle)
188     : m_sandboxExtension(handle.m_sandboxExtension)
189 {
190     handle.m_sandboxExtension = 0;
191 }
192
193 SandboxExtension::~SandboxExtension()
194 {
195     if (!m_sandboxExtension)
196         return;
197
198     WKSandboxExtensionInvalidate(m_sandboxExtension);
199     WKSandboxExtensionDestroy(m_sandboxExtension);
200 }
201
202 bool SandboxExtension::invalidate()
203 {
204     ASSERT(m_sandboxExtension);
205
206     bool result = WKSandboxExtensionInvalidate(m_sandboxExtension);
207     WKSandboxExtensionDestroy(m_sandboxExtension);
208     m_sandboxExtension = 0;
209
210     return result;
211 }
212
213 bool SandboxExtension::consume()
214 {
215     ASSERT(m_sandboxExtension);
216
217     return WKSandboxExtensionConsume(m_sandboxExtension);
218 }
219
220 bool SandboxExtension::consumePermanently()
221 {
222     ASSERT(m_sandboxExtension);
223
224     bool result = WKSandboxExtensionConsume(m_sandboxExtension);
225
226     // Destroy the extension without invalidating it.
227     WKSandboxExtensionDestroy(m_sandboxExtension);
228     m_sandboxExtension = 0;
229
230     return result;
231 }
232
233 } // namespace WebKit
234
235 #endif // ENABLE(WEB_PROCESS_SANDBOX)