From 95f82466aa592f13f76221c98a50a8f40cca9065 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 15 Aug 2005 09:22:29 +0000 Subject: [PATCH] * Added 2.6.12.5 (Simon Horman) - Fix BUG() is triggered by a call to set_mempolicy() with a negativ first argument. - [amd64] Fix a SRAT handling on systems with dual cores. - [amd64] SMP timing problem - [security] Zlib fixes See CAN-2005-2458, CAN-2005-2459 http://sources.redhat.com/ml/bug-gnu-utils/1999-06/msg00183.html http://bugs.gentoo.org/show_bug.cgi - Add zlib deflateBound() - [security] Fix error during session join. See CAN-2005-2098 - [security] Fix keyring destructor. See CAN-2005-2099 - Module per-cpu alignment cannot always be met http://www.ussg.iu.edu/hypermail/linux/kernel/0409.0/0768.html Closes: #323039 svn path=/trunk/kernel/source/linux-2.6/; revision=3878 --- debian/changelog | 25 +- debian/patches-debian/patch-2.6.12.5 | 364 ++++++++++++++++++ .../security-keys-destructor-oops.patch | 55 --- .../security-keys-session-join.patch | 54 --- debian/patches-debian/series/2.6.12-3 | 3 +- 5 files changed, 379 insertions(+), 122 deletions(-) create mode 100644 debian/patches-debian/patch-2.6.12.5 delete mode 100644 debian/patches-debian/security-keys-destructor-oops.patch delete mode 100644 debian/patches-debian/security-keys-session-join.patch diff --git a/debian/changelog b/debian/changelog index 5fc7ec941..00861efe4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -34,19 +34,22 @@ linux-2.6 (2.6.12-3) UNRELEASED; urgency=low toolchain in sid. Many thanks go to GOTO Masanori and Matthias Klose as well as any other who worked on the biarch toolchain to make this happen. - * [security] - security-keys-destructor-oops.patch - Fix keyring destructor - See CAN-2005-2099 (Simon Horman) + * Added 2.6.12.5 (Simon Horman) + - Fix BUG() is triggered by a call to set_mempolicy() with a negativ + first argument. + - [amd64] Fix a SRAT handling on systems with dual cores. + - [amd64] SMP timing problem + - [security] Zlib fixes See CAN-2005-2458, CAN-2005-2459 + http://sources.redhat.com/ml/bug-gnu-utils/1999-06/msg00183.html + http://bugs.gentoo.org/show_bug.cgi + - Add zlib deflateBound() + - [security] Fix error during session join. See CAN-2005-2098 + - [security] Fix keyring destructor. See CAN-2005-2099 + - Module per-cpu alignment cannot always be met + http://www.ussg.iu.edu/hypermail/linux/kernel/0409.0/0768.html Closes: #323039 - * [security] - security-keys-session-join.patch - Fix error during session join - See CAN-2005-2098 (Simon Horman) - Closes: #323039 - - -- Simon Horman Mon, 15 Aug 2005 17:41:42 +0900 + -- Simon Horman Mon, 15 Aug 2005 18:15:51 +0900 linux-2.6 (2.6.12-2) unstable; urgency=low diff --git a/debian/patches-debian/patch-2.6.12.5 b/debian/patches-debian/patch-2.6.12.5 new file mode 100644 index 000000000..fdf4093d3 --- /dev/null +++ b/debian/patches-debian/patch-2.6.12.5 @@ -0,0 +1,364 @@ +diff --git a/Makefile b/Makefile +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + VERSION = 2 + PATCHLEVEL = 6 + SUBLEVEL = 12 +-EXTRAVERSION = .4 ++EXTRAVERSION = .5 + NAME=Woozy Numbat + + # *DOCUMENTATION* +diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c +--- a/arch/ppc64/boot/zlib.c ++++ b/arch/ppc64/boot/zlib.c +@@ -1307,7 +1307,7 @@ local int huft_build( + { + *t = (inflate_huft *)Z_NULL; + *m = 0; +- return Z_OK; ++ return Z_DATA_ERROR; + } + + +@@ -1351,6 +1351,7 @@ local int huft_build( + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); ++ n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ +diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c +--- a/arch/x86_64/kernel/setup.c ++++ b/arch/x86_64/kernel/setup.c +@@ -729,8 +729,6 @@ static void __init amd_detect_cmp(struct + int cpu = smp_processor_id(); + int node = 0; + unsigned bits; +- if (c->x86_num_cores == 1) +- return; + + bits = 0; + while ((1 << bits) < c->x86_num_cores) +diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c +--- a/arch/x86_64/kernel/smp.c ++++ b/arch/x86_64/kernel/smp.c +@@ -284,6 +284,71 @@ struct call_data_struct { + static struct call_data_struct * call_data; + + /* ++ * this function sends a 'generic call function' IPI to one other CPU ++ * in the system. ++ */ ++static void __smp_call_function_single (int cpu, void (*func) (void *info), void *info, ++ int nonatomic, int wait) ++{ ++ struct call_data_struct data; ++ int cpus = 1; ++ ++ data.func = func; ++ data.info = info; ++ atomic_set(&data.started, 0); ++ data.wait = wait; ++ if (wait) ++ atomic_set(&data.finished, 0); ++ ++ call_data = &data; ++ wmb(); ++ /* Send a message to all other CPUs and wait for them to respond */ ++ send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR); ++ ++ /* Wait for response */ ++ while (atomic_read(&data.started) != cpus) ++ cpu_relax(); ++ ++ if (!wait) ++ return; ++ ++ while (atomic_read(&data.finished) != cpus) ++ cpu_relax(); ++} ++ ++/* ++ * Run a function on another CPU ++ * The function to run. This must be fast and non-blocking. ++ * An arbitrary pointer to pass to the function. ++ * Currently unused. ++ * If true, wait until function has completed on other CPUs. ++ * [RETURNS] 0 on success, else a negative status code. ++ * ++ * Does not return until the remote CPU is nearly ready to execute ++ * or is or has executed. ++ */ ++ ++int smp_call_function_single (int cpu, void (*func) (void *info), void *info, ++ int nonatomic, int wait) ++{ ++ ++ int me = get_cpu(); /* prevent preemption and reschedule on another processor */ ++ ++ if (cpu == me) { ++ printk("%s: trying to call self\n", __func__); ++ put_cpu(); ++ return -EBUSY; ++ } ++ spin_lock_bh(&call_lock); ++ ++ __smp_call_function_single(cpu, func,info,nonatomic,wait); ++ ++ spin_unlock_bh(&call_lock); ++ put_cpu(); ++ return 0; ++} ++ ++/* + * this function sends a 'generic call function' IPI to all other CPUs + * in the system. + */ +diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c +--- a/arch/x86_64/kernel/smpboot.c ++++ b/arch/x86_64/kernel/smpboot.c +@@ -202,9 +202,6 @@ static __cpuinit void sync_master(void * + { + unsigned long flags, i; + +- if (smp_processor_id() != boot_cpu_id) +- return; +- + go[MASTER] = 0; + + local_irq_save(flags); +@@ -253,7 +250,7 @@ get_delta(long *rt, long *master) + return tcenter - best_tm; + } + +-static __cpuinit void sync_tsc(void) ++static __cpuinit void sync_tsc(unsigned int master) + { + int i, done = 0; + long delta, adj, adjust_latency = 0; +@@ -267,9 +264,17 @@ static __cpuinit void sync_tsc(void) + } t[NUM_ROUNDS] __cpuinitdata; + #endif + ++ printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", ++ smp_processor_id(), master); ++ + go[MASTER] = 1; + +- smp_call_function(sync_master, NULL, 1, 0); ++ /* It is dangerous to broadcast IPI as cpus are coming up, ++ * as they may not be ready to accept them. So since ++ * we only need to send the ipi to the boot cpu direct ++ * the message, and avoid the race. ++ */ ++ smp_call_function_single(master, sync_master, NULL, 1, 0); + + while (go[MASTER]) /* wait for master to be ready */ + no_cpu_relax(); +@@ -313,16 +318,14 @@ static __cpuinit void sync_tsc(void) + printk(KERN_INFO + "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " + "maxerr %lu cycles)\n", +- smp_processor_id(), boot_cpu_id, delta, rt); ++ smp_processor_id(), master, delta, rt); + } + + static void __cpuinit tsc_sync_wait(void) + { + if (notscsync || !cpu_has_tsc) + return; +- printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(), +- boot_cpu_id); +- sync_tsc(); ++ sync_tsc(0); + } + + static __init int notscsync_setup(char *s) +diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c +--- a/fs/isofs/compress.c ++++ b/fs/isofs/compress.c +@@ -129,8 +129,14 @@ static int zisofs_readpage(struct file * + cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask))); + brelse(bh); + ++ if (cstart > cend) ++ goto eio; ++ + csize = cend-cstart; + ++ if (csize > deflateBound(1UL << zisofs_block_shift)) ++ goto eio; ++ + /* Now page[] contains an array of pages, any of which can be NULL, + and the locks on which we hold. We should now read the data and + release the pages. If the pages are NULL the decompressed data +diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h +--- a/include/asm-x86_64/smp.h ++++ b/include/asm-x86_64/smp.h +@@ -46,6 +46,8 @@ extern int pic_mode; + extern int smp_num_siblings; + extern void smp_flush_tlb(void); + extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); ++extern int smp_call_function_single (int cpuid, void (*func) (void *info), void *info, ++ int retry, int wait); + extern void smp_send_reschedule(int cpu); + extern void smp_invalidate_rcv(void); /* Process an NMI */ + extern void zap_low_mappings(void); +diff --git a/include/linux/zlib.h b/include/linux/zlib.h +--- a/include/linux/zlib.h ++++ b/include/linux/zlib.h +@@ -506,6 +506,11 @@ extern int zlib_deflateReset (z_streamp + stream state was inconsistent (such as zalloc or state being NULL). + */ + ++static inline unsigned long deflateBound(unsigned long s) ++{ ++ return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11; ++} ++ + extern int zlib_deflateParams (z_streamp strm, int level, int strategy); + /* + Dynamically update the compression level and compression strategy. The +diff --git a/kernel/module.c b/kernel/module.c +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -249,13 +249,18 @@ static inline unsigned int block_size(in + /* Created by linker magic */ + extern char __per_cpu_start[], __per_cpu_end[]; + +-static void *percpu_modalloc(unsigned long size, unsigned long align) ++static void *percpu_modalloc(unsigned long size, unsigned long align, ++ const char *name) + { + unsigned long extra; + unsigned int i; + void *ptr; + +- BUG_ON(align > SMP_CACHE_BYTES); ++ if (align > SMP_CACHE_BYTES) { ++ printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n", ++ name, align, SMP_CACHE_BYTES); ++ align = SMP_CACHE_BYTES; ++ } + + ptr = __per_cpu_start; + for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { +@@ -347,7 +352,8 @@ static int percpu_modinit(void) + } + __initcall(percpu_modinit); + #else /* ... !CONFIG_SMP */ +-static inline void *percpu_modalloc(unsigned long size, unsigned long align) ++static inline void *percpu_modalloc(unsigned long size, unsigned long align, ++ const char *name) + { + return NULL; + } +@@ -1554,7 +1560,8 @@ static struct module *load_module(void _ + if (pcpuindex) { + /* We have a special allocation for this section. */ + percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, +- sechdrs[pcpuindex].sh_addralign); ++ sechdrs[pcpuindex].sh_addralign, ++ mod->name); + if (!percpu) { + err = -ENOMEM; + goto free_mod; +diff --git a/lib/inflate.c b/lib/inflate.c +--- a/lib/inflate.c ++++ b/lib/inflate.c +@@ -326,7 +326,7 @@ DEBG("huft1 "); + { + *t = (struct huft *)NULL; + *m = 0; +- return 0; ++ return 2; + } + + DEBG("huft2 "); +@@ -374,6 +374,7 @@ DEBG("huft5 "); + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); ++ n = x[g]; /* set n to length of v */ + + DEBG("h6 "); + +@@ -410,12 +411,13 @@ DEBG1("1 "); + DEBG1("2 "); + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; +- while (++j < z) /* try smaller tables up to z bits */ +- { +- if ((f <<= 1) <= *++xp) +- break; /* enough codes to use up j bits */ +- f -= *xp; /* else deduct codes from patterns */ +- } ++ if (j < z) ++ while (++j < z) /* try smaller tables up to z bits */ ++ { ++ if ((f <<= 1) <= *++xp) ++ break; /* enough codes to use up j bits */ ++ f -= *xp; /* else deduct codes from patterns */ ++ } + } + DEBG1("3 "); + z = 1 << j; /* table entries for j-bit table */ +diff --git a/lib/zlib_inflate/inftrees.c b/lib/zlib_inflate/inftrees.c +--- a/lib/zlib_inflate/inftrees.c ++++ b/lib/zlib_inflate/inftrees.c +@@ -141,7 +141,7 @@ static int huft_build( + { + *t = NULL; + *m = 0; +- return Z_OK; ++ return Z_DATA_ERROR; + } + + +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -409,7 +409,7 @@ asmlinkage long sys_set_mempolicy(int mo + struct mempolicy *new; + DECLARE_BITMAP(nodes, MAX_NUMNODES); + +- if (mode > MPOL_MAX) ++ if (mode < 0 || mode > MPOL_MAX) + return -EINVAL; + err = get_nodes(nodes, nmask, maxnode, mode); + if (err) +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -188,7 +188,11 @@ static void keyring_destroy(struct key * + + if (keyring->description) { + write_lock(&keyring_name_lock); +- list_del(&keyring->type_data.link); ++ ++ if (keyring->type_data.link.next != NULL && ++ !list_empty(&keyring->type_data.link)) ++ list_del(&keyring->type_data.link); ++ + write_unlock(&keyring_name_lock); + } + +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -641,7 +641,7 @@ long join_session_keyring(const char *na + keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); + if (IS_ERR(keyring)) { + ret = PTR_ERR(keyring); +- goto error; ++ goto error2; + } + } + else if (IS_ERR(keyring)) { +- +To unsubscribe from this list: send the line "unsubscribe linux-kernel-announce" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/debian/patches-debian/security-keys-destructor-oops.patch b/debian/patches-debian/security-keys-destructor-oops.patch deleted file mode 100644 index 45abea317..000000000 --- a/debian/patches-debian/security-keys-destructor-oops.patch +++ /dev/null @@ -1,55 +0,0 @@ -commit 94efe72f762e2c147d8146d637d5ece5614c8d94 -tree 002e4719541ad838342e01a5f8ff63ae0a618b29 -parent bcf945d36fa0598f41ac4ad46a9dc43135460263 -author David Howells 1123186027 -0700 -committer Linus Torvalds 1123186274 -0700 - -[PATCH] Destruction of failed keyring oopses - -The attached patch makes sure that a keyring that failed to instantiate -properly is destroyed without oopsing [CAN-2005-2099]. - -The problem occurs in three stages: - - (1) The key allocator initialises the type-specific data to all zeroes. In - the case of a keyring, this will become a link in the keyring name list - when the keyring is instantiated. - - (2) If a user (any user) attempts to add a keyring with anything other than - an empty payload, the keyring instantiation function will fail with an - error and won't add the keyring to the name list. - - (3) The keyring's destructor then sees that the keyring has a description - (name) and tries to remove the keyring from the name list, which oopses - because the link pointers are both zero. - -This bug permits any user to take down a box trivially. - -Signed-Off-By: David Howells -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds - -I:100644 100644 a1f6bac647a1c3a673bfbb2b4b03d0556cc9be88 9c208c756df8136cbaa0a06f5442af60c712ae6d M security/keys/keyring.c - -Key: -S: Skipped -I: Included Included verbatim -D: Deleted Manually deleted by subsequent user edit -R: Revised Manually revised by subsequent user edit - -diff --git a/security/keys/keyring.c b/security/keys/keyring.c ---- a/security/keys/keyring.c -+++ b/security/keys/keyring.c -@@ -201,7 +201,11 @@ static void keyring_destroy(struct key * - - if (keyring->description) { - write_lock(&keyring_name_lock); -- list_del(&keyring->type_data.link); -+ -+ if (keyring->type_data.link.next != NULL && -+ !list_empty(&keyring->type_data.link)) -+ list_del(&keyring->type_data.link); -+ - write_unlock(&keyring_name_lock); - } - diff --git a/debian/patches-debian/security-keys-session-join.patch b/debian/patches-debian/security-keys-session-join.patch deleted file mode 100644 index 9ea00539e..000000000 --- a/debian/patches-debian/security-keys-session-join.patch +++ /dev/null @@ -1,54 +0,0 @@ -commit bcf945d36fa0598f41ac4ad46a9dc43135460263 -tree 7a2aa188442bf863f20055a001baf85143d7a5b9 -parent 6fb0caa42308923d9e4ed7b36ec077b97c107e24 -author David Howells 1123186026 -0700 -committer Linus Torvalds 1123186274 -0700 - -[PATCH] Error during attempt to join key management session can leave semaphore pinned - -The attached patch prevents an error during the key session joining operation -from hanging future joins in the D state [CAN-2005-2098]. - -The problem is that the error handling path for the KEYCTL_JOIN_SESSION_KEYRING -operation has one error path that doesn't release the session management -semaphore. Further attempts to get the semaphore will then sleep for ever in -the D state. - -This can happen in four situations, all involving an attempt to allocate a new -session keyring: - - (1) ENOMEM. - - (2) The users key quota being reached. - - (3) A keyring name that is an empty string. - - (4) A keyring name that is too long. - -Any user may attempt this operation, and so any user can cause the problem to -occur. - -Signed-Off-By: David Howells -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds - -I:100644 100644 9b0369c5a223acbf951178e87ebbb0789458b507 c089f78fb94ec170dbd042f08a4a61b9915c526e M security/keys/process_keys.c - -Key: -S: Skipped -I: Included Included verbatim -D: Deleted Manually deleted by subsequent user edit -R: Revised Manually revised by subsequent user edit - -diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c ---- a/security/keys/process_keys.c -+++ b/security/keys/process_keys.c -@@ -678,7 +678,7 @@ long join_session_keyring(const char *na - keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); - if (IS_ERR(keyring)) { - ret = PTR_ERR(keyring); -- goto error; -+ goto error2; - } - } - else if (IS_ERR(keyring)) { diff --git a/debian/patches-debian/series/2.6.12-3 b/debian/patches-debian/series/2.6.12-3 index 85966b128..cbbfd4a33 100644 --- a/debian/patches-debian/series/2.6.12-3 +++ b/debian/patches-debian/series/2.6.12-3 @@ -1,2 +1 @@ -+ security-keys-destructor-oops.patch -+ security-keys-session-join.patch ++ patch-2.6.12.5