mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Henry Cejtin <henry@sourcelight.com>
To: linux-kernel@vger.kernel.org
Subject: race in getrusage()
Date: Tue, 17 Jul 2001 00:35:35 -0500	[thread overview]
Message-ID: <200107170535.f6H5ZZt20785@syzygy.sourcelight.com> (raw)

Sorry for sending this bug report out to this broad an audience, but there is
an old bug in getrusage() (it  has  been  there  since  at  least  2.2.5  and
probably way before that and is still in 2.4.6).  Depending on the cleverness
of the C compiler, when you do
    getrusage(RUSAGE_SELF, &rbuf)
you can get one of the following:

    A rbuf.ru_stime which is 1 second too small.  (In  particular,  1  second
        smaller than you got from a previous call in the same process.)
    rbuf.ru_stime.tv_usec = 10^6 (i.e., larger than should be possible).

The  bug  is  caused  by  the  fact  that in kernel/sys.c, in the getrusage()
function, the p->times.tms_stime might change  while  the  code  is  running.
Since  it  isn't marked as being volatile, if the compiler optimizes the code
by  subtracting  the  r.ru_stime.tv_sec  *  HZ  from   a   second   load   of
p->times.tms_stime  then  you  get the r.ru_stime.tv_usec set to 10^6.  If it
reloads p->times.tms_stime then you get the lost second.  I  have  seen  both
behaviors,  depending  on the compiler being used.  In particular, the kernel
distributed with Red Hat 7.1 shows the lost second phenomenon, and  the  10^6
value for ru_stime.tv_usec on Red Hat 6.0's kernel.

The fix is to just load p->times.tms_stime into a local variable and then use
the local copy for setting both the tv_sec and tv_usec fields of  r.ru_stime.

Only  r.ru_stime  is  vulnerable since the process is in a system call at the
time.

Note, to force the compiler to  actually  fetch  p->times.tms_stime,  and  to
fetch it only once, requires something like this:
    clock_t tmp;

    tmp = *(volatile clock_t *)&p->times.tms_stime;
    r.ru_utime.tv_sec = CT_TO_SECS(tmp);
    r.ru_utime.tv_usec = CT_TO_USECS(tmp);
otherwise  the  compiler is quite free to ignore the load and to simply fetch
p->times.tms_stime twice.

                 reply	other threads:[~2001-07-17  5:36 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200107170535.f6H5ZZt20785@syzygy.sourcelight.com \
    --to=henry@sourcelight.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®