Title: [147500] trunk/Source/WebKit2
- Revision
- 147500
- Author
- [email protected]
- Date
- 2013-04-02 14:49:34 -0700 (Tue, 02 Apr 2013)
Log Message
[Mac][WK2] Donât let plug-ins use System V shared memory
https://bugs.webkit.org/show_bug.cgi?id=113466
<rdar://problem/13159030>
Reviewed, tweaked and landed by Alexey Proskuryakov.
Instead of allowing plug-ins to request System V shm, give them a
temporary but usable alternative if they try to request it.
* PluginProcess/mac/PluginProcessShim.mm:
Modified Paths
Diff
Modified: trunk/Source/WebKit2/ChangeLog (147499 => 147500)
--- trunk/Source/WebKit2/ChangeLog 2013-04-02 21:24:14 UTC (rev 147499)
+++ trunk/Source/WebKit2/ChangeLog 2013-04-02 21:49:34 UTC (rev 147500)
@@ -1,3 +1,16 @@
+2013-04-02 Simon Cooper <[email protected]>
+
+ [Mac][WK2] Don’t let plug-ins use System V shared memory
+ https://bugs.webkit.org/show_bug.cgi?id=113466
+ <rdar://problem/13159030>
+
+ Reviewed, tweaked and landed by Alexey Proskuryakov.
+
+ Instead of allowing plug-ins to request System V shm, give them a
+ temporary but usable alternative if they try to request it.
+
+ * PluginProcess/mac/PluginProcessShim.mm:
+
2013-04-02 Anders Carlsson <[email protected]>
Add WKContextSetInvalidMessageFunction
Modified: trunk/Source/WebKit2/PluginProcess/mac/PluginProcessShim.mm (147499 => 147500)
--- trunk/Source/WebKit2/PluginProcess/mac/PluginProcessShim.mm 2013-04-02 21:24:14 UTC (rev 147499)
+++ trunk/Source/WebKit2/PluginProcess/mac/PluginProcessShim.mm 2013-04-02 21:49:34 UTC (rev 147500)
@@ -32,6 +32,10 @@
#import <stdio.h>
#import <objc/message.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+#include <sys/mman.h>
+
#define DYLD_INTERPOSE(_replacement,_replacee) \
__attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee };
@@ -113,6 +117,162 @@
#endif
+// Simple Fake System V shared memory. This replacement API implements
+// usable system V shared memory for use within a single process. The memory
+// is not shared outside of the scope of the process.
+struct FakeSharedMemoryDescriptor {
+ FakeSharedMemoryDescriptor* next;
+ int referenceCount;
+ key_t key;
+ size_t requestedSize;
+ size_t mmapedSize;
+ int sharedMemoryFlags;
+ int sharedMemoryIdentifier;
+ void* mmapedAddress;
+};
+
+static FakeSharedMemoryDescriptor* shmDescriptorList = 0;
+static int fakeSharedMemoryIdentifier = 0;
+
+static FakeSharedMemoryDescriptor* findBySharedMemoryIdentifier(int sharedMemoryIdentifier)
+{
+ FakeSharedMemoryDescriptor* descriptorPtr = shmDescriptorList;
+
+ while (descriptorPtr) {
+ if (descriptorPtr->sharedMemoryIdentifier == sharedMemoryIdentifier)
+ break;
+ descriptorPtr = descriptorPtr->next;
+ }
+ return descriptorPtr;
+}
+
+static FakeSharedMemoryDescriptor* findBySharedMemoryAddress(const void* mmapedAddress)
+{
+ FakeSharedMemoryDescriptor* descriptorPtr = shmDescriptorList;
+
+ while (descriptorPtr) {
+ if (descriptorPtr->mmapedAddress == mmapedAddress)
+ break;
+
+ descriptorPtr = descriptorPtr->next;
+ }
+ return descriptorPtr;
+}
+
+static int shim_shmdt(const void* sharedAddress)
+{
+ FakeSharedMemoryDescriptor* descriptorPtr = findBySharedMemoryAddress(sharedAddress);
+ if (!descriptorPtr) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ descriptorPtr->referenceCount--;
+ if (!descriptorPtr->referenceCount) {
+ munmap(descriptorPtr->mmapedAddress, descriptorPtr->mmapedSize);
+ descriptorPtr->mmapedAddress = 0;
+ }
+
+ return 0;
+}
+
+static void* shim_shmat(int sharedMemoryIdentifier, const void* requestedSharedAddress, int shmflg)
+{
+ FakeSharedMemoryDescriptor* descriptorPtr = findBySharedMemoryIdentifier(sharedMemoryIdentifier);
+ void* mappedAddress = (void*)-1;
+
+ if (!descriptorPtr) {
+ errno = EINVAL;
+ return mappedAddress;
+ }
+
+ if (descriptorPtr->mmapedAddress) {
+ if (!requestedSharedAddress || requestedSharedAddress == descriptorPtr->mmapedAddress) {
+ mappedAddress = descriptorPtr->mmapedAddress;
+ descriptorPtr->referenceCount++;
+ }
+ } else {
+ descriptorPtr->mmapedSize = (descriptorPtr->requestedSize + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+ mappedAddress = descriptorPtr->mmapedAddress = mmap((void*)requestedSharedAddress,
+ descriptorPtr->mmapedSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ descriptorPtr->referenceCount++;
+ }
+
+ return mappedAddress;
+}
+
+static int shim_shmget(key_t key, size_t requestedSizeOfSharedMemory, int sharedMemoryFlags)
+{
+ FakeSharedMemoryDescriptor* descriptorPtr = shmDescriptorList;
+
+ while (descriptorPtr) {
+ // Are we looking for something we've already created?
+ if (descriptorPtr->key == key
+ && descriptorPtr->requestedSize == requestedSizeOfSharedMemory
+ && !((descriptorPtr->sharedMemoryFlags ^ sharedMemoryFlags) & 0777))
+ break;
+ descriptorPtr = descriptorPtr->next;
+ }
+
+ if (!descriptorPtr) {
+ descriptorPtr = (FakeSharedMemoryDescriptor*)malloc(sizeof(FakeSharedMemoryDescriptor));
+ if (!descriptorPtr) {
+ errno = ENOMEM;
+ return -1;
+ }
+ descriptorPtr->key = key;
+ descriptorPtr->requestedSize = requestedSizeOfSharedMemory;
+ descriptorPtr->sharedMemoryFlags = sharedMemoryFlags;
+ descriptorPtr->sharedMemoryIdentifier = ++fakeSharedMemoryIdentifier;
+ descriptorPtr->referenceCount = 0;
+ descriptorPtr->mmapedAddress = 0;
+ descriptorPtr->mmapedSize = 0;
+ descriptorPtr->next = shmDescriptorList;
+ shmDescriptorList = descriptorPtr;
+ }
+ return descriptorPtr->sharedMemoryIdentifier;
+}
+
+static int shim_shmctl(int sharedMemoryIdentifier, int cmd, struct shmid_ds* outputDescriptor)
+{
+ FakeSharedMemoryDescriptor* descriptorPtr = findBySharedMemoryIdentifier(sharedMemoryIdentifier);
+
+ if (!descriptorPtr) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ switch (cmd) {
+ case IPC_SET:
+ case IPC_RMID:
+ errno = EPERM;
+ return -1;
+
+ case IPC_STAT:
+ outputDescriptor->shm_perm.cuid = outputDescriptor->shm_perm.uid = getuid();
+ outputDescriptor->shm_perm.cgid = outputDescriptor->shm_perm.gid = getgid();
+ outputDescriptor->shm_perm.mode = descriptorPtr->sharedMemoryFlags & 0777;
+
+ outputDescriptor->shm_segsz = descriptorPtr->requestedSize;
+
+ outputDescriptor->shm_cpid = outputDescriptor->shm_lpid = getpid();
+
+ outputDescriptor->shm_nattch = descriptorPtr->referenceCount;
+
+ outputDescriptor->shm_ctime = outputDescriptor->shm_atime = outputDescriptor->shm_dtime = time(0);
+
+ return 0;
+ }
+
+ errno = EINVAL;
+ return -1;
+}
+
+DYLD_INTERPOSE(shim_shmat, shmat);
+DYLD_INTERPOSE(shim_shmdt, shmdt);
+DYLD_INTERPOSE(shim_shmget, shmget);
+DYLD_INTERPOSE(shim_shmctl, shmctl);
+
__attribute__((visibility("default")))
void WebKitPluginProcessShimInitialize(const PluginProcessShimCallbacks& callbacks)
{
@@ -120,3 +280,4 @@
}
} // namespace WebKit
+
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes