2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #import "SandboxExtension.h"
29 #if ENABLE(WEB_PROCESS_SANDBOX)
31 #import "ArgumentDecoder.h"
32 #import "ArgumentEncoder.h"
33 #import "DataReference.h"
34 #import "WebKitSystemInterface.h"
35 #import <WebCore/FileSystem.h>
37 #import <wtf/text/CString.h>
39 using namespace WebCore;
43 SandboxExtension::Handle::Handle()
44 : m_sandboxExtension(0)
48 SandboxExtension::Handle::~Handle()
50 if (m_sandboxExtension) {
51 WKSandboxExtensionInvalidate(m_sandboxExtension);
52 WKSandboxExtensionDestroy(m_sandboxExtension);
56 void SandboxExtension::Handle::encode(CoreIPC::ArgumentEncoder* encoder) const
58 if (!m_sandboxExtension) {
59 encoder->encodeBytes(0, 0);
64 const char *serializedFormat = WKSandboxExtensionGetSerializedFormat(m_sandboxExtension, &length);
65 ASSERT(serializedFormat);
67 encoder->encodeBytes(reinterpret_cast<const uint8_t*>(serializedFormat), length);
69 // Encoding will destroy the sandbox extension locally.
70 WKSandboxExtensionDestroy(m_sandboxExtension);
71 m_sandboxExtension = 0;
74 bool SandboxExtension::Handle::decode(CoreIPC::ArgumentDecoder* decoder, Handle& result)
76 ASSERT(!result.m_sandboxExtension);
78 CoreIPC::DataReference dataReference;
79 if (!decoder->decodeBytes(dataReference))
82 if (dataReference.isEmpty())
85 result.m_sandboxExtension = WKSandboxExtensionCreateFromSerializedFormat(reinterpret_cast<const char*>(dataReference.data()), dataReference.size());
89 PassRefPtr<SandboxExtension> SandboxExtension::create(const Handle& handle)
91 if (!handle.m_sandboxExtension)
94 return adoptRef(new SandboxExtension(handle));
97 static WKSandboxExtensionType wkSandboxExtensionType(SandboxExtension::Type type)
100 case SandboxExtension::ReadOnly:
101 return WKSandboxExtensionTypeReadOnly;
102 case SandboxExtension::WriteOnly:
103 return WKSandboxExtensionTypeWriteOnly;
104 case SandboxExtension::ReadWrite:
105 return WKSandboxExtensionTypeReadWrite;
108 ASSERT_NOT_REACHED();
109 return WKSandboxExtensionTypeReadOnly;
112 static CString resolveSymlinksInPath(const CString& path)
116 // Check if this file exists.
117 if (!stat(path.data(), &statBuf)) {
118 char resolvedName[PATH_MAX];
120 return realpath(path.data(), resolvedName);
123 char* slashPtr = strrchr(path.data(), '/');
124 if (slashPtr == path.data())
127 size_t parentDirectoryLength = slashPtr - path.data();
128 if (parentDirectoryLength >= PATH_MAX)
131 // Get the parent directory.
132 char parentDirectory[PATH_MAX];
133 memcpy(parentDirectory, path.data(), parentDirectoryLength);
134 parentDirectory[parentDirectoryLength] = '\0';
137 CString resolvedParentDirectory = resolveSymlinksInPath(CString(parentDirectory));
138 if (resolvedParentDirectory.isNull())
141 size_t lastPathComponentLength = path.length() - parentDirectoryLength;
142 size_t resolvedPathLength = resolvedParentDirectory.length() + lastPathComponentLength;
143 if (resolvedPathLength >= PATH_MAX)
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);
155 void SandboxExtension::createHandle(const String& path, Type type, Handle& handle)
157 ASSERT(!handle.m_sandboxExtension);
159 CString standardizedPath = resolveSymlinksInPath([[(NSString *)path stringByStandardizingPath] fileSystemRepresentation]);
160 handle.m_sandboxExtension = WKSandboxExtensionCreate(standardizedPath.data(), wkSandboxExtensionType(type));
163 String SandboxExtension::createHandleForTemporaryFile(const String& prefix, Type type, Handle& handle)
165 ASSERT(!handle.m_sandboxExtension);
167 Vector<char> path(PATH_MAX);
168 if (!confstr(_CS_DARWIN_USER_TEMP_DIR, path.data(), path.size()))
171 // Shrink the vector.
172 path.shrink(strlen(path.data()));
173 ASSERT(path.last() == '/');
175 // Append the file name.
176 path.append(prefix.utf8().data(), prefix.length());
179 handle.m_sandboxExtension = WKSandboxExtensionCreate(fileSystemRepresentation(path.data()).data(), wkSandboxExtensionType(type));
181 if (!handle.m_sandboxExtension) {
184 return String(path.data());
187 SandboxExtension::SandboxExtension(const Handle& handle)
188 : m_sandboxExtension(handle.m_sandboxExtension)
190 handle.m_sandboxExtension = 0;
193 SandboxExtension::~SandboxExtension()
195 if (!m_sandboxExtension)
198 WKSandboxExtensionInvalidate(m_sandboxExtension);
199 WKSandboxExtensionDestroy(m_sandboxExtension);
202 bool SandboxExtension::invalidate()
204 ASSERT(m_sandboxExtension);
206 bool result = WKSandboxExtensionInvalidate(m_sandboxExtension);
207 WKSandboxExtensionDestroy(m_sandboxExtension);
208 m_sandboxExtension = 0;
213 bool SandboxExtension::consume()
215 ASSERT(m_sandboxExtension);
217 return WKSandboxExtensionConsume(m_sandboxExtension);
220 bool SandboxExtension::consumePermanently()
222 ASSERT(m_sandboxExtension);
224 bool result = WKSandboxExtensionConsume(m_sandboxExtension);
226 // Destroy the extension without invalidating it.
227 WKSandboxExtensionDestroy(m_sandboxExtension);
228 m_sandboxExtension = 0;
233 } // namespace WebKit
235 #endif // ENABLE(WEB_PROCESS_SANDBOX)