July, 2009

  • Never doubt thy debugger

    Security advisory bulletin 973882 (July 28, 2009)

    • 0 Comments

    My colleague Feliciano has just made me aware of an extraordinary security bulletin we have just released for a new vulnerability discovered in ATL libraries which could allow remote code execution; here are the information I am aware of so far:

    The updates to install:

     

    Carlo

    Quote of the day:
    Those who dream by day are cognizant of many things which escape those who dream only by night. - Edgar Allan Poe
  • Never doubt thy debugger

    ASP.NET 1.1 not configurable in IIS Manager?

    • 0 Comments

    If you search the Internet you’ll likely find a good number of articles and blog posts about how to configure ASP.NET 1.1 on IIS 7, here are a couple of good examples:

    Something I have not found written elsewhere is why it is not possible configure ASP.NET properties from the IIS Manager interface? Even if you correctly configure the application pool (32 bit, Classic pipeline), use the workaround to avoid the error on applicationHost.config, add the IgnoreSectionHandler to avoid ASP.NET 1.1 runtime exceptions due to the not recognized IIS 7 configuration tags and finally the ASP.NET 1.1 pages works fine and are served correctly, you’ll not have the “ASP.NET” icon group in IIS Manager:

    Missing "ASP.NET" tab

    As you can imagine, if you move the application to an application pool where you are running ASP.NET 2.0, the icon group appears where you expect it to be:

    With "ASP.NET" Tab

    Well, it turns out that ASP.NET 1.1 configuration is not supported by InetMgr.exe (the IIS Manager), you have to use appcmd.exe using /commit:machine (for machine.config) or /commit:webroot (for the root web.config) to check if the changes work and they end up where they are supposed to. Note, there are some limitations because of the lack of a complete schema; if you feel brave enough you can create your own custom schema, I do not think (this is my opinion, I do not have an official work on this) that Microsoft will provide such schema. Or if you are even braver you can edit the .config files directly in Notepad, but this sounds like business for real geeks… how much geek do you feel? Nerd smile

     

    Carlo

    Quote of the day:
    The belief in a supernatural source of evil is not necessary; men alone are quite capable of every wickedness. - Joseph Conrad
  • Never doubt thy debugger

    Thread exit may kill your Session

    • 0 Comments

    Every now and then we got a call for an application which, randomly and without a specific pattern or apparent reason, shuts down all user’s sessions. Since ASP.NET 2.0 we can use Web Events to have more information on what is happening at the runtime level and this time the message we had in the event log was pretty clear:

    Event code: 1002
    Event message: Application is shutting down. Reason: Configuration changed.
    Event time: 
    Event time (UTC):
    Event ID: 
    Event sequence:
    Event occurrence: 1
    Event detail code: 

    Application information:
    Application domain: /LM/W3SVC/1045621189/Root-2-1742334186915428
    Trust level: Full
    Application Virtual Path: /
    Application Path: C:\Inetpub\wwwroot\
    Machine name: <machinename>

    Process information:
    Process ID: 1234
    Process name: w3wp.exe
    Account name: NT AUTHORITY\NETWORK SERVICE

    We used Process Monitor to track access to the relevant .config files which are usually the cause for this kind of problem, but with no luck.

    To make a long story short, we had a look at the events around the time when the session was lost and we noticed it usually followed some exception tracking logic the customer had used, so we had a look at the source code and found something interesting: the customer had some code to write and maintain a custom log on a text file and this work was done on a background thread. This code was using the ConfigurationManager class to read some settings from the web.config.

    Now the interesting part: the background thread was executed in a different AppDomain than the ASP.NET application and it needed to initialize this new AppDomain to use the ConfigurationManager; as part of this initialization we create a new File Change Notification object to monitor machine.config and web.config files for changes. When the background thread exited after his job was done, the File Change Notification object encountered this error:

    0x800703E3 ( -2147023901 ) = ERROR_OPERATION_ABORTED
    The I/O operation has been aborted because of either a thread exit or an application request

    Note, that is not an exception; but this change notification event was “head” by all ASP.NET applications which is the expected behavior, and all AppDomains were restarted: the end users were therefore redirected to the login page Nerd smile.

    How do you avoid this situation? Well, we made a small change to the exception handling code to not use ConfigurationManager in the background thread.

     

    Carlo

    Quote of the day:
    When a person can no longer laugh at himself, it is time for others to laugh at him. - Thomas Szasz
  • Never doubt thy debugger

    StackOverflow continued: DataSource or DataSourceID?

    • 0 Comments

    I have already wrote here about a StackOverflowException I recently came across; after a while I got another quite similar problem, still a StackOverflowException with a very long recursion.

    Thread 36 is the one where the exception was thrown:

    0:000> !threads
    ThreadCount: 21
    UnstartedThread: 0
    BackgroundThread: 21
    PendingThread: 0
    DeadThread: 0
    Hosted Runtime: no
    PreEmptive GC Alloc Lock
    ID OSID ThreadOBJ State GC Context Domain Count APT Exception
    17 1 950 000f2580 1808220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Worker)
    27 2 1bfc 00100018 b220 Enabled 00000000:00000000 000eed48 0 MTA (Finalizer)
    28 3 300 00117068 80a220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Completion Port)
    29 4 1cf4 0011a458 1220 Enabled 00000000:00000000 000eed48 0 Ukn
    9 5 ec0 001702e0 220 Enabled 00000000:00000000 000eed48 0 Ukn
    31 6 2414 00171f68 180b220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Worker)
    32 7 1f24 00172338 180b220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Worker)
    33 8 97c 001729e0 180b220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Worker)
    34 9 13bc 00173088 180b220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Worker)
    35 a 22f8 00173a50 180b220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Worker)
    36 b 1e60 00174540 180b220 Disabled 12445a64:124475b8 0011ab48 1 MTA (Threadpool Worker) System.StackOverflowException (1a0a00a4)
    37 c 1c8c 00174cf8 180b220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Worker)
    15 d 1934 0017d040 880a220 Enabled 00000000:00000000 000eed48 0 MTA (Threadpool Completion Port)
    7 e 2028 0017ece8 220 Enabled 00000000:00000000 000eed48 0 Ukn
    8 f dbc 0016f280 220 Enabled 00000000:00000000 000eed48 0 Ukn
    4 10 2298 05007008 220 Enabled 00000000:00000000 000eed48 0 Ukn
    6 11 20c0 05004278 220 Enabled 00000000:00000000 000eed48 0 Ukn
    3 12 c9c 05003b70 220 Enabled 00000000:00000000 000eed48 0 Ukn
    5 13 1a84 04ff7a60 220 Enabled 00000000:00000000 000eed48 0 Ukn
    2 14 253c 0d378ee0 220 Enabled 00000000:00000000 000eed48 0 Ukn
    42 15 1760 0d38b3d8 220 Enabled 00000000:00000000 000eed48 0 Ukn

    Again, here is the managed stack of the thread:

    0:036> !clrstack
    OS Thread Id: 0x1e60 (36)
    ESP EIP
    04e94acc 77e42004 [FaultingExceptionFrame: 04e94acc]
    04e95058 77e42004 [HelperMethodFrame: 04e95058]
    04e950c4 65230cc1 System.Data.RBTree`1+TreePage[[System.__Canon, mscorlib]]..ctor(Int32)
    04e950d4 65230abe System.Data.RBTree`1[[System.__Canon, mscorlib]].AllocPage(Int32)
    04e950f8 652309fc System.Data.RBTree`1[[System.__Canon, mscorlib]].InitTree()
    04e95108 65230961 System.Data.DataRowCollection..ctor(System.Data.DataTable)
    04e95118 652307c2 System.Data.DataTable..ctor()
    04e95134 65230535 System.Data.Common.DataTableMapping.GetDataTableBySchemaAction(System.Data.DataSet, System.Data.MissingSchemaAction)
    04e95150 6523037c System.Data.ProviderBase.SchemaMapping..ctor(System.Data.Common.DataAdapter, System.Data.DataSet, System.Data.DataTable, System.Data.ProviderBase.DataReaderContainer, Boolean, System.Data.SchemaType, System.String, Boolean, System.Data.DataColumn, System.Object)
    04e9519c 6522fbac System.Data.Common.DataAdapter.FillMappingInternal(System.Data.DataSet, System.Data.DataTable, System.String, System.Data.ProviderBase.DataReaderContainer, Int32, System.Data.DataColumn, System.Object)
    04e951d0 6522fc1e System.Data.Common.DataAdapter.FillMapping(System.Data.DataSet, System.Data.DataTable, System.String, System.Data.ProviderBase.DataReaderContainer, Int32, System.Data.DataColumn, System.Object)
    04e95218 6522f9e6 System.Data.Common.DataAdapter.FillFromReader(System.Data.DataSet, System.Data.DataTable, System.String, System.Data.ProviderBase.DataReaderContainer, Int32, Int32, System.Data.DataColumn, System.Object)
    04e95270 6522f942 System.Data.Common.DataAdapter.Fill(System.Data.DataSet, System.String, System.Data.IDataReader, Int32, Int32)
    04e952b4 65230105 System.Data.Common.DbDataAdapter.FillInternal(System.Data.DataSet, System.Data.DataTable[], Int32, Int32, System.String, System.Data.IDbCommand, System.Data.CommandBehavior)
    04e9530c 65230010 System.Data.Common.DbDataAdapter.Fill(System.Data.DataSet, Int32, Int32, System.String, System.Data.IDbCommand, System.Data.CommandBehavior)
    04e95350 6559401d System.Data.Common.DbDataAdapter.Fill(System.Data.DataSet, System.String)
    04e95384 6678d11f System.Web.UI.WebControls.SqlDataSourceView.ExecuteSelect(System.Web.UI.DataSourceSelectArguments)
    04e95424 6668f498 System.Web.UI.DataSourceView.Select(System.Web.UI.DataSourceSelectArguments, System.Web.UI.DataSourceViewSelectCallback)
    04e95434 66792c0f System.Web.UI.WebControls.DataBoundControl.PerformSelect()
    04e9544c 6679285e System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
    04e95458 667dcf35 System.Web.UI.WebControls.GridView.DataBind()
    04e9545c 660e1ac3 System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
    04e95488 668ecdcd System.Web.UI.WebControls.BaseDataBoundControl.set_RequiresDataBinding(Boolean)
    04e95498 667da23b System.Web.UI.WebControls.GridView.set_PageIndex(Int32)
    04e954a8 0ad3e096 ASP.search_aspx.Gridview1_DataBound(System.Object, System.EventArgs)
    04e959a8 667928ce System.Web.UI.WebControls.BaseDataBoundControl.OnDataBound(System.EventArgs)
    04e959bc 66792b45 System.Web.UI.WebControls.DataBoundControl.OnDataSourceViewSelectCallback(System.Collections.IEnumerable)
    04e959cc 6668f4a4 System.Web.UI.DataSourceView.Select(System.Web.UI.DataSourceSelectArguments, System.Web.UI.DataSourceViewSelectCallback)
    04e959dc 66792c0f System.Web.UI.WebControls.DataBoundControl.PerformSelect()
    04e959f4 6679285e System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
    04e95a00 667dcf35 System.Web.UI.WebControls.GridView.DataBind()
    04e95a04 660e1ac3 System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
    04e95a30 668ecdcd System.Web.UI.WebControls.BaseDataBoundControl.set_RequiresDataBinding(Boolean)
    04e95a40 667da23b System.Web.UI.WebControls.GridView.set_PageIndex(Int32)
    04e95a50 0ad3e096 ASP.search_aspx.Gridview1_DataBound(System.Object, System.EventArgs)
    04e95f50 667928ce System.Web.UI.WebControls.BaseDataBoundControl.OnDataBound(System.EventArgs)
    04e95f64 66792b45 System.Web.UI.WebControls.DataBoundControl.OnDataSourceViewSelectCallback(System.Collections.IEnumerable)
    04e95f74 6668f4a4 System.Web.UI.DataSourceView.Select(System.Web.UI.DataSourceSelectArguments, System.Web.UI.DataSourceViewSelectCallback)
    04e95f84 66792c0f System.Web.UI.WebControls.DataBoundControl.PerformSelect()
    04e95f9c 6679285e System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
    04e95fa8 667dcf35 System.Web.UI.WebControls.GridView.DataBind()
    04e95fac 660e1ac3 System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
    04e95fd8 668ecdcd System.Web.UI.WebControls.BaseDataBoundControl.set_RequiresDataBinding(Boolean)
    04e95fe8 667da23b System.Web.UI.WebControls.GridView.set_PageIndex(Int32)
    04e95ff8 0ad3e096 ASP.search_aspx.Gridview1_DataBound(System.Object, System.EventArgs)

    [...]
    04ebea70 0ad3e096 ASP.search_aspx.Gridview1_DataBound(System.Object, System.EventArgs)
    04ebef70 667928ce System.Web.UI.WebControls.BaseDataBoundControl.OnDataBound(System.EventArgs)
    04ebef84 66792b45 System.Web.UI.WebControls.DataBoundControl.OnDataSourceViewSelectCallback(System.Collections.IEnumerable)
    04ebef94 6668f4a4 System.Web.UI.DataSourceView.Select(System.Web.UI.DataSourceSelectArguments, System.Web.UI.DataSourceViewSelectCallback)
    04ebefa4 66792c0f System.Web.UI.WebControls.DataBoundControl.PerformSelect()
    04ebefbc 6679285e System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
    04ebefc8 667dcf35 System.Web.UI.WebControls.GridView.DataBind()
    04ebefcc 660e1ac3 System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
    04ebeff8 660e1a57 System.Web.UI.WebControls.BaseDataBoundControl.OnPreRender(System.EventArgs)
    04ebf008 667e07da System.Web.UI.WebControls.GridView.OnPreRender(System.EventArgs)
    04ebf030 660abc21 System.Web.UI.Control.PreRenderRecursiveInternal()
    04ebf048 660abc7c System.Web.UI.Control.PreRenderRecursiveInternal()
    04ebf060 660abc7c System.Web.UI.Control.PreRenderRecursiveInternal()
    04ebf078 660abc7c System.Web.UI.Control.PreRenderRecursiveInternal()
    04ebf090 660abc7c System.Web.UI.Control.PreRenderRecursiveInternal()
    04ebf0a8 660a7c4b System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
    04ebf200 660a77a4 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
    04ebf238 660a76d1 System.Web.UI.Page.ProcessRequest()
    04ebf270 660a7666 System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)
    04ebf27c 660a7642 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
    04ebf290 0ad37afe ASP.search_aspx.ProcessRequest(System.Web.HttpContext)
    04ebf2a0 660adb16 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
    04ebf2d4 6608132c System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
    04ebf314 6608c5c3 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)
    04ebf364 660808ac System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)
    04ebf380 66083e1c System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)
    04ebf3b4 66083ac3 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)
    04ebf3c4 66082c5c System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32)
    04ebf5d8 79f68cde [ContextTransitionFrame: 04ebf5d8]
    04ebf60c 79f68cde [GCFrame: 04ebf60c]
    04ebf768 79f68cde [ComMethodFrame: 04ebf768]

    After the DataBound event hander is executed, we always call set_PageIndex and go through the binding logic over and over. What does it mean?

    Well, either use Reflector or download the .NET Framework source (or the SSCLI, Shared Source Common Language Infrastructure), if you have a look at the implementation of set_PageIndex you’ll see something like this:

    public virtual void set_PageIndex(int value)
    {
    if (value < 0)
    {
    throw new ArgumentOutOfRangeException("value");
    }
    if (this.PageIndex != value)
    {
    this._pageIndex = value;
    if (base.Initialized)
    {
    base.RequiresDataBinding = true;
    }
    }
    }

    Going deeper we see this:

    protected bool RequiresDataBinding()
    {
    get
    {
    return this._requiresDataBinding;
    }
    set
    {
    if (((value && this._preRendered) && ((this.DataSourceID.Length > 0) && (this.Page != null))) && !this.Page.IsCallback)
    {
    this._requiresDataBinding = true;
    this.EnsureDataBound();
    }
    else
    {
    this._requiresDataBinding = value;
    }
    }
    }






    protected virtual void EnsureDataBound()
    {
    try
    {
    this._throwOnDataPropertyChange = true;
    if (this.RequiresDataBinding && ((this.DataSourceID.Length > 0) || this._requiresBindToNull))
    {
    this.DataBind();
    this._requiresBindToNull = false;
    }
    }
    finally
    {
    this._throwOnDataPropertyChange = false;
    }
    }

    Here is the source code of the faulting page:

    Sub Gridview1_DataBound(ByVal sender As Object, ByVal e As EventArgs)
    Try
    If GridView1.Rows.Count > 0 Then
    Dim pagerRow As GridViewRow = GridView1.BottomPagerRow

    [...]

    Dim CurrentPage As String

    If Request.QueryString("page") <> "" Then
    CurrentPage = Request.QueryString("page")
    Else
    CurrentPage = 1
    End If

    Try
    GridView1.PageIndex = CurrentPage - 1
    Catch
    CurrentPage = 1
    GridView1.PageIndex = CurrentPage - 1
    End Try

    [...]

    End Try
    End Sub

    So, if we change the PageIndex value, under some circumstances we call the DataBind method, the OnDataBound event is fired, the DataBound event hander is executed, PageIndex is changed again and so on until the stack is exhausted.

    Bottom line here is: do not change the PageIndex value inside the DataBound event handler!

    DataSource or DataSourceID?

    One of the conditions to implicitly call DataBind() is to have a value set for DataSourceID:

    protected bool RequiresDataBinding()
    {
    get
    {
    return this._requiresDataBinding;
    }
    set
    {
    if (((value && this._preRendered) && ((this.DataSourceID.Length > 0) && (this.Page != null))) && !this.Page.IsCallback)
    {
    this._requiresDataBinding = true;
    this.EnsureDataBound();
    }
    else
    {
    this._requiresDataBinding = value;
    }
    }
    }

    Honestly I have not tried it (I’ll do and update the post if needed), but I think if we use DataSource rather than DataSourceID we’ll not incur in this problem.

    Carlo

    Quote of the day:
    There is nothing more dreadful than imagination without taste. - Johann Wolfgang von Goethe
  • Never doubt thy debugger

    SharePoint and Office Live? Access forbidden!

    • 0 Comments

    I recently came across an odd problem the customer got on his SharePoint server: when the clients had the Office Live add-on installed they were constantly refused with a 403 error. The problem is well described here.

    If you have this problem, there is a fix for you: 970946.

    If you do not want to install the fix, you might consider to filter the UserAgent string you receive on the server (well, you should filter it before the web request is processed on the server) as one of my customers is testing: if the UserAgent string contains the word “Mozilla” and “Office”* or “non-browser” or “FrontPage”*, just remove the unwanted token.

     

    Carlo

    Quote of the day:
    All things are difficult before they are easy. - Thomas Fuller
Page 1 of 1 (5 items)