Monday, January 12, 2009

What is a buffer overrun?

Below is an excellent, yet brief, description of buffer overruns, which I found on the Microsoft bloggers feed on http://weblogs.asp.net.

I do a demo of a buffer overrun in the Essentials of Application Security session, one of two I’m presenting at numerous locations in the eastern US.

One of the things I find quite surprising is the relatively high percentage of C++ programmers in the sessions, and even more so, the relatively low percentage of them who’ve actually seen what a buffer overflow looks like.

The fact that it’s so easy to code a buffer overflow makes me very glad that I use managed code. Now all I need to do is make sure that I’m not vulnerable to SQL Injection attacks (use stored procedures and good input validation) or Cross-site Scripting attacks (use good validation, and HTML encode all input before echoing it back to the browser).

 Buffer overrun attack is a very common attack utilized by hackers.  This type of attack is not new.  This attack utilizes poor coding practices in C and C++ code, with the handling of string functions. The following code is an example of a buffer overrun. 

void myMethod(char * pStr) {

    char pBuff[10];

    int nCount = 0;

    strcpy(pBuff, pStr);

}

void foo()

{

}

Cause:

The input pStr is of an unknown size.  The string copy is unsafe.  If the string (pStr) is greater then 10 characters, then the buffer (pBuff) starts to bleed into nCount and the method foo.  The buffer overrun property exploited would allow for the execution of foo by manipulation of the application input.


Solution:

There are three main actions to resolve the problem. 

First is to utilize the /GS compile option.  This option creates a cookie between the stack overrun and the return address.  This allows the system to helps prevent buffer overruns, by changing the stack layout.  

The second action is to use the library.  This library has buffer overrun safe functions that will help with the detection of buffer overflows. 

Finally, the last action is to perform extensive code reviews of string functionality and indexes utilized within your application.









 






The upper limit of open cursors for Microsoft Dynamics has been exceeded (90).-2

We had this issue on our system and the problem was that the user had no security on the database.  Since there was a login failure the process would retry over and over until the cursor limit was reached then the AOS would shutdown.  Once we granted the appropriate security to the user connection everything worked.  Process involved was putting SQL tracing on a table and the user BMSSA did not have rights to do SQL tracing.  Granted this right and everything worked.

The upper limit of open cursors for Microsoft Dynamics has been exceeded (90).-1

