diff --git a/debian/changelog b/debian/changelog index 5454a097f..1d99e51de 100644 --- a/debian/changelog +++ b/debian/changelog @@ -23,6 +23,15 @@ linux-2.6 (3.2.2-1) UNRELEASED; urgency=low is now built-in (fixes FTBFS) * [armhf] udeb: Include rt2800usb in nic-modules, replacing rt2870sta which was removed from the kernel + * drm: Fix authentication kernel crash + * xfs: Fix missing xfs_iunlock() on error recovery path in xfs_readlink() + * jbd: Issue cache flush after checkpointing + * crypto: sha512 - make it work, undo percpu message schedule + - crypto: sha512 - reduce stack usage to safe number + * [x86] xen: size struct xen_spinlock to always fit in arch_spinlock_t + * l2tp: l2tp_ip - fix possible oops on packet receive + * macvlan: fix a possible use after free + * tcp: fix tcp_trim_head() to adjust segment count with skb MSS [ Thorsten Glaser ] * [m68k] Use gcc-4.6 like (almost) all other architectures diff --git a/debian/patches/bugfix/all/crypto-sha512-make-it-work-undo-percpu-message-schedule.patch b/debian/patches/bugfix/all/crypto-sha512-make-it-work-undo-percpu-message-schedule.patch new file mode 100644 index 000000000..62b7aee5e --- /dev/null +++ b/debian/patches/bugfix/all/crypto-sha512-make-it-work-undo-percpu-message-schedule.patch @@ -0,0 +1,75 @@ +From 84e31fdb7c797a7303e0cc295cb9bc8b73fb872d Mon Sep 17 00:00:00 2001 +From: Alexey Dobriyan +Date: Sat, 14 Jan 2012 21:27:37 +0300 +Subject: crypto: sha512 - make it work, undo percpu message schedule + +From: Alexey Dobriyan + +commit 84e31fdb7c797a7303e0cc295cb9bc8b73fb872d upstream. + +commit f9e2bca6c22d75a289a349f869701214d63b5060 +aka "crypto: sha512 - Move message schedule W[80] to static percpu area" +created global message schedule area. + +If sha512_update will ever be entered twice, hash will be silently +calculated incorrectly. + +Probably the easiest way to notice incorrect hashes being calculated is +to run 2 ping floods over AH with hmac(sha512): + + #!/usr/sbin/setkey -f + flush; + spdflush; + add IP1 IP2 ah 25 -A hmac-sha512 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025; + add IP2 IP1 ah 52 -A hmac-sha512 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052; + spdadd IP1 IP2 any -P out ipsec ah/transport//require; + spdadd IP2 IP1 any -P in ipsec ah/transport//require; + +XfrmInStateProtoError will start ticking with -EBADMSG being returned +from ah_input(). This never happens with, say, hmac(sha1). + +With patch applied (on BOTH sides), XfrmInStateProtoError does not tick +with multiple bidirectional ping flood streams like it doesn't tick +with SHA-1. + +After this patch sha512_transform() will start using ~750 bytes of stack on x86_64. +This is OK for simple loads, for something more heavy, stack reduction will be done +separatedly. + +Signed-off-by: Alexey Dobriyan +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/sha512_generic.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/crypto/sha512_generic.c ++++ b/crypto/sha512_generic.c +@@ -21,8 +21,6 @@ + #include + #include + +-static DEFINE_PER_CPU(u64[80], msg_schedule); +- + static inline u64 Ch(u64 x, u64 y, u64 z) + { + return z ^ (x & (y ^ z)); +@@ -89,7 +87,7 @@ sha512_transform(u64 *state, const u8 *i + u64 a, b, c, d, e, f, g, h, t1, t2; + + int i; +- u64 *W = get_cpu_var(msg_schedule); ++ u64 W[80]; + + /* load the input */ + for (i = 0; i < 16; i++) +@@ -128,8 +126,6 @@ sha512_transform(u64 *state, const u8 *i + + /* erase our data */ + a = b = c = d = e = f = g = h = t1 = t2 = 0; +- memset(W, 0, sizeof(__get_cpu_var(msg_schedule))); +- put_cpu_var(msg_schedule); + } + + static int diff --git a/debian/patches/bugfix/all/crypto-sha512-reduce-stack-usage-to-safe-number.patch b/debian/patches/bugfix/all/crypto-sha512-reduce-stack-usage-to-safe-number.patch new file mode 100644 index 000000000..29b9c3695 --- /dev/null +++ b/debian/patches/bugfix/all/crypto-sha512-reduce-stack-usage-to-safe-number.patch @@ -0,0 +1,127 @@ +From 51fc6dc8f948047364f7d42a4ed89b416c6cc0a3 Mon Sep 17 00:00:00 2001 +From: Alexey Dobriyan +Date: Sat, 14 Jan 2012 21:40:57 +0300 +Subject: crypto: sha512 - reduce stack usage to safe number + +From: Alexey Dobriyan + +commit 51fc6dc8f948047364f7d42a4ed89b416c6cc0a3 upstream. + +For rounds 16--79, W[i] only depends on W[i - 2], W[i - 7], W[i - 15] and W[i - 16]. +Consequently, keeping all W[80] array on stack is unnecessary, +only 16 values are really needed. + +Using W[16] instead of W[80] greatly reduces stack usage +(~750 bytes to ~340 bytes on x86_64). + +Line by line explanation: +* BLEND_OP + array is "circular" now, all indexes have to be modulo 16. + Round number is positive, so remainder operation should be + without surprises. + +* initial full message scheduling is trimmed to first 16 values which + come from data block, the rest is calculated before it's needed. + +* original loop body is unrolled version of new SHA512_0_15 and + SHA512_16_79 macros, unrolling was done to not do explicit variable + renaming. Otherwise it's the very same code after preprocessing. + See sha1_transform() code which does the same trick. + +Patch survives in-tree crypto test and original bugreport test +(ping flood with hmac(sha512). + +See FIPS 180-2 for SHA-512 definition +http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf + +Signed-off-by: Alexey Dobriyan +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/sha512_generic.c | 58 ++++++++++++++++++++++++++++-------------------- + 1 file changed, 34 insertions(+), 24 deletions(-) + +--- a/crypto/sha512_generic.c ++++ b/crypto/sha512_generic.c +@@ -78,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W + + static inline void BLEND_OP(int I, u64 *W) + { +- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; ++ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]); + } + + static void +@@ -87,38 +87,48 @@ sha512_transform(u64 *state, const u8 *i + u64 a, b, c, d, e, f, g, h, t1, t2; + + int i; +- u64 W[80]; ++ u64 W[16]; + + /* load the input */ + for (i = 0; i < 16; i++) + LOAD_OP(i, W, input); + +- for (i = 16; i < 80; i++) { +- BLEND_OP(i, W); +- } +- + /* load the state into our registers */ + a=state[0]; b=state[1]; c=state[2]; d=state[3]; + e=state[4]; f=state[5]; g=state[6]; h=state[7]; + +- /* now iterate */ +- for (i=0; i<80; i+=8) { +- t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ]; +- t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; +- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1]; +- t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; +- t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2]; +- t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; +- t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3]; +- t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; +- t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4]; +- t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; +- t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5]; +- t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; +- t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6]; +- t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; +- t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7]; +- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; ++#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \ ++ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \ ++ t2 = e0(a) + Maj(a, b, c); \ ++ d += t1; \ ++ h = t1 + t2 ++ ++#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \ ++ BLEND_OP(i, W); \ ++ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \ ++ t2 = e0(a) + Maj(a, b, c); \ ++ d += t1; \ ++ h = t1 + t2 ++ ++ for (i = 0; i < 16; i += 8) { ++ SHA512_0_15(i, a, b, c, d, e, f, g, h); ++ SHA512_0_15(i + 1, h, a, b, c, d, e, f, g); ++ SHA512_0_15(i + 2, g, h, a, b, c, d, e, f); ++ SHA512_0_15(i + 3, f, g, h, a, b, c, d, e); ++ SHA512_0_15(i + 4, e, f, g, h, a, b, c, d); ++ SHA512_0_15(i + 5, d, e, f, g, h, a, b, c); ++ SHA512_0_15(i + 6, c, d, e, f, g, h, a, b); ++ SHA512_0_15(i + 7, b, c, d, e, f, g, h, a); ++ } ++ for (i = 16; i < 80; i += 8) { ++ SHA512_16_79(i, a, b, c, d, e, f, g, h); ++ SHA512_16_79(i + 1, h, a, b, c, d, e, f, g); ++ SHA512_16_79(i + 2, g, h, a, b, c, d, e, f); ++ SHA512_16_79(i + 3, f, g, h, a, b, c, d, e); ++ SHA512_16_79(i + 4, e, f, g, h, a, b, c, d); ++ SHA512_16_79(i + 5, d, e, f, g, h, a, b, c); ++ SHA512_16_79(i + 6, c, d, e, f, g, h, a, b); ++ SHA512_16_79(i + 7, b, c, d, e, f, g, h, a); + } + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; diff --git a/debian/patches/bugfix/all/drm-fix-authentication-kernel-crash.patch b/debian/patches/bugfix/all/drm-fix-authentication-kernel-crash.patch new file mode 100644 index 000000000..06a91c817 --- /dev/null +++ b/debian/patches/bugfix/all/drm-fix-authentication-kernel-crash.patch @@ -0,0 +1,85 @@ +From 598781d71119827b454fd75d46f84755bca6f0c6 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Tue, 24 Jan 2012 18:54:21 +0100 +Subject: drm: Fix authentication kernel crash + +From: Thomas Hellstrom + +commit 598781d71119827b454fd75d46f84755bca6f0c6 upstream. + +If the master tries to authenticate a client using drm_authmagic and +that client has already closed its drm file descriptor, +either wilfully or because it was terminated, the +call to drm_authmagic will dereference a stale pointer into kmalloc'ed memory +and corrupt it. + +Typically this results in a hard system hang. + +This patch fixes that problem by removing any authentication tokens +(struct drm_magic_entry) open for a file descriptor when that file +descriptor is closed. + +Signed-off-by: Thomas Hellstrom +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_auth.c | 6 +++++- + drivers/gpu/drm/drm_fops.c | 5 +++++ + include/drm/drmP.h | 1 + + 3 files changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_auth.c ++++ b/drivers/gpu/drm/drm_auth.c +@@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_mast + * Searches and unlinks the entry in drm_device::magiclist with the magic + * number hash key, while holding the drm_device::struct_mutex lock. + */ +-static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) ++int drm_remove_magic(struct drm_master *master, drm_magic_t magic) + { + struct drm_magic_entry *pt; + struct drm_hash_item *hash; +@@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_m + * If there is a magic number in drm_file::magic then use it, otherwise + * searches an unique non-zero magic number and add it associating it with \p + * file_priv. ++ * This ioctl needs protection by the drm_global_mutex, which protects ++ * struct drm_file::magic and struct drm_magic_entry::priv. + */ + int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) + { +@@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev, + * \return zero if authentication successed, or a negative number otherwise. + * + * Checks if \p file_priv is associated with the magic number passed in \arg. ++ * This ioctl needs protection by the drm_global_mutex, which protects ++ * struct drm_file::magic and struct drm_magic_entry::priv. + */ + int drm_authmagic(struct drm_device *dev, void *data, + struct drm_file *file_priv) +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -487,6 +487,11 @@ int drm_release(struct inode *inode, str + (long)old_encode_dev(file_priv->minor->device), + dev->open_count); + ++ /* Release any auth tokens that might point to this file_priv, ++ (do that under the drm_global_mutex) */ ++ if (file_priv->magic) ++ (void) drm_remove_magic(file_priv->master, file_priv->magic); ++ + /* if the master has gone away we can't do anything with the lock */ + if (file_priv->minor->master) + drm_master_release(dev, filp); +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1328,6 +1328,7 @@ extern int drm_getmagic(struct drm_devic + struct drm_file *file_priv); + extern int drm_authmagic(struct drm_device *dev, void *data, + struct drm_file *file_priv); ++extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic); + + /* Cache management (drm_cache.c) */ + void drm_clflush_pages(struct page *pages[], unsigned long num_pages); diff --git a/debian/patches/bugfix/all/jbd-issue-cache-flush-after-checkpointing.patch b/debian/patches/bugfix/all/jbd-issue-cache-flush-after-checkpointing.patch new file mode 100644 index 000000000..a510e645b --- /dev/null +++ b/debian/patches/bugfix/all/jbd-issue-cache-flush-after-checkpointing.patch @@ -0,0 +1,114 @@ +From 353b67d8ced4dc53281c88150ad295e24bc4b4c5 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Sat, 26 Nov 2011 00:35:39 +0100 +Subject: jbd: Issue cache flush after checkpointing + +From: Jan Kara + +commit 353b67d8ced4dc53281c88150ad295e24bc4b4c5 upstream. + +When we reach cleanup_journal_tail(), there is no guarantee that +checkpointed buffers are on a stable storage - especially if buffers were +written out by log_do_checkpoint(), they are likely to be only in disk's +caches. Thus when we update journal superblock, effectively removing old +transaction from journal, this write of superblock can get to stable storage +before those checkpointed buffers which can result in filesystem corruption +after a crash. + +A similar problem can happen if we replay the journal and wipe it before +flushing disk's caches. + +Thus we must unconditionally issue a cache flush before we update journal +superblock in these cases. The fix is slightly complicated by the fact that we +have to get log tail before we issue cache flush but we can store it in the +journal superblock only after the cache flush. Otherwise we risk races where +new tail is written before appropriate cache flush is finished. + +I managed to reproduce the corruption using somewhat tweaked Chris Mason's +barrier-test scheduler. Also this should fix occasional reports of 'Bit already +freed' filesystem errors which are totally unreproducible but inspection of +several fs images I've gathered over time points to a problem like this. + +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd/checkpoint.c | 27 ++++++++++++++++++++++----- + fs/jbd/recovery.c | 4 ++++ + 2 files changed, 26 insertions(+), 5 deletions(-) + +--- a/fs/jbd/checkpoint.c ++++ b/fs/jbd/checkpoint.c +@@ -453,8 +453,6 @@ out: + * + * Return <0 on error, 0 on success, 1 if there was nothing to clean up. + * +- * Called with the journal lock held. +- * + * This is the only part of the journaling code which really needs to be + * aware of transaction aborts. Checkpointing involves writing to the + * main filesystem area rather than to the journal, so it can proceed +@@ -472,13 +470,14 @@ int cleanup_journal_tail(journal_t *jour + if (is_journal_aborted(journal)) + return 1; + +- /* OK, work out the oldest transaction remaining in the log, and ++ /* ++ * OK, work out the oldest transaction remaining in the log, and + * the log block it starts at. + * + * If the log is now empty, we need to work out which is the + * next transaction ID we will write, and where it will +- * start. */ +- ++ * start. ++ */ + spin_lock(&journal->j_state_lock); + spin_lock(&journal->j_list_lock); + transaction = journal->j_checkpoint_transactions; +@@ -504,7 +503,25 @@ int cleanup_journal_tail(journal_t *jour + spin_unlock(&journal->j_state_lock); + return 1; + } ++ spin_unlock(&journal->j_state_lock); ++ ++ /* ++ * We need to make sure that any blocks that were recently written out ++ * --- perhaps by log_do_checkpoint() --- are flushed out before we ++ * drop the transactions from the journal. It's unlikely this will be ++ * necessary, especially with an appropriately sized journal, but we ++ * need this to guarantee correctness. Fortunately ++ * cleanup_journal_tail() doesn't get called all that often. ++ */ ++ if (journal->j_flags & JFS_BARRIER) ++ blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); + ++ spin_lock(&journal->j_state_lock); ++ if (!tid_gt(first_tid, journal->j_tail_sequence)) { ++ spin_unlock(&journal->j_state_lock); ++ /* Someone else cleaned up journal so return 0 */ ++ return 0; ++ } + /* OK, update the superblock to recover the freed space. + * Physical blocks come first: have we wrapped beyond the end of + * the log? */ +--- a/fs/jbd/recovery.c ++++ b/fs/jbd/recovery.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #endif + + /* +@@ -263,6 +264,9 @@ int journal_recover(journal_t *journal) + err2 = sync_blockdev(journal->j_fs_dev); + if (!err) + err = err2; ++ /* Flush disk caches to get replayed data on the permanent storage */ ++ if (journal->j_flags & JFS_BARRIER) ++ blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); + + return err; + } diff --git a/debian/patches/bugfix/all/l2tp-l2tp_ip-fix-possible-oops-on-packet-receive.patch b/debian/patches/bugfix/all/l2tp-l2tp_ip-fix-possible-oops-on-packet-receive.patch new file mode 100644 index 000000000..d4541d90c --- /dev/null +++ b/debian/patches/bugfix/all/l2tp-l2tp_ip-fix-possible-oops-on-packet-receive.patch @@ -0,0 +1,72 @@ +From: James Chapman +Date: Wed, 25 Jan 2012 02:39:05 +0000 +Subject: [PATCH 06/12] l2tp: l2tp_ip - fix possible oops on packet receive + +[ Upstream commit 68315801dbf3ab2001679fd2074c9dc5dcf87dfa ] + +When a packet is received on an L2TP IP socket (L2TPv3 IP link +encapsulation), the l2tpip socket's backlog_rcv function calls +xfrm4_policy_check(). This is not necessary, since it was called +before the skb was added to the backlog. With CONFIG_NET_NS enabled, +xfrm4_policy_check() will oops if skb->dev is null, so this trivial +patch removes the call. + +This bug has always been present, but only when CONFIG_NET_NS is +enabled does it cause problems. Most users are probably using UDP +encapsulation for L2TP, hence the problem has only recently +surfaced. + +EIP: 0060:[] EFLAGS: 00210246 CPU: 0 +EIP is at l2tp_ip_recvmsg+0xd4/0x2a7 +EAX: 00000001 EBX: d77b5180 ECX: 00000000 EDX: 00200246 +ESI: 00000000 EDI: d63cbd30 EBP: d63cbd18 ESP: d63cbcf4 + DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 +Call Trace: + [] sock_common_recvmsg+0x31/0x46 + [] __sock_recvmsg_nosec+0x45/0x4d + [] __sock_recvmsg+0x31/0x3b + [] sock_recvmsg+0x96/0xab + [] ? might_fault+0x47/0x81 + [] ? might_fault+0x47/0x81 + [] ? _copy_from_user+0x31/0x115 + [] ? copy_from_user+0x8/0xa + [] ? verify_iovec+0x3e/0x78 + [] __sys_recvmsg+0x10a/0x1aa + [] ? sock_recvmsg+0x0/0xab + [] ? __lock_acquire+0xbdf/0xbee + [] ? do_page_fault+0x193/0x375 + [] ? fcheck_files+0x9b/0xca + [] ? fget_light+0x2a/0x9c + [] sys_recvmsg+0x2b/0x43 + [] sys_socketcall+0x16d/0x1a5 + [] ? trace_hardirqs_on_thunk+0xc/0x10 + [] sysenter_do_call+0x12/0x38 +Code: c6 05 8c ea a8 c1 01 e8 0c d4 d9 ff 85 f6 74 07 3e ff 86 80 00 00 00 b9 17 b6 2b c1 ba 01 00 00 00 b8 78 ed 48 c1 e8 23 f6 d9 ff 76 0c 68 28 e3 30 c1 68 2d 44 41 c1 e8 89 57 01 00 83 c4 0c + +Signed-off-by: James Chapman +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +--- + net/l2tp/l2tp_ip.c | 5 ----- + 1 files changed, 0 insertions(+), 5 deletions(-) + +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index d21e7eb..55670ec 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -393,11 +393,6 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) + { + int rc; + +- if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) +- goto drop; +- +- nf_reset(skb); +- + /* Charge it to the socket, dropping if the queue is full. */ + rc = sock_queue_rcv_skb(sk, skb); + if (rc < 0) +-- +1.7.7.6 + + diff --git a/debian/patches/bugfix/all/macvlan-fix-a-possible-use-after-free.patch b/debian/patches/bugfix/all/macvlan-fix-a-possible-use-after-free.patch new file mode 100644 index 000000000..fc096e0ff --- /dev/null +++ b/debian/patches/bugfix/all/macvlan-fix-a-possible-use-after-free.patch @@ -0,0 +1,33 @@ +From: Eric Dumazet +Date: Mon, 23 Jan 2012 05:38:59 +0000 +Subject: [PATCH 07/12] macvlan: fix a possible use after free + +[ Upstream commit 4ec7ac1203bcf21f5e3d977c9818b1a56c9ef40d ] + +Commit bc416d9768 (macvlan: handle fragmented multicast frames) added a +possible use after free in macvlan_handle_frame(), since +ip_check_defrag() uses pskb_may_pull() : skb header can be reallocated. + +Signed-off-by: Eric Dumazet +Cc: Ben Greear +Signed-off-by: David S. Miller +--- + drivers/net/macvlan.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 7413497..959d448 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -172,6 +172,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) + skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN); + if (!skb) + return RX_HANDLER_CONSUMED; ++ eth = eth_hdr(skb); + src = macvlan_hash_lookup(port, eth->h_source); + if (!src) + /* frame comes from an external address */ +-- +1.7.7.6 + + diff --git a/debian/patches/bugfix/all/tcp-fix-tcp_trim_head-to-adjust-segment-count-with-skb-MSS.patch b/debian/patches/bugfix/all/tcp-fix-tcp_trim_head-to-adjust-segment-count-with-skb-MSS.patch new file mode 100644 index 000000000..1029f2256 --- /dev/null +++ b/debian/patches/bugfix/all/tcp-fix-tcp_trim_head-to-adjust-segment-count-with-skb-MSS.patch @@ -0,0 +1,57 @@ +From: Neal Cardwell +Date: Sat, 28 Jan 2012 17:29:46 +0000 +Subject: [PATCH 11/12] tcp: fix tcp_trim_head() to adjust segment count + with skb MSS + +[ Upstream commit 5b35e1e6e9ca651e6b291c96d1106043c9af314a ] + +This commit fixes tcp_trim_head() to recalculate the number of +segments in the skb with the skb's existing MSS, so trimming the head +causes the skb segment count to be monotonically non-increasing - it +should stay the same or go down, but not increase. + +Previously tcp_trim_head() used the current MSS of the connection. But +if there was a decrease in MSS between original transmission and ACK +(e.g. due to PMTUD), this could cause tcp_trim_head() to +counter-intuitively increase the segment count when trimming bytes off +the head of an skb. This violated assumptions in tcp_tso_acked() that +tcp_trim_head() only decreases the packet count, so that packets_acked +in tcp_tso_acked() could underflow, leading tcp_clean_rtx_queue() to +pass u32 pkts_acked values as large as 0xffffffff to +ca_ops->pkts_acked(). + +As an aside, if tcp_trim_head() had really wanted the skb to reflect +the current MSS, it should have called tcp_set_skb_tso_segs() +unconditionally, since a decrease in MSS would mean that a +single-packet skb should now be sliced into multiple segments. + +Signed-off-by: Neal Cardwell +Acked-by: Nandita Dukkipati +Acked-by: Ilpo Järvinen +Signed-off-by: David S. Miller +--- + net/ipv4/tcp_output.c | 6 ++---- + 1 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 63170e2..097e0c7 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1138,11 +1138,9 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) + sk_mem_uncharge(sk, len); + sock_set_flag(sk, SOCK_QUEUE_SHRUNK); + +- /* Any change of skb->len requires recalculation of tso +- * factor and mss. +- */ ++ /* Any change of skb->len requires recalculation of tso factor. */ + if (tcp_skb_pcount(skb) > 1) +- tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk)); ++ tcp_set_skb_tso_segs(sk, skb, tcp_skb_mss(skb)); + + return 0; + } +-- +1.7.7.6 + + diff --git a/debian/patches/bugfix/all/x86-xen-size-struct-xen_spinlock-to-always-fit-in-arch_spinlock_t.patch b/debian/patches/bugfix/all/x86-xen-size-struct-xen_spinlock-to-always-fit-in-arch_spinlock_t.patch new file mode 100644 index 000000000..8bd7f1e6f --- /dev/null +++ b/debian/patches/bugfix/all/x86-xen-size-struct-xen_spinlock-to-always-fit-in-arch_spinlock_t.patch @@ -0,0 +1,100 @@ +From 7a7546b377bdaa25ac77f33d9433c59f259b9688 Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Mon, 23 Jan 2012 19:32:25 +0000 +Subject: x86: xen: size struct xen_spinlock to always fit in arch_spinlock_t + +From: David Vrabel + +commit 7a7546b377bdaa25ac77f33d9433c59f259b9688 upstream. + +If NR_CPUS < 256 then arch_spinlock_t is only 16 bits wide but struct +xen_spinlock is 32 bits. When a spin lock is contended and +xl->spinners is modified the two bytes immediately after the spin lock +would be corrupted. + +This is a regression caused by 84eb950db13ca40a0572ce9957e14723500943d6 +(x86, ticketlock: Clean up types and accessors) which reduced the size +of arch_spinlock_t. + +Fix this by making xl->spinners a u8 if NR_CPUS < 256. A +BUILD_BUG_ON() is also added to check the sizes of the two structures +are compatible. + +In many cases this was not noticable as there would often be padding +bytes after the lock (e.g., if any of CONFIG_GENERIC_LOCKBREAK, +CONFIG_DEBUG_SPINLOCK, or CONFIG_DEBUG_LOCK_ALLOC were enabled). + +The bnx2 driver is affected. In struct bnx2, phy_lock and +indirect_lock may have no padding after them. Contention on phy_lock +would corrupt indirect_lock making it appear locked and the driver +would deadlock. + +Signed-off-by: David Vrabel +Signed-off-by: Jeremy Fitzhardinge +Acked-by: Ian Campbell +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/spinlock.c | 27 ++++++++++++++++++++++----- + 1 file changed, 22 insertions(+), 5 deletions(-) + +--- a/arch/x86/xen/spinlock.c ++++ b/arch/x86/xen/spinlock.c +@@ -116,9 +116,26 @@ static inline void spin_time_accum_block + } + #endif /* CONFIG_XEN_DEBUG_FS */ + ++/* ++ * Size struct xen_spinlock so it's the same as arch_spinlock_t. ++ */ ++#if NR_CPUS < 256 ++typedef u8 xen_spinners_t; ++# define inc_spinners(xl) \ ++ asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory"); ++# define dec_spinners(xl) \ ++ asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory"); ++#else ++typedef u16 xen_spinners_t; ++# define inc_spinners(xl) \ ++ asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory"); ++# define dec_spinners(xl) \ ++ asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory"); ++#endif ++ + struct xen_spinlock { + unsigned char lock; /* 0 -> free; 1 -> locked */ +- unsigned short spinners; /* count of waiting cpus */ ++ xen_spinners_t spinners; /* count of waiting cpus */ + }; + + static int xen_spin_is_locked(struct arch_spinlock *lock) +@@ -164,8 +181,7 @@ static inline struct xen_spinlock *spinn + + wmb(); /* set lock of interest before count */ + +- asm(LOCK_PREFIX " incw %0" +- : "+m" (xl->spinners) : : "memory"); ++ inc_spinners(xl); + + return prev; + } +@@ -176,8 +192,7 @@ static inline struct xen_spinlock *spinn + */ + static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev) + { +- asm(LOCK_PREFIX " decw %0" +- : "+m" (xl->spinners) : : "memory"); ++ dec_spinners(xl); + wmb(); /* decrement count before restoring lock */ + __this_cpu_write(lock_spinners, prev); + } +@@ -373,6 +388,8 @@ void xen_uninit_lock_cpu(int cpu) + + void __init xen_init_spinlocks(void) + { ++ BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); ++ + pv_lock_ops.spin_is_locked = xen_spin_is_locked; + pv_lock_ops.spin_is_contended = xen_spin_is_contended; + pv_lock_ops.spin_lock = xen_spin_lock; diff --git a/debian/patches/bugfix/all/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch b/debian/patches/bugfix/all/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch new file mode 100644 index 000000000..cfb4b977e --- /dev/null +++ b/debian/patches/bugfix/all/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch @@ -0,0 +1,35 @@ +From 9b025eb3a89e041bab6698e3858706be2385d692 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 11 Jan 2012 18:52:10 +0000 +Subject: xfs: Fix missing xfs_iunlock() on error recovery path in xfs_readlink() + +From: Jan Kara + +commit 9b025eb3a89e041bab6698e3858706be2385d692 upstream. + +Commit b52a360b forgot to call xfs_iunlock() when it detected corrupted +symplink and bailed out. Fix it by jumping to 'out' instead of doing return. + +CC: Carlos Maiolino +Signed-off-by: Jan Kara +Reviewed-by: Alex Elder +Reviewed-by: Dave Chinner +Signed-off-by: Ben Myers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_vnodeops.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/xfs/xfs_vnodeops.c ++++ b/fs/xfs/xfs_vnodeops.c +@@ -131,7 +131,8 @@ xfs_readlink( + __func__, (unsigned long long) ip->i_ino, + (long long) pathlen); + ASSERT(0); +- return XFS_ERROR(EFSCORRUPTED); ++ error = XFS_ERROR(EFSCORRUPTED); ++ goto out; + } + + diff --git a/debian/patches/series/base b/debian/patches/series/base index f84605a5e..986716613 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -73,3 +73,12 @@ + bugfix/x86/KVM-nVMX-Add-KVM_REQ_IMMEDIATE_EXIT.patch + bugfix/x86/KVM-nVMX-Fix-warning-causing-idt-vectoring-info-beha.patch + bugfix/m68k/m68k-fix-assembler-constraint-to-prevent-overeager-gcc-optimisation.patch ++ bugfix/all/drm-fix-authentication-kernel-crash.patch ++ bugfix/all/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch ++ bugfix/all/jbd-issue-cache-flush-after-checkpointing.patch ++ bugfix/all/crypto-sha512-make-it-work-undo-percpu-message-schedule.patch ++ bugfix/all/crypto-sha512-reduce-stack-usage-to-safe-number.patch ++ bugfix/all/x86-xen-size-struct-xen_spinlock-to-always-fit-in-arch_spinlock_t.patch ++ bugfix/all/l2tp-l2tp_ip-fix-possible-oops-on-packet-receive.patch ++ bugfix/all/macvlan-fix-a-possible-use-after-free.patch ++ bugfix/all/tcp-fix-tcp_trim_head-to-adjust-segment-count-with-skb-MSS.patch