socket: fix bug #65260 (SCM_RIGHTS)

The data for messages of type SOL_SOCKET/SCM_RIGHTS was not being
passed correctly. There were actually two bugs: (1) the number of file
descriptors being passed was being read incorrectly (the length of the
cmsg array was being read instead of that of its 'data' element), as a
result it was generally being reported as always three elements
('level', 'type' and 'data') and (2) the allocated block for writing
the file descriptors was being acessed incorrectly because a 1-based
counter was being used as if it was 0-based.

Any of these two bugs would probably be enough to cause heap
corruption.
This commit is contained in:
Gustavo Lopes 2013-07-15 01:44:38 +02:00
parent e7a4cf8d7e
commit e2744f1aa3
2 changed files with 11 additions and 2 deletions

View file

@ -223,6 +223,7 @@ static unsigned from_array_iterate(const zval *arr,
char buf[sizeof("element #4294967295")]; char buf[sizeof("element #4294967295")];
char *bufp = buf; char *bufp = buf;
/* Note i starts at 1, not 0! */
for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 1; for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 1;
!ctx->err.has_error !ctx->err.has_error
&& zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS; && zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS;
@ -869,7 +870,14 @@ static void from_zval_write_control(const zval *arr,
} }
if (entry->calc_space) { if (entry->calc_space) {
data_len = entry->calc_space(arr, ctx); zval **data_elem;
/* arr must be an array at this point */
if (zend_hash_find(Z_ARRVAL_P(arr), "data", sizeof("data"),
(void**)&data_elem) == FAILURE) {
do_from_zval_err(ctx, "cmsghdr should have a 'data' element here");
return;
}
data_len = entry->calc_space(*data_elem, ctx);
if (ctx->err.has_error) { if (ctx->err.has_error) {
return; return;
} }
@ -1370,7 +1378,7 @@ static void from_zval_write_fd_array_aux(zval **elem, unsigned i, void **args, s
return; return;
} }
if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i], if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i - 1],
REPORT_ERRORS) == FAILURE) { REPORT_ERRORS) == FAILURE) {
do_from_zval_err(ctx, "cast stream to file descriptor failed"); do_from_zval_err(ctx, "cast stream to file descriptor failed");
return; return;

View file

@ -84,6 +84,7 @@ Array
[0] => Resource id #%d [0] => Resource id #%d
[1] => Resource id #%d [1] => Resource id #%d
[2] => Resource id #%d [2] => Resource id #%d
[3] => Resource id #%d
) )
) )