The upper limit of open cursors for Microsoft Dynamics has been exceeded (90). Use the -OPENCURSORS parameter, or modify the X++ code. - Bill Thompson [MSFT]
This might help you out. This is for version 3.0, but the concepts are the same for version 4.0: SYMPTOMS When you are working in Microsoft Business Solutions - Axapta 3.0, you may receive the following error message at any time:
Upper limit for open cursors has been exceeded (90) - use parameter openCursors or change the X++ code.
CAUSE This problem may occur because Microsoft Axapta is using more SQL cursors than the default setting of 90. Several factors can cause this condition. These factors may include custom code, uncommitted transactions, or idle connections.
RESOLUTION To resolve this problem, use one or more of the following methods: Method 1: Reduce the time that idle cursors remain open Method 2: Increase the maximum limit of open cursors Method 3: Change the X++ code  Note: Before you follow these steps, test these steps in a testing environment, and back up your data.
Method 1: Reduce the time that idle cursors remain open The open cursors may exceed the limit because idle cursors are not closed. The Timeout connection after being idle setting in the Microsoft Axapta Client Configuration Utility or in the Axapta Object Server (AOS) settings can reduce the time that idle cursors remain open. You can use this method to decrease the seconds before disconnecting idle cursors setting from the default of 60 seconds to less than 30 seconds.  AOS three-tier thin client:
1.  Click Start, click Control Panel, and then click Navision-Axapta Object Server.
2.  In the Axapta Server Manager window, click Settings, and then click the Database tab.
3.  In the Connection category, click Timeout connection after being idle.
4.  In the seconds before disconnecting idle cursors box, enter the time limit that you want. You can make this less than 30 seconds.  Microsoft Axapta two-tier or three-tier rich client
1.  Open the Axapta Configuration Utility.
2.  On the Database tab, click Timeout connection after being idle under the Connection category.
3.  In the seconds before disconnecting idle cursors box, enter the time limit that you want.If you still receive the same error message, you can try increasing the maximum limit of open cursors.  Method 2: Increase the maximum limit of open cursors  By default, the maximum number of open cursors that are allowed is 90. By increasing this setting, the amount of memory that is used will also increase. Therefore, performance may decrease. Increasing the open cursors can mask an underlying code problem. This problem is discussed in Method 3.  Note You can start with 400 maximum open cursors. Then, decrease this amount if you experience performance problems.  AOS three-tier thin client
1.  Click Start, click Control Panel, and then click Navision-Axapta Object Server.
2.  In the Axapta Server Manager window, click Settings, and then click the Database tab.
3.  Under the Settings category, click Max open cursors, and then enter the number that you want.
Microsoft Axapta two-tier or three-tier rich client: 1.  Open the Axapta Configuration Utility. 2.  On the Database tab, click Max open cursors under the Settings category, and then enter the number that you want.
Method 3: Change the X++ code The following code uses nested select statements to generate four cursors.  While select a {      select b where b.f = a.f     select c where c.f = b.f     while select d where d.f=c.f     ...this to 1     ...
A smart join can reduce these four cursors to one to save lots of server trips.
The following sample code can also generate lots of cursors because the cursor reuse does not work in the loop.   for (ordrCnt = 1;ordrCnt <= TPCOrder.O_OL_CNT;ordrCnt++) {      TPCOrderLine.OL_I_ID = tI.getRandomItem();       select firstOnly I_Price, I_Name, I_data from TPCItem // This cannot be reused.                where TPCItem.I_ID == TPCOrderLine.OL_I_ID;      .. }
If the loop is run through 10 times, the program uses 10 cursors for the internal lookup. To resolve this problem, you can change the code to one of the following two examples.
Example 1 for (ordrCnt = 1;ordrCnt <= TPCOrder.O_OL_CNT;ordrCnt++) {       TPCOrderLine.OL_I_ID = tI.getRandomItem();       select firstOnly I_Price, I_Name, I_data from TPCItem // This cannot be reused.                where TPCItem.I_ID == TPCOrderLine.OL_I_ID;       ...       myVariable = TPCItem.myField        // Force/Enable CursorReUse       TPCItem = NULL; } 
In Example 1, the select statement is run by using the cursor, a variable is set, and the table buffer is set to NULL to release the cursor for reuse. When the table buffer is set in this manner, the cursor is released for reuse after the statement has been run. The advantage of writing the code in this manner is that the cursor is released after all data has been processed. Therefore, the cursor should be empty when the cursor is released. Example 2 By setting TPCItem = NULL, you force the cursor to be reused. for (ordrCnt = 1;ordrCnt <= TPCOrder.O_OL_CNT;ordrCnt++) { TPCOrderLine.OL_I_ID = tI.getRandomItem(); // Force/Enable CursorReUse for next loop
    TPCItem = NULL;       select firstOnly I_Price, I_Name, I_data from TPCItem // This cannot be reused.               where TPCItem.I_ID == TPCOrderLine.OL_I_ID; }
In Example 2, the TCPItem table buffer is set to NULL to release the cursor for reuse before the select statement is run. Then, the cursor is consumed by the select statement and is released on the next iteration of the loop.  General X++ code tips If the problem is still not resolved after you review the code examples that are mentioned earlier, examine your code and follow these general tips for working with cursors: Use table joins instead of while select statements.
If you have customizations that query tables in Microsoft Axapta by using X++ code, join the tables in the queries to reduce the need for cursors. Balance the TTSCOMMIT statements.
In nested transactions, when a transaction has been committed, the cursor is released. Make sure that there is a balance between the TTSBEGIN statements and the TTSCOMMIT statements. By using the TTSLEVEL statement, you can receive a count of the current TTSBEGIN statements that are issued to match the TTSCOMMIT statements. Clear the data buffer
Add the following line of code after the TTSCOMMIT statement to clear the buffer. DataBuffer = null
-- Bill 'Luther' Thompson Microsoft Online Support Engineer - MBS Dynamics AX Developer Support

Performance Tuning Axapta

In Axapta, there are a few things that can be used in order to tune for better performance. Before you jump right into performance tuning and tracing in Axapta itself, first you need to take a step back and review the entire picture. You see Axapta, in most cases, is an n-tier (aka: 3-tier) application. There is the Database <-> AOS (Business Logic) <-> Axapta Client (User / Presentation). These are the different major areas of Axapta. There is also two other ways to split this within these major area which are: Software and Hardware. 

My approach to performance tuning and tracing is always start at the ground level, Database layer. Your database most likely is a SQL server v. 2000 (or 2k5 for the lucky ones!). Also hopefully it is running on a PC built to be ran as a Server, with at least 2 GB of RAM, and the Data and Logs seperate on different disks. 

Some things that you can check here are:
- RAM: at least 2GB, I recommend 3GB with AWE turned on.
- CPU: at least 2x 2.4 GHz processors.
- Disk: Seperate Disk arrays for the OS, Data, and Logs. 
*** If you can swing it, put your SQL server on a SAN with at least two clusters Win2k3 nodes, running SQL server as a Virtual Server. 

Now that we have looked into the hardware, next is the software side to SQL server. One of the first things I would check is to make sure the SQL server is nothing But a SQL server. Have it be 100% dedicated to being a SQL server. Next thing I would do is run SQL profiler. Use this to indentify any queries, stored proc. that run to long, that are NON Axapta related. By addressing this first, you take some un forseen issues out of the picture. (please reference: 
SQL Performance Tips for further SQL performance Tips)

Next thing I would do is move on to the AOS server. Here basically the same process, make sure you have enough horse power to give to the AOS. Normally the AOS does not require much, so another big thing that will improve the AOS is making sure the server running it Only runs the AOS and nothing else. This will make sure that the only queued processing items for the CPU is AOS related.

After this, you can check the network between the AOS server, SQL server, and client machines. Between the SQL Server and AOS server a Gigabit ethernet connection would be desired. As for the Client machines LAN at least 100mb ethernet, and WAN no less than 1.54 megabits per second (T1, DSL, etc.) I think at this point a good review of what all you have tested would be recommended. Also make sure to document all your test findings, so that you can use them as bench marks for future fine tuning.

Now that we have looked at everything outside of Axapta, we can move to looking into the code, and application performance. This area there is always improvement, from making sure you have indices created, and you use them, to code profiling, and making sure unneeded database calls are not all over the place. I would recommend starting out here with a SQL trace enabled, to 1000 ms for long queries. Then run a bunch of code, and do some different steps like creating Sales Orders, etc. (note: make sure yo run every single piece of Custom code you can at this point). See if anything pops up, if not, then lower the threshold until things do. If 500 ms is where some of them pop-up I would not worry because most likely you will not get much wiggle room there. Next I would review any code that uses a lot of math, or trips back and forth from the database. Also, try to consolidate code by following true OOP protocols.

Well I hope that I have given enough tips for now when it comes to performance tuning and Axapta. There is still more that you can detail, and each one of the above has details that reach deep down into each section. If there are any sepcific questions please post them in the comments section and I will make sure to answer them on the blog!

Sunday, January 4, 2009

DAX4.0 Partner Productivity Tools Version 2.0 (RCT AX4SP2)

Before you start to install the DAX4.0 PartnerProductivityTools version 2.0 (Rapid Configuration Tool AX4SP2),RCT into your existing environment, make sure that you first: 
  1. Create a new company, called PPT.
  2. Change your AX4 Client Configuration's start up company to 'PPT'.
  3. Create a new label file by using AX label wizard with prefix 'RCT'.

Refer to the below screen shot to have a simple idea on how to configure the RCT.

NOTE:
a) Business Domain 'XXX' = Best practice/Check list of the master setup.
b)Open menu item = Activate the form.
c)Menu item help = Documentation/Explaination of each of the fields appear in the form.
d)Document = Check to see if any powerpoint slides/video available for more explainations.
e)Test XXX = Demo/Test scripts are provided