Changeset 147500 in webkit


Ignore:
Timestamp:
Apr 2, 2013 2:49:34 PM (11 years ago)
Author:
ap@apple.com
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:
Location:
trunk/Source/WebKit2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r147489 r147500  
     12013-04-02  Simon Cooper  <scooper@apple.com>
     2
     3        [Mac][WK2] Don’t let plug-ins use System V shared memory
     4        https://bugs.webkit.org/show_bug.cgi?id=113466
     5        <rdar://problem/13159030>
     6
     7        Reviewed, tweaked and landed by Alexey Proskuryakov.
     8
     9        Instead of allowing plug-ins to request System V shm, give them a
     10        temporary but usable alternative if they try to request it.
     11
     12        * PluginProcess/mac/PluginProcessShim.mm:
     13
    1142013-04-02  Anders Carlsson  <andersca@apple.com>
    215
  • trunk/Source/WebKit2/PluginProcess/mac/PluginProcessShim.mm

    r135882 r147500  
    3333#import <objc/message.h>
    3434
     35#include <sys/shm.h>
     36#include <sys/ipc.h>
     37#include <sys/mman.h>
     38
    3539#define DYLD_INTERPOSE(_replacement,_replacee) \
    3640    __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \
     
    114118#endif
    115119
     120// Simple Fake System V shared memory. This replacement API implements
     121// usable system V shared memory for use within a single process. The memory
     122// is not shared outside of the scope of the process.
     123struct FakeSharedMemoryDescriptor {
     124    FakeSharedMemoryDescriptor* next;
     125    int referenceCount;
     126    key_t key;
     127    size_t requestedSize;
     128    size_t mmapedSize;
     129    int sharedMemoryFlags;
     130    int sharedMemoryIdentifier;
     131    void* mmapedAddress;
     132};
     133
     134static FakeSharedMemoryDescriptor* shmDescriptorList = 0;
     135static int fakeSharedMemoryIdentifier = 0;
     136
     137static FakeSharedMemoryDescriptor* findBySharedMemoryIdentifier(int sharedMemoryIdentifier)
     138{
     139    FakeSharedMemoryDescriptor* descriptorPtr = shmDescriptorList;
     140
     141    while (descriptorPtr) {
     142        if (descriptorPtr->sharedMemoryIdentifier == sharedMemoryIdentifier)
     143            break;
     144        descriptorPtr = descriptorPtr->next;
     145    }
     146    return descriptorPtr;
     147}
     148
     149static FakeSharedMemoryDescriptor* findBySharedMemoryAddress(const void* mmapedAddress)
     150{
     151    FakeSharedMemoryDescriptor* descriptorPtr = shmDescriptorList;
     152
     153    while (descriptorPtr) {
     154        if (descriptorPtr->mmapedAddress == mmapedAddress)
     155            break;
     156
     157        descriptorPtr = descriptorPtr->next;
     158    }
     159    return descriptorPtr;
     160}
     161
     162static int shim_shmdt(const void* sharedAddress)
     163{
     164    FakeSharedMemoryDescriptor* descriptorPtr = findBySharedMemoryAddress(sharedAddress);
     165    if (!descriptorPtr) {
     166        errno = EINVAL;
     167        return -1;
     168    }
     169
     170    descriptorPtr->referenceCount--;
     171    if (!descriptorPtr->referenceCount) {
     172        munmap(descriptorPtr->mmapedAddress, descriptorPtr->mmapedSize);
     173        descriptorPtr->mmapedAddress = 0;
     174    }
     175
     176    return 0;
     177}
     178
     179static void* shim_shmat(int sharedMemoryIdentifier, const void* requestedSharedAddress, int shmflg)
     180{
     181    FakeSharedMemoryDescriptor* descriptorPtr = findBySharedMemoryIdentifier(sharedMemoryIdentifier);
     182    void* mappedAddress = (void*)-1;
     183
     184    if (!descriptorPtr) {
     185        errno = EINVAL;
     186        return mappedAddress;
     187    }
     188
     189    if (descriptorPtr->mmapedAddress) {
     190        if (!requestedSharedAddress || requestedSharedAddress == descriptorPtr->mmapedAddress) {
     191            mappedAddress = descriptorPtr->mmapedAddress;
     192            descriptorPtr->referenceCount++;
     193        }
     194    } else {
     195        descriptorPtr->mmapedSize = (descriptorPtr->requestedSize + PAGE_SIZE) & ~(PAGE_SIZE - 1);
     196        mappedAddress = descriptorPtr->mmapedAddress = mmap((void*)requestedSharedAddress,
     197            descriptorPtr->mmapedSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
     198        descriptorPtr->referenceCount++;
     199    }
     200
     201    return mappedAddress;
     202}
     203
     204static int shim_shmget(key_t key, size_t requestedSizeOfSharedMemory, int sharedMemoryFlags)
     205{
     206    FakeSharedMemoryDescriptor* descriptorPtr = shmDescriptorList;
     207
     208    while (descriptorPtr) {
     209        // Are we looking for something we've already created?
     210        if (descriptorPtr->key == key
     211            && descriptorPtr->requestedSize == requestedSizeOfSharedMemory
     212            && !((descriptorPtr->sharedMemoryFlags ^ sharedMemoryFlags) & 0777))
     213            break;
     214        descriptorPtr = descriptorPtr->next;
     215    }
     216
     217    if (!descriptorPtr) {
     218        descriptorPtr = (FakeSharedMemoryDescriptor*)malloc(sizeof(FakeSharedMemoryDescriptor));
     219        if (!descriptorPtr) {
     220            errno = ENOMEM;
     221            return -1;
     222        }
     223        descriptorPtr->key = key;
     224        descriptorPtr->requestedSize = requestedSizeOfSharedMemory;
     225        descriptorPtr->sharedMemoryFlags = sharedMemoryFlags;
     226        descriptorPtr->sharedMemoryIdentifier = ++fakeSharedMemoryIdentifier;
     227        descriptorPtr->referenceCount = 0;
     228        descriptorPtr->mmapedAddress = 0;
     229        descriptorPtr->mmapedSize = 0;
     230        descriptorPtr->next = shmDescriptorList;
     231        shmDescriptorList = descriptorPtr;
     232    }
     233    return descriptorPtr->sharedMemoryIdentifier;
     234}
     235
     236static int shim_shmctl(int sharedMemoryIdentifier, int cmd, struct shmid_ds* outputDescriptor)
     237{
     238    FakeSharedMemoryDescriptor* descriptorPtr = findBySharedMemoryIdentifier(sharedMemoryIdentifier);
     239
     240    if (!descriptorPtr) {
     241        errno = EINVAL;
     242        return -1;
     243    }
     244
     245    switch (cmd) {
     246    case IPC_SET:
     247    case IPC_RMID:
     248        errno = EPERM;
     249        return -1;
     250
     251    case IPC_STAT:
     252        outputDescriptor->shm_perm.cuid = outputDescriptor->shm_perm.uid = getuid();
     253        outputDescriptor->shm_perm.cgid = outputDescriptor->shm_perm.gid = getgid();
     254        outputDescriptor->shm_perm.mode = descriptorPtr->sharedMemoryFlags & 0777;
     255
     256        outputDescriptor->shm_segsz = descriptorPtr->requestedSize;
     257
     258        outputDescriptor->shm_cpid = outputDescriptor->shm_lpid = getpid();
     259
     260        outputDescriptor->shm_nattch = descriptorPtr->referenceCount;
     261
     262        outputDescriptor->shm_ctime = outputDescriptor->shm_atime = outputDescriptor->shm_dtime = time(0);
     263
     264        return 0;
     265    }
     266
     267    errno = EINVAL;
     268    return -1;
     269}
     270
     271DYLD_INTERPOSE(shim_shmat, shmat);
     272DYLD_INTERPOSE(shim_shmdt, shmdt);
     273DYLD_INTERPOSE(shim_shmget, shmget);
     274DYLD_INTERPOSE(shim_shmctl, shmctl);
     275
    116276__attribute__((visibility("default")))
    117277void WebKitPluginProcessShimInitialize(const PluginProcessShimCallbacks& callbacks)
     
    121281
    122282} // namespace WebKit
     283
Note: See TracChangeset for help on using the changeset viewer.