diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2012-09-26 11:36:32 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2012-09-26 11:36:32 -0400 |
commit | dfe713a1e403e896a8f79f172f970024ad81a3cf (patch) | |
tree | 9ae415642bd1bccb8b28793e985bc26bb81740e4 | |
parent | 1d97425c981cca7de802616668b1891e0cb5e066 (diff) | |
download | longterm-queue-2.6.34-dfe713a1e403e896a8f79f172f970024ad81a3cf.tar.gz |
Add skb and three time patches
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
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 + |