Permalink
Browse files

Don't blindly try to access memory in bad frames

  • Loading branch information...
1 parent 253750f commit 974b6d791c1f9f41954c029d1ca33f450980f120 @mxcl committed Sep 30, 2012
Showing with 14 additions and 6 deletions.
  1. +14 −6 MBWebSocketServer.m
View
@@ -70,36 +70,44 @@ - (void)respondToHandshake:(NSData *)data client:(AsyncSocket *)client {
[client writeData:[response dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:2];
}
-- (uint64_t)readFrame:(const unsigned char*)bytes block:(void (^)(char *data, NSUInteger nbytes))block {
+- (uint64_t)readFrame:(const unsigned char*)bytes length:(NSUInteger)length block:(void (^)(char *data, NSUInteger nbytes))block {
+ if (length < 2)
+ @throw @"Bad frame";
if (!bytes[0] & 0x81)
@throw @"Cannot handle this websocket frame format!";
-
if (!bytes[1] & 0x80)
@throw @"Can only handle websocket frames with masks!";
-
+
unsigned n = 2;
uint64_t N = bytes[1] & 0x7f;
switch (N) {
case 126: {
+ if (length < 4)
+ @throw @"Bad frame";
uint16_t *p = (uint16_t *)(bytes + 2);
N = ntohs(*p);
n += 2;
break;
}
case 127: {
+ if (length < 10)
+ @throw @"Bad frame";
uint64_t *p = (uint64_t *)(bytes + 2);
N = ntohll(*p);
n += 8;
}
default:
break;
}
-
+
+ if (length < n + 4 + N)
+ @throw @"Bad frame";
+
const unsigned char *mask = bytes + n;
char unmaskedData[N];
for (int x = 0; x < N; ++x)
unmaskedData[x] = bytes[x+n+4] ^ mask[x%4];
-
+
block(unmaskedData, N);
return n + 4 + N;
@@ -109,7 +117,7 @@ - (NSData *)readFrames:(NSData *)indata {
NSMutableData *data = [NSMutableData data];
uint x = 0;
while (x < indata.length) {
- x += [self readFrame:indata.bytes + x block:^(char *rawdata, NSUInteger length){
+ x += [self readFrame:indata.bytes + x length:indata.length block:^(char *rawdata, NSUInteger length){
[data appendBytes:rawdata length:length];
}];
}

0 comments on commit 974b6d7

Please sign in to comment.