~ubuntu-branches/ubuntu/gutsy/php5/gutsy

« back to all changes in this revision

Viewing changes to ext/session/session.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt, CVE-2007-0905, CVE-2007-0906, CVE-2007-0909, CVE-2007-0910
  • Date: 2007-02-20 17:54:46 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20070220175446-nudqyuv0dfowel3r
Tags: 5.2.1-0ubuntu1
* New upstream security/bugfix release:
  - safe_mode & open_basedir bypasses inside the session extension
    [CVE-2007-0905]
  - multiple buffer overflows in various extensions and functions
    [CVE-2007-0906]
  - underflow in the internal sapi_header_op() function [CVE-2007-0907]
  - information disclosure in the wddx extension [CVE-2007-0908]
  - string format vulnerability in *print() functions on 64 bit systems
    [CVE-2007-0909]
  - possible clobbering of super-globals in several code paths
    [CVE-2007-0910]
* Adapted patches to new upstream release:
  - 006-debian_quirks.patch
  - 034-apache2_umask_fix.patch
  - 044-strtod_arm_fix.patch
* Drop 109-libdb4.4.patch: Obsolete, upstream now checks for db 4.5 and 4.4.
* Drop 114-zend_alloc.c_m68k_alignment.patch and
  115-zend_alloc.c_memleak.patch: Applied upstream.
* Add debian/patches/000upstream-str_ireplace_offbyone.patch:
  - Fix off-by-one in str_ireplace(), a regression introduced in 5.2.1.
  - Patch taken from upstream CVS:
    http://cvs.php.net/viewvc.cgi/php-src/ext/standard/string.c?r1=1.630&r2=1.631
  - CVE-2007-0911
* debian/control: Set Ubuntu maintainer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
   +----------------------------------------------------------------------+
3
3
   | PHP Version 5                                                        |
4
4
   +----------------------------------------------------------------------+
5
 
   | Copyright (c) 1997-2006 The PHP Group                                |
 
5
   | Copyright (c) 1997-2007 The PHP Group                                |
6
6
   +----------------------------------------------------------------------+
7
7
   | This source file is subject to version 3.01 of the PHP license,      |
8
8
   | that is bundled with this package in the file LICENSE, and is        |
17
17
   +----------------------------------------------------------------------+
18
18
 */
19
19
 
20
 
/* $Id: session.c,v 1.417.2.8.2.16 2006/10/06 21:11:36 iliaa Exp $ */
 
20
/* $Id: session.c,v 1.417.2.8.2.26 2007/01/10 07:04:49 dmitry Exp $ */
21
21
 
22
22
#ifdef HAVE_CONFIG_H
23
23
#include "config.h"
153
153
        if (stage == PHP_INI_STAGE_RUNTIME) {
154
154
                char *p;
155
155
 
 
156
                if (memchr(new_value, '\0', new_value_length) != NULL) {
 
157
                        return FAILURE;
 
158
                }
 
159
 
156
160
                if ((p = zend_memrchr(new_value, ';', new_value_length))) {
157
161
                        p++;
158
162
                } else {
159
163
                        p = new_value;
160
164
                }
161
165
 
162
 
                if (PG(safe_mode) && (!php_checkuid(p, NULL, CHECKUID_ALLOW_ONLY_DIR))) {
 
166
                if (PG(safe_mode) && (!php_checkuid(p, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
163
167
                        return FAILURE;
164
168
                }
165
169
 
272
276
 
273
277
static void php_rinit_session_globals(TSRMLS_D);
274
278
static void php_rshutdown_session_globals(TSRMLS_D);
275
 
static zend_bool php_session_destroy(TSRMLS_D);
 
279
static int php_session_destroy(TSRMLS_D);
276
280
 
277
281
zend_module_entry session_module_entry = {
278
282
        STANDARD_MODULE_HEADER,
324
328
        if (PG(register_globals)) {
325
329
                zval **sym_global = NULL;
326
330
                
327
 
                zend_hash_find(&EG(symbol_table), name, namelen + 1, 
328
 
                                (void *) &sym_global);
329
 
                                
 
331
                if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void *) &sym_global) == SUCCESS) {                            
 
332
                        if ((Z_TYPE_PP(sym_global) == IS_ARRAY && Z_ARRVAL_PP(sym_global) == &EG(symbol_table)) || *sym_global == PS(http_session_vars)) {
 
333
                                return;
 
334
                        }
 
335
                }
 
336
 
330
337
                if (sym_global == NULL && sym_track == NULL) {
331
338
                        zval *empty_var;
332
339
 
356
363
        if (PG(register_globals)) {
357
364
                zval **old_symbol;
358
365
                if (zend_hash_find(&EG(symbol_table),name,namelen+1,(void *)&old_symbol) == SUCCESS) { 
359
 
                        
 
366
                        if ((Z_TYPE_PP(old_symbol) == IS_ARRAY && Z_ARRVAL_PP(old_symbol) == &EG(symbol_table)) || *old_symbol == PS(http_session_vars)) {
 
367
                                return;
 
368
                        }
 
369
 
360
370
                        /* 
361
371
                         * A global symbol with the same name exists already. That
362
372
                         * symbol might have been created by other means (e.g. $_GET).
465
475
        PHP_VAR_UNSERIALIZE_INIT(var_hash);
466
476
 
467
477
        for (p = val; p < endptr; ) {
 
478
                zval **tmp;
468
479
                namelen = *p & (~PS_BIN_UNDEF);
 
480
 
 
481
                if (namelen > PS_BIN_MAX || (p + namelen) >= endptr) {
 
482
                        return FAILURE;
 
483
                }
 
484
 
469
485
                has_value = *p & PS_BIN_UNDEF ? 0 : 1;
470
486
 
471
487
                name = estrndup(p + 1, namelen);
472
 
                
 
488
 
473
489
                p += namelen + 1;
474
 
                
 
490
 
 
491
                if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
 
492
                        if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) {
 
493
                                efree(name);
 
494
                                continue;
 
495
                        }
 
496
                }
 
497
 
475
498
                if (has_value) {
476
499
                        ALLOC_INIT_ZVAL(current);
477
500
                        if (php_var_unserialize(&current, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
537
560
        p = val;
538
561
 
539
562
        while (p < endptr) {
 
563
                zval **tmp;
540
564
                q = p;
541
565
                while (*q != PS_DELIMITER)
542
566
                        if (++q >= endptr) goto break_outer_loop;
551
575
                namelen = q - p;
552
576
                name = estrndup(p, namelen);
553
577
                q++;
554
 
                
 
578
 
 
579
                if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
 
580
                        if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) {
 
581
                                goto skip;
 
582
                        }
 
583
                }
 
584
 
555
585
                if (has_value) {
556
586
                        ALLOC_INIT_ZVAL(current);
557
587
                        if (php_var_unserialize(&current, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
558
 
                                php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);
 
588
                                php_set_session_var(name, namelen, current, &var_hash  TSRMLS_CC);
559
589
                        }
560
590
                        zval_ptr_dtor(&current);
561
591
                }
562
592
                PS_ADD_VARL(name, namelen);
 
593
skip:
563
594
                efree(name);
564
 
                
565
595
                p = q;
566
596
        }
567
597
break_outer_loop:
579
609
        zend_delete_global_variable("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS")-1 TSRMLS_CC);
580
610
        zend_delete_global_variable("_SESSION", sizeof("_SESSION")-1 TSRMLS_CC);
581
611
 
 
612
        if (PS(http_session_vars)) {
 
613
                zval_ptr_dtor(&PS(http_session_vars));
 
614
        }
 
615
 
582
616
        MAKE_STD_ZVAL(session_vars);
583
617
        array_init(session_vars);
584
618
        PS(http_session_vars) = session_vars;
585
619
        
586
620
        if (PG(register_long_arrays)) {
587
 
                ZEND_SET_GLOBAL_VAR_WITH_LENGTH("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), PS(http_session_vars), 2, 1);
 
621
                ZEND_SET_GLOBAL_VAR_WITH_LENGTH("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), PS(http_session_vars), 3, 1);
 
622
                ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 3, 1);
 
623
        }
 
624
        else {
588
625
                ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 2, 1);
589
626
        }
590
 
        else {
591
 
                ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 1, 0);
592
 
        }
593
627
}
594
628
 
595
629
static char *php_session_encode(int *newlen TSRMLS_DC)
700
734
        buf = emalloc(100);
701
735
 
702
736
        /* maximum 15+19+19+10 bytes */ 
703
 
        sprintf(buf, "%.15s%ld%ld%0.8f", remote_addr ? remote_addr : "", 
 
737
        sprintf(buf, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", 
704
738
                        tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
705
739
 
706
740
        switch (PS(hash_func)) {
1300
1334
        }
1301
1335
}
1302
1336
 
1303
 
static zend_bool php_session_destroy(TSRMLS_D)
 
1337
static int php_session_destroy(TSRMLS_D)
1304
1338
{
1305
 
        zend_bool retval = SUCCESS;
 
1339
        int retval = SUCCESS;
1306
1340
 
1307
1341
        if (PS(session_status) != php_session_active) {
1308
1342
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to destroy uninitialized session");
1528
1562
        zend_bool del_ses = 0;
1529
1563
 
1530
1564
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
1531
 
                WRONG_PARAM_COUNT;
 
1565
                return;
1532
1566
        }
1533
1567
 
1534
1568
        if (SG(headers_sent)) {
1824
1858
 
1825
1859
static void php_rshutdown_session_globals(TSRMLS_D)
1826
1860
{
 
1861
        if (PS(http_session_vars)) {
 
1862
                zval_ptr_dtor(&PS(http_session_vars));
 
1863
                PS(http_session_vars) = NULL;
 
1864
        }
1827
1865
        if (PS(mod_data)) {
1828
1866
                zend_try {
1829
1867
                        PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);