diff options
author | Aravind Srinivasan <raa.aars@gmail.com> | 2009-04-03 03:58:59 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-03 06:05:05 +0400 |
commit | 2c53d9109f077900e140edb8b766132ad93b81cc (patch) | |
tree | 082c063da6c83fe2a2aa84ed0b33c504e19d05f4 | |
parent | edb79a213223488735fae1d408f4c136e9ed25d6 (diff) | |
download | linux-2c53d9109f077900e140edb8b766132ad93b81cc.tar.xz |
relay: fix for possible loss/corruption of produced subbufs
Fix possible loss/corruption of produced subbufs in
relay_subbufs_consumed().
When buf->subbufs_produced wraps around after UINT_MAX and
buf->subbufs_consumed is still < UINT_MAX, the condition
if (buf->subbufs_consumed > buf->subbufs_produced)
will be true even for certain valid values of subbufs_consumed. This may
lead to loss or corruption of produced subbufs.
Signed-off-by: Aravind Srinivasan <raa.aars@gmail.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Tom Zanussi <zanussi@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/relay.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/kernel/relay.c b/kernel/relay.c index 8f2179c8056f..e92db8c06acf 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -797,13 +797,15 @@ void relay_subbufs_consumed(struct rchan *chan, if (!chan) return; - if (cpu >= NR_CPUS || !chan->buf[cpu]) + if (cpu >= NR_CPUS || !chan->buf[cpu] || + subbufs_consumed > chan->n_subbufs) return; buf = chan->buf[cpu]; - buf->subbufs_consumed += subbufs_consumed; - if (buf->subbufs_consumed > buf->subbufs_produced) + if (subbufs_consumed > buf->subbufs_produced - buf->subbufs_consumed) buf->subbufs_consumed = buf->subbufs_produced; + else + buf->subbufs_consumed += subbufs_consumed; } EXPORT_SYMBOL_GPL(relay_subbufs_consumed); |