Search

System.Diagnostics.StopWatch elapsed time affected by user changing computer's date/time by Strilanc

Closed
as Won't Fix Help for as Won't Fix

1
0
Sign in
to vote
Type: Bug
ID: 741848
Opened: 5/12/2012 8:11:05 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
0
Workaround(s)
0
User(s) can reproduce this bug
According to reflector, the System.Diagnostics.StopWatch class uses DateTime.UtcNow when a high resolution timer is not available. This means that a user can control the elapsed time by editing their system time.

This issue makes the stop watch class an insecure method of measuring elapsed time. A user can even make the elapsed time negative, which could trigger serious bugs because developers are unlikely to consider that case!

One potential solution is to fallback to Environment.TickCount instead of DateTime.UtcNow.

This bug may be present in other places in the framework. Anywhere multiple queries to the system time are operated upon.
Details (expand)

Visual Studio/Team Foundation Server/.NET Framework Tooling version

Visual Studio 11 Beta

Steps to reproduce

On a machine without a high resolution timer (i.e. QueryPerformanceFrequency returns false), create a program that periodically displays the elapsed time of a stop watch class. Run the program and then adjust the machine's date to be far in the past.

Product Language

English

Operating System

Windows 7

Operating System Language

English

Actual results

Negative elapsed time displayed.

Expected results

Elapsed time unaffected by editing the system date/time. The stopwatch class should guarantee non-decreasing elapsed time.
File Attachments
0 attachments
Sign in to post a comment.
Posted by Microsoft on 5/15/2012 at 3:50 PM
Hi Strilanc!

Thanks for bringing up this issue. We are always grateful when customers point towards potential concerns - this helps us ensuring the quality of the .NET Framework and driving the product into the right direction.

Indeed, your analysis is correct. Unfortunately, we cannot address this issue in the immediate future.
However, we have logged it and we will continue thinking about addressing issue in a future release.

I thank you for your time and your contribution.

Greg
(Software Engineer on the .NET Base Class Libraries team)
Posted by Microsoft on 5/15/2012 at 3:42 AM
Thanks for your update. We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Strilanc on 5/14/2012 at 7:10 AM
Here is test code. Put it inside the main class of a new C# console project.

The code periodically prints out elapsed time as measured by StopWatch, TickCount, and Date.UtcNow. If you change the date of the test machine then the Date measure will be affected and, if the system doesn't have a high resolution timer, so will the StopWatch measure (this is the bug). To make things easier the code prints out if a high resolution timer is found.

        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern bool QueryPerformanceCounter(out long freq);

        static void Main(string[] args) {
            long x;
            var hasHighRes = QueryPerformanceCounter(out x);
            Console.WriteLine("High res timer available: " + hasHighRes);
            if (hasHighRes) Console.WriteLine("Issue only appears WITHOUT high res timer");

            var s = System.Diagnostics.Stopwatch.StartNew();
            var starttick = Environment.TickCount;
            var startdate = DateTime.UtcNow;
            while (true) {
                System.Threading.Thread.Sleep(1000);
                unchecked {
                    var dtick = (uint)(Environment.TickCount - starttick);
                    var ddate = DateTime.UtcNow - startdate;
                    Console.WriteLine(String.Format(
                        "stopwatch: {0:0.0}s, tickcount: {1:0.0}s, datedif: {2:0.0}s",
                        s.Elapsed.TotalSeconds,
                        dtick/1000.0,
                        ddate.TotalSeconds));
                }
            }
        }
Posted by MS-Moderator10 [Feedback Moderator] on 5/14/2012 at 1:23 AM
Thank you for your feedback. In order to efficiently investigate and reproduce this issue, we are requesting additional information outlined below.

Could you please give us a demo project to demonstrate this issue?

Please submit this information to us within 4 business days. We look forward to hearing from you with this information.

Microsoft Visual Studio Connect Support Team
Posted by MS-Moderator01 on 5/13/2012 at 6:32 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.