summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2012-09-26 11:36:32 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-09-26 11:36:32 -0400
commitdfe713a1e403e896a8f79f172f970024ad81a3cf (patch)
tree9ae415642bd1bccb8b28793e985bc26bb81740e4
parent1d97425c981cca7de802616668b1891e0cb5e066 (diff)
downloadlongterm-queue-2.6.34-dfe713a1e403e896a8f79f172f970024ad81a3cf.tar.gz
Add skb and three time patches
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--queue/net-sock-validate-data_len-before-allocating-skb-in-.patch53
-rw-r--r--queue/series4
-rw-r--r--queue/time-Avoid-making-adjustments-if-we-haven-t-accumula.patch43
-rw-r--r--queue/time-Improve-sanity-checking-of-timekeeping-inputs.patch131
-rw-r--r--queue/time-Move-ktime_t-overflow-checking-into-timespec_va.patch87
5 files changed, 318 insertions, 0 deletions
diff --git a/queue/net-sock-validate-data_len-before-allocating-skb-in-.patch b/queue/net-sock-validate-data_len-before-allocating-skb-in-.patch
new file mode 100644
index 0000000..9d640f9
--- /dev/null
+++ b/queue/net-sock-validate-data_len-before-allocating-skb-in-.patch
@@ -0,0 +1,53 @@
+From 310bef8283723a9db9db4a381b2312b504d7493f Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Wed, 30 May 2012 21:18:10 +0000
+Subject: [PATCH 1/4] net: sock: validate data_len before allocating skb in
+ sock_alloc_send_pskb()
+
+commit cc9b17ad29ecaa20bfe426a8d4dbfb94b13ff1cc upstream.
+
+We need to validate the number of pages consumed by data_len, otherwise frags
+array could be overflowed by userspace. So this patch validate data_len and
+return -EMSGSIZE when data_len may occupies more frags than MAX_SKB_FRAGS.
+
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+---
+ net/core/sock.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 78b7087..4b45ad8 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1425,6 +1425,11 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
+ gfp_t gfp_mask;
+ long timeo;
+ int err;
++ int npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
++
++ err = -EMSGSIZE;
++ if (npages > MAX_SKB_FRAGS)
++ goto failure;
+
+ gfp_mask = sk->sk_allocation;
+ if (gfp_mask & __GFP_WAIT)
+@@ -1443,14 +1448,12 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
+ if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) {
+ skb = alloc_skb(header_len, gfp_mask);
+ if (skb) {
+- int npages;
+ int i;
+
+ /* No pages, we're done... */
+ if (!data_len)
+ break;
+
+- npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ skb->truesize += data_len;
+ skb_shinfo(skb)->nr_frags = npages;
+ for (i = 0; i < npages; i++) {
+--
+1.7.12.rc2
+
diff --git a/queue/series b/queue/series
index e69de29..2d61e0c 100644
--- a/queue/series
+++ b/queue/series
@@ -0,0 +1,4 @@
+net-sock-validate-data_len-before-allocating-skb-in-.patch
+time-Improve-sanity-checking-of-timekeeping-inputs.patch
+time-Avoid-making-adjustments-if-we-haven-t-accumula.patch
+time-Move-ktime_t-overflow-checking-into-timespec_va.patch
diff --git a/queue/time-Avoid-making-adjustments-if-we-haven-t-accumula.patch b/queue/time-Avoid-making-adjustments-if-we-haven-t-accumula.patch
new file mode 100644
index 0000000..e83c190
--- /dev/null
+++ b/queue/time-Avoid-making-adjustments-if-we-haven-t-accumula.patch
@@ -0,0 +1,43 @@
+From 21536f61291ff182274307c2a6d0d13a753b6bfb Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Mon, 17 Sep 2012 21:38:46 -0400
+Subject: [PATCH 3/4] time: Avoid making adjustments if we haven't accumulated
+ anything
+
+commit bf2ac312195155511a0f79325515cbb61929898a upstream.
+
+If update_wall_time() is called and the current offset isn't large
+enough to accumulate, avoid re-calling timekeeping_adjust which may
+change the clock freq and can cause 1ns inconsistencies with
+CLOCK_REALTIME_COARSE/CLOCK_MONOTONIC_COARSE.
+
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Cc: Prarit Bhargava <prarit@redhat.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Link: http://lkml.kernel.org/r/1345595449-34965-5-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Linux Kernel <linux-kernel@vger.kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+---
+ kernel/time/timekeeping.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 0d59077..bbdad71 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -849,6 +849,10 @@ void update_wall_time(void)
+ #else
+ offset = timekeeper.cycle_interval;
+ #endif
++ /* Check if there's really nothing to do */
++ if (offset < timekeeper.cycle_interval)
++ return;
++
+ timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
+
+ /*
+--
+1.7.12.rc2
+
diff --git a/queue/time-Improve-sanity-checking-of-timekeeping-inputs.patch b/queue/time-Improve-sanity-checking-of-timekeeping-inputs.patch
new file mode 100644
index 0000000..2f7afb3
--- /dev/null
+++ b/queue/time-Improve-sanity-checking-of-timekeeping-inputs.patch
@@ -0,0 +1,131 @@
+From 48106cb9c8ec12e9aedf18fb51f0ecf60f2bce30 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Mon, 17 Sep 2012 21:38:45 -0400
+Subject: [PATCH 2/4] time: Improve sanity checking of timekeeping inputs
+
+commit 4e8b14526ca7fb046a81c94002c1c43b6fdf0e9b upstream.
+
+Unexpected behavior could occur if the time is set to a value large
+enough to overflow a 64bit ktime_t (which is something larger then the
+year 2262).
+
+Also unexpected behavior could occur if large negative offsets are
+injected via adjtimex.
+
+So this patch improves the sanity check timekeeping inputs by
+improving the timespec_valid() check, and then makes better use of
+timespec_valid() to make sure we don't set the time to an invalid
+negative value or one that overflows ktime_t.
+
+Note: This does not protect from setting the time close to overflowing
+ktime_t and then letting natural accumulation cause the overflow.
+
+Reported-by: CAI Qian <caiqian@redhat.com>
+Reported-by: Sasha Levin <levinsasha928@gmail.com>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Prarit Bhargava <prarit@redhat.com>
+Cc: Zhouping Liu <zliu@redhat.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Link: http://lkml.kernel.org/r/1344454580-17031-1-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Linux Kernel <linux-kernel@vger.kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+---
+ include/linux/ktime.h | 7 -------
+ include/linux/time.h | 22 ++++++++++++++++++++--
+ kernel/time/timekeeping.c | 15 ++++++++++++++-
+ 3 files changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/ktime.h b/include/linux/ktime.h
+index ce59832..ecdf64e 100644
+--- a/include/linux/ktime.h
++++ b/include/linux/ktime.h
+@@ -58,13 +58,6 @@ union ktime {
+
+ typedef union ktime ktime_t; /* Kill this */
+
+-#define KTIME_MAX ((s64)~((u64)1 << 63))
+-#if (BITS_PER_LONG == 64)
+-# define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
+-#else
+-# define KTIME_SEC_MAX LONG_MAX
+-#endif
+-
+ /*
+ * ktime_t definitions when using the 64-bit scalar representation:
+ */
+diff --git a/include/linux/time.h b/include/linux/time.h
+index 6e026e4..146b6f3 100644
+--- a/include/linux/time.h
++++ b/include/linux/time.h
+@@ -91,11 +91,29 @@ static inline struct timespec timespec_sub(struct timespec lhs,
+ return ts_delta;
+ }
+
++#define KTIME_MAX ((s64)~((u64)1 << 63))
++#if (BITS_PER_LONG == 64)
++# define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
++#else
++# define KTIME_SEC_MAX LONG_MAX
++#endif
++
+ /*
+ * Returns true if the timespec is norm, false if denorm:
+ */
+-#define timespec_valid(ts) \
+- (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
++static inline bool timespec_valid(const struct timespec *ts)
++{
++ /* Dates before 1970 are bogus */
++ if (ts->tv_sec < 0)
++ return false;
++ /* Can't have more nanoseconds then a second */
++ if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
++ return false;
++ /* Disallow values that could overflow ktime_t */
++ if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
++ return false;
++ return true;
++}
+
+ extern struct timespec xtime;
+ extern struct timespec wall_to_monotonic;
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 156fd67..0d59077 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -343,7 +343,7 @@ int do_settimeofday(struct timespec *tv)
+ struct timespec ts_delta;
+ unsigned long flags;
+
+- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
++ if (!timespec_valid(tv))
+ return -EINVAL;
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+@@ -559,7 +559,20 @@ void __init timekeeping_init(void)
+ struct timespec now, boot;
+
+ read_persistent_clock(&now);
++ if (!timespec_valid(&now)) {
++ printk("WARNING: Persistent clock returned invalid value!\n"
++ " Check your CMOS/BIOS settings.\n");
++ now.tv_sec = 0;
++ now.tv_nsec = 0;
++ }
++
+ read_boot_clock(&boot);
++ if (!timespec_valid(&boot)) {
++ printk("WARNING: Boot clock returned invalid value!\n"
++ " Check your CMOS/BIOS settings.\n");
++ boot.tv_sec = 0;
++ boot.tv_nsec = 0;
++ }
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+--
+1.7.12.rc2
+
diff --git a/queue/time-Move-ktime_t-overflow-checking-into-timespec_va.patch b/queue/time-Move-ktime_t-overflow-checking-into-timespec_va.patch
new file mode 100644
index 0000000..4a4fddc
--- /dev/null
+++ b/queue/time-Move-ktime_t-overflow-checking-into-timespec_va.patch
@@ -0,0 +1,87 @@
+From e57b15f6f05b7faf6b9245045d6c452fb4d30726 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Mon, 17 Sep 2012 21:38:47 -0400
+Subject: [PATCH 4/4] time: Move ktime_t overflow checking into
+ timespec_valid_strict
+
+commit cee58483cf56e0ba355fdd97ff5e8925329aa936 upstream.
+
+Andreas Bombe reported that the added ktime_t overflow checking added to
+timespec_valid in commit 4e8b14526ca7 ("time: Improve sanity checking of
+timekeeping inputs") was causing problems with X.org because it caused
+timeouts larger then KTIME_T to be invalid.
+
+Previously, these large timeouts would be clamped to KTIME_MAX and would
+never expire, which is valid.
+
+This patch splits the ktime_t overflow checking into a new
+timespec_valid_strict function, and converts the timekeeping codes
+internal checking to use this more strict function.
+
+Reported-and-tested-by: Andreas Bombe <aeb@debian.org>
+Cc: Zhouping Liu <zliu@redhat.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Prarit Bhargava <prarit@redhat.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Linux Kernel <linux-kernel@vger.kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+---
+ include/linux/time.h | 7 +++++++
+ kernel/time/timekeeping.c | 6 +++---
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/time.h b/include/linux/time.h
+index 146b6f3..bc93987 100644
+--- a/include/linux/time.h
++++ b/include/linux/time.h
+@@ -109,6 +109,13 @@ static inline bool timespec_valid(const struct timespec *ts)
+ /* Can't have more nanoseconds then a second */
+ if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
++ return true;
++}
++
++static inline bool timespec_valid_strict(const struct timespec *ts)
++{
++ if (!timespec_valid(ts))
++ return false;
+ /* Disallow values that could overflow ktime_t */
+ if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
+ return false;
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index bbdad71..21cd75b 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -343,7 +343,7 @@ int do_settimeofday(struct timespec *tv)
+ struct timespec ts_delta;
+ unsigned long flags;
+
+- if (!timespec_valid(tv))
++ if (!timespec_valid_strict(tv))
+ return -EINVAL;
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+@@ -559,7 +559,7 @@ void __init timekeeping_init(void)
+ struct timespec now, boot;
+
+ read_persistent_clock(&now);
+- if (!timespec_valid(&now)) {
++ if (!timespec_valid_strict(&now)) {
+ printk("WARNING: Persistent clock returned invalid value!\n"
+ " Check your CMOS/BIOS settings.\n");
+ now.tv_sec = 0;
+@@ -567,7 +567,7 @@ void __init timekeeping_init(void)
+ }
+
+ read_boot_clock(&boot);
+- if (!timespec_valid(&boot)) {
++ if (!timespec_valid_strict(&boot)) {
+ printk("WARNING: Boot clock returned invalid value!\n"
+ " Check your CMOS/BIOS settings.\n");
+ boot.tv_sec = 0;
+--
+1.7.12.rc2
+