static PHP_FUNCTION(session_set_save_handler)
{
	zval ***args = NULL;
	int i, num_args, argc = ZEND_NUM_ARGS();
	char *name;

	if (PS(session_status) != php_session_none) {
		RETURN_FALSE;
	}

	if (argc > 0 && argc <= 2) {
		zval *obj = NULL, *callback = NULL;
		zend_uint func_name_len;
		char *func_name;
		HashPosition pos;
		zend_function *default_mptr, *current_mptr;
		ulong func_index;
		php_shutdown_function_entry shutdown_function_entry;
		zend_bool register_shutdown = 1;

		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &obj, php_session_iface_entry, &register_shutdown) == FAILURE) {
			RETURN_FALSE;
		}

		/* Find implemented methods - SessionHandlerInterface */
		zend_hash_internal_pointer_reset_ex(&php_session_iface_entry->function_table, &pos);
		i = 0;
		while (zend_hash_get_current_data_ex(&php_session_iface_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
			zend_hash_get_current_key_ex(&php_session_iface_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);

			if (zend_hash_find(&Z_OBJCE_P(obj)->function_table, func_name, func_name_len, (void **)&current_mptr) == SUCCESS) {
				if (PS(mod_user_names).names[i] != NULL) {
					zval_ptr_dtor(&PS(mod_user_names).names[i]);
				}

				MAKE_STD_ZVAL(callback);
				array_init_size(callback, 2);
				Z_ADDREF_P(obj);
				add_next_index_zval(callback, obj);
				add_next_index_stringl(callback, func_name, func_name_len - 1, 1);
				PS(mod_user_names).names[i] = callback;
			} else {
				php_error_docref(NULL TSRMLS_CC, E_ERROR, "Session handler's function table is corrupt");
				RETURN_FALSE;
			}

			zend_hash_move_forward_ex(&php_session_iface_entry->function_table, &pos);
			++i;
		}

		/* Find implemented methods - SessionIdInterface (optional) */
		zend_hash_internal_pointer_reset_ex(&php_session_id_iface_entry->function_table, &pos);
		while (zend_hash_get_current_data_ex(&php_session_id_iface_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
			zend_hash_get_current_key_ex(&php_session_id_iface_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);

			if (zend_hash_find(&Z_OBJCE_P(obj)->function_table, func_name, func_name_len, (void **)&current_mptr) == SUCCESS) {
				if (PS(mod_user_names).names[i] != NULL) {
					zval_ptr_dtor(&PS(mod_user_names).names[i]);
				}

				MAKE_STD_ZVAL(callback);
				array_init_size(callback, 2);
				Z_ADDREF_P(obj);
				add_next_index_zval(callback, obj);
				add_next_index_stringl(callback, func_name, func_name_len - 1, 1);
				PS(mod_user_names).names[i] = callback;
			}

			zend_hash_move_forward_ex(&php_session_id_iface_entry->function_table, &pos);
			++i;
		}

		if (register_shutdown) {
			/* create shutdown function */
			shutdown_function_entry.arg_count = 1;
			shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), 1, 0);

			MAKE_STD_ZVAL(callback);
			ZVAL_STRING(callback, "session_register_shutdown", 1);
			shutdown_function_entry.arguments[0] = callback;

			/* add shutdown function, removing the old one if it exists */
			if (!register_user_shutdown_function("session_shutdown", sizeof("session_shutdown"), &shutdown_function_entry TSRMLS_CC)) {
				zval_ptr_dtor(&callback);
				efree(shutdown_function_entry.arguments);
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to register session shutdown function");
				RETURN_FALSE;
			}
		} else {
			/* remove shutdown function */
			remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") TSRMLS_CC);
		}

		if (PS(mod) && PS(session_status) == php_session_none && PS(mod) != &ps_mod_user) {
			zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
		}

		RETURN_TRUE;
	}

	if (argc != 6 && argc != 7) {
		WRONG_PARAM_COUNT;
	}

	if (zend_parse_parameters(argc TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
		return;
	}

	/* remove shutdown function */
	remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") TSRMLS_CC);

	/* at this point argc can only be 6 or 7 */
	for (i = 0; i < argc; i++) {
		if (!zend_is_callable(*args[i], 0, &name TSRMLS_CC)) {
			efree(args);
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
			efree(name);
			RETURN_FALSE;
		}
		efree(name);
	}

	if (PS(mod) && PS(mod) != &ps_mod_user) {
		zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
	}

	for (i = 0; i < argc; i++) {
		if (PS(mod_user_names).names[i] != NULL) {
			zval_ptr_dtor(&PS(mod_user_names).names[i]);
		}
		Z_ADDREF_PP(args[i]);
		PS(mod_user_names).names[i] = *args[i];
	}

	efree(args);
	RETURN_TRUE;
}

The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory belongs to the code that operates on the new pointer.