diff options
-rw-r--r-- | 2.6.32/0000_README | 8 | ||||
-rw-r--r-- | 2.6.32/1036_linux-2.6.32.37.patch | 2592 | ||||
-rw-r--r-- | 2.6.32/1037_linux-2.6.32.38.patch | 19 | ||||
-rw-r--r-- | 2.6.32/4425_grsec-pax-without-grsec.patch | 6 |
4 files changed, 2622 insertions, 3 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README index 6bfec0c..70319a3 100644 --- a/2.6.32/0000_README +++ b/2.6.32/0000_README @@ -3,6 +3,14 @@ README Individual Patch Descriptions: ----------------------------------------------------------------------------- +Patch: 1036_linux-2.6.32.37.patch +From: http://www.kernel.org +Desc: Linux 2.6.32.37 + +Patch: 1037_linux-2.6.32.38.patch +From: http://www.kernel.org +Desc: Linux 2.6.32.38 + Patch: 4420_grsecurity-2.2.2-2.6.32.38-201104191737.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/2.6.32/1036_linux-2.6.32.37.patch b/2.6.32/1036_linux-2.6.32.37.patch new file mode 100644 index 0000000..c2d8bf9 --- /dev/null +++ b/2.6.32/1036_linux-2.6.32.37.patch @@ -0,0 +1,2592 @@ +diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c +index fe02e71..5009198 100644 +--- a/arch/powerpc/kernel/crash.c ++++ b/arch/powerpc/kernel/crash.c +@@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu) + } + + /* wait for all the CPUs to hit real mode but timeout if they don't come in */ ++#ifdef CONFIG_PPC_STD_MMU_64 + static void crash_kexec_wait_realmode(int cpu) + { + unsigned int msecs; +@@ -187,6 +188,7 @@ static void crash_kexec_wait_realmode(int cpu) + } + mb(); + } ++#endif + + /* + * This function will be called by secondary cpus or by kexec cpu +@@ -445,7 +447,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs) + crash_kexec_prepare_cpus(crashing_cpu); + cpu_set(crashing_cpu, cpus_in_crash); + crash_kexec_stop_spus(); ++#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) + crash_kexec_wait_realmode(crashing_cpu); ++#endif + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(1, 0); + } +diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c +index 419e328..fd60f09 100644 +--- a/arch/x86/kernel/cpu/mtrr/main.c ++++ b/arch/x86/kernel/cpu/mtrr/main.c +@@ -262,14 +262,24 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ + + /* + * HACK! +- * We use this same function to initialize the mtrrs on boot. +- * The state of the boot cpu's mtrrs has been saved, and we want +- * to replicate across all the APs. +- * If we're doing that @reg is set to something special... ++ * ++ * We use this same function to initialize the mtrrs during boot, ++ * resume, runtime cpu online and on an explicit request to set a ++ * specific MTRR. ++ * ++ * During boot or suspend, the state of the boot cpu's mtrrs has been ++ * saved, and we want to replicate that across all the cpus that come ++ * online (either at the end of boot or resume or during a runtime cpu ++ * online). If we're doing that, @reg is set to something special and on ++ * this cpu we still do mtrr_if->set_all(). During boot/resume, this ++ * is unnecessary if at this point we are still on the cpu that started ++ * the boot/resume sequence. But there is no guarantee that we are still ++ * on the same cpu. So we do mtrr_if->set_all() on this cpu aswell to be ++ * sure that we are in sync with everyone else. + */ + if (reg != ~0U) + mtrr_if->set(reg, base, size, type); +- else if (!mtrr_aps_delayed_init) ++ else + mtrr_if->set_all(); + + /* Wait for the others */ +diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c +index 0b08160..0b06cd7 100644 +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -76,6 +76,9 @@ void __init x86_64_start_kernel(char * real_mode_data) + /* Make NULL pointers segfault */ + zap_identity_mappings(); + ++ /* Cleanup the over mapped high alias */ ++ cleanup_highmap(); ++ + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) { + #ifdef CONFIG_EARLY_PRINTK + set_intr_gate(i, &early_idt_handlers[i]); +diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c +index f4c538b..1e47679 100644 +--- a/arch/x86/kernel/microcode_amd.c ++++ b/arch/x86/kernel/microcode_amd.c +@@ -63,7 +63,6 @@ struct microcode_amd { + unsigned int mpb[0]; + }; + +-#define UCODE_MAX_SIZE 2048 + #define UCODE_CONTAINER_SECTION_HDR 8 + #define UCODE_CONTAINER_HEADER_SIZE 12 + +@@ -109,12 +108,8 @@ static int get_matching_microcode(int cpu, void *mc, int rev) + return 0; + } + +- if (mc_header->processor_rev_id != equiv_cpu_id) { +- printk(KERN_ERR "microcode: CPU%d: patch mismatch " +- "(processor_rev_id: %x, equiv_cpu_id: %x)\n", +- cpu, mc_header->processor_rev_id, equiv_cpu_id); ++ if (mc_header->processor_rev_id != equiv_cpu_id) + return 0; +- } + + /* ucode might be chipset specific -- currently we don't support this */ + if (mc_header->nb_dev_id || mc_header->sb_dev_id) { +@@ -129,6 +124,37 @@ static int get_matching_microcode(int cpu, void *mc, int rev) + return 1; + } + ++static unsigned int verify_ucode_size(int cpu, const u8 *buf, unsigned int size) ++{ ++ struct cpuinfo_x86 *c = &cpu_data(cpu); ++ unsigned int max_size, actual_size; ++ ++#define F1XH_MPB_MAX_SIZE 2048 ++#define F14H_MPB_MAX_SIZE 1824 ++#define F15H_MPB_MAX_SIZE 4096 ++ ++ switch (c->x86) { ++ case 0x14: ++ max_size = F14H_MPB_MAX_SIZE; ++ break; ++ case 0x15: ++ max_size = F15H_MPB_MAX_SIZE; ++ break; ++ default: ++ max_size = F1XH_MPB_MAX_SIZE; ++ break; ++ } ++ ++ actual_size = buf[4] + (buf[5] << 8); ++ ++ if (actual_size > size || actual_size > max_size) { ++ pr_err("section size mismatch\n"); ++ return 0; ++ } ++ ++ return actual_size; ++} ++ + static int apply_microcode_amd(int cpu) + { + u32 rev, dummy; +@@ -168,11 +194,11 @@ static int get_ucode_data(void *to, const u8 *from, size_t n) + } + + static void * +-get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size) ++get_next_ucode(int cpu, const u8 *buf, unsigned int size, unsigned int *mc_size) + { +- unsigned int total_size; ++ unsigned int actual_size = 0; + u8 section_hdr[UCODE_CONTAINER_SECTION_HDR]; +- void *mc; ++ void *mc = NULL; + + if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR)) + return NULL; +@@ -183,26 +209,18 @@ get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size) + return NULL; + } + +- total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); +- +- printk(KERN_DEBUG "microcode: size %u, total_size %u\n", +- size, total_size); ++ actual_size = verify_ucode_size(cpu, buf, size); ++ if (!actual_size) ++ return NULL; + +- if (total_size > size || total_size > UCODE_MAX_SIZE) { +- printk(KERN_ERR "microcode: error: size mismatch\n"); ++ mc = vmalloc(actual_size); ++ if (!mc) + return NULL; +- } + +- mc = vmalloc(UCODE_MAX_SIZE); +- if (mc) { +- memset(mc, 0, UCODE_MAX_SIZE); +- if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, +- total_size)) { +- vfree(mc); +- mc = NULL; +- } else +- *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR; +- } ++ memset(mc, 0, actual_size); ++ get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, actual_size); ++ *mc_size = actual_size + UCODE_CONTAINER_SECTION_HDR; ++ + return mc; + } + +@@ -271,7 +289,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) + unsigned int uninitialized_var(mc_size); + struct microcode_header_amd *mc_header; + +- mc = get_next_ucode(ucode_ptr, leftover, &mc_size); ++ mc = get_next_ucode(cpu, ucode_ptr, leftover, &mc_size); + if (!mc) + break; + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 76358ee..5449a26 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -294,9 +294,6 @@ static void __init init_gbpages(void) + static inline void init_gbpages(void) + { + } +-static void __init cleanup_highmap(void) +-{ +-} + #endif + + static void __init reserve_brk(void) +@@ -924,8 +921,6 @@ void __init setup_arch(char **cmdline_p) + + reserve_brk(); + +- cleanup_highmap(); +- + init_gbpages(); + + /* max_pfn_mapped is updated here */ +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 6bce215..73ffd55 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -287,6 +287,25 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, + load_cr3(swapper_pg_dir); + #endif + ++#ifdef CONFIG_X86_64 ++ if (!after_bootmem && !start) { ++ pud_t *pud; ++ pmd_t *pmd; ++ ++ mmu_cr4_features = read_cr4(); ++ ++ /* ++ * _brk_end cannot change anymore, but it and _end may be ++ * located on different 2M pages. cleanup_highmap(), however, ++ * can only consider _end when it runs, so destroy any ++ * mappings beyond _brk_end here. ++ */ ++ pud = pud_offset(pgd_offset_k(_brk_end), _brk_end); ++ pmd = pmd_offset(pud, _brk_end - 1); ++ while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1)) ++ pmd_clear(pmd); ++ } ++#endif + __flush_tlb_all(); + + if (!after_bootmem && e820_table_end > e820_table_start) +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index 1584023..7d095ad 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -49,7 +49,6 @@ + #include <asm/numa.h> + #include <asm/cacheflush.h> + #include <asm/init.h> +-#include <asm/setup.h> + #include <linux/bootmem.h> + + static unsigned long dma_reserve __initdata; +@@ -258,18 +257,18 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size) + * to the compile time generated pmds. This results in invalid pmds up + * to the point where we hit the physaddr 0 mapping. + * +- * We limit the mappings to the region from _text to _brk_end. _brk_end +- * is rounded up to the 2MB boundary. This catches the invalid pmds as ++ * We limit the mappings to the region from _text to _end. _end is ++ * rounded up to the 2MB boundary. This catches the invalid pmds as + * well, as they are located before _text: + */ + void __init cleanup_highmap(void) + { + unsigned long vaddr = __START_KERNEL_map; +- unsigned long vaddr_end = __START_KERNEL_map + (max_pfn_mapped << PAGE_SHIFT); +- unsigned long end = roundup((unsigned long)_brk_end, PMD_SIZE) - 1; ++ unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1; + pmd_t *pmd = level2_kernel_pgt; ++ pmd_t *last_pmd = pmd + PTRS_PER_PMD; + +- for (; vaddr + PMD_SIZE - 1 < vaddr_end; pmd++, vaddr += PMD_SIZE) { ++ for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) { + if (pmd_none(*pmd)) + continue; + if (vaddr < (unsigned long) _text || vaddr > end) +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index a73f102..84c93ff 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -688,7 +688,7 @@ void solos_bh(unsigned long card_arg) + size); + } + if (atmdebug) { +- dev_info(&card->dev->dev, "Received: device %d\n", port); ++ dev_info(&card->dev->dev, "Received: port %d\n", port); + dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n", + size, le16_to_cpu(header->vpi), + le16_to_cpu(header->vci)); +@@ -1008,8 +1008,15 @@ static uint32_t fpga_tx(struct solos_card *card) + + /* Clean up and free oldskb now it's gone */ + if (atmdebug) { ++ struct pkt_hdr *header = (void *)oldskb->data; ++ int size = le16_to_cpu(header->size); ++ ++ skb_pull(oldskb, sizeof(*header)); + dev_info(&card->dev->dev, "Transmitted: port %d\n", + port); ++ dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n", ++ size, le16_to_cpu(header->vpi), ++ le16_to_cpu(header->vci)); + print_buffer(oldskb); + } + +diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h +index 31524cf..5ae1b1c 100644 +--- a/drivers/block/cciss.h ++++ b/drivers/block/cciss.h +@@ -165,6 +165,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) + printk("Sending %x - down to controller\n", c->busaddr ); + #endif /* CCISS_DEBUG */ + writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); ++ readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); + h->commands_outstanding++; + if ( h->commands_outstanding > h->max_outstanding) + h->max_outstanding = h->commands_outstanding; +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 0e9c564..c12d0fb 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -62,6 +62,9 @@ static struct usb_device_id btusb_table[] = { + /* Apple iMac11,1 */ + { USB_DEVICE(0x05ac, 0x8215) }, + ++ /* Apple MacBookPro8,2 */ ++ { USB_DEVICE(0x05ac, 0x821a) }, ++ + /* AVM BlueFRITZ! USB v2.0 */ + { USB_DEVICE(0x057c, 0x3800) }, + +diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c +index 8548ae7..edd7b7f 100644 +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -969,7 +969,7 @@ int tpm_open(struct inode *inode, struct file *file) + return -EBUSY; + } + +- chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); ++ chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); + if (chip->data_buffer == NULL) { + clear_bit(0, &chip->is_open); + put_device(chip->dev); +diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c +index 6134810..78e3e85 100644 +--- a/drivers/mfd/ab3100-core.c ++++ b/drivers/mfd/ab3100-core.c +@@ -591,7 +591,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100) + ab3100_get_priv.ab3100 = ab3100; + ab3100_get_priv.mode = false; + ab3100_get_reg_file = debugfs_create_file("get_reg", +- S_IWUGO, ab3100_dir, &ab3100_get_priv, ++ S_IWUSR, ab3100_dir, &ab3100_get_priv, + &ab3100_get_set_reg_fops); + if (!ab3100_get_reg_file) { + err = -ENOMEM; +@@ -601,7 +601,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100) + ab3100_set_priv.ab3100 = ab3100; + ab3100_set_priv.mode = true; + ab3100_set_reg_file = debugfs_create_file("set_reg", +- S_IWUGO, ab3100_dir, &ab3100_set_priv, ++ S_IWUSR, ab3100_dir, &ab3100_set_priv, + &ab3100_get_set_reg_fops); + if (!ab3100_set_reg_file) { + err = -ENOMEM; +diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c +index ba46941..3f9a0ab 100644 +--- a/drivers/misc/ep93xx_pwm.c ++++ b/drivers/misc/ep93xx_pwm.c +@@ -248,11 +248,11 @@ static ssize_t ep93xx_pwm_set_invert(struct device *dev, + + static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL); + static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL); +-static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO, ++static DEVICE_ATTR(freq, S_IWUSR | S_IRUGO, + ep93xx_pwm_get_freq, ep93xx_pwm_set_freq); +-static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO, ++static DEVICE_ATTR(duty_percent, S_IWUSR | S_IRUGO, + ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent); +-static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO, ++static DEVICE_ATTR(invert, S_IWUSR | S_IRUGO, + ep93xx_pwm_get_invert, ep93xx_pwm_set_invert); + + static struct attribute *ep93xx_pwm_attrs[] = { +diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c +index f362451..b8dc2d1 100644 +--- a/drivers/net/myri10ge/myri10ge.c ++++ b/drivers/net/myri10ge/myri10ge.c +@@ -3640,6 +3640,7 @@ static void myri10ge_free_slices(struct myri10ge_priv *mgp) + dma_free_coherent(&pdev->dev, bytes, + ss->fw_stats, ss->fw_stats_bus); + ss->fw_stats = NULL; ++ netif_napi_del(&ss->napi); + } + } + kfree(mgp->ss); +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index 0c349ce..54e716a 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1918,6 +1918,8 @@ static int ath9k_start(struct ieee80211_hw *hw) + DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " + "initial channel: %d MHz\n", curchan->center_freq); + ++ ath9k_ps_wakeup(sc); ++ + mutex_lock(&sc->mutex); + + if (ath9k_wiphy_started(sc)) { +@@ -2025,6 +2027,8 @@ static int ath9k_start(struct ieee80211_hw *hw) + mutex_unlock: + mutex_unlock(&sc->mutex); + ++ ath9k_ps_restore(sc); ++ + return r; + } + +diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c +index 571d475..8bf4bbd 100644 +--- a/drivers/net/wireless/b43/dma.c ++++ b/drivers/net/wireless/b43/dma.c +@@ -1521,7 +1521,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) + dmaaddr = meta->dmaaddr; + goto drop_recycle_buffer; + } +- if (unlikely(len > ring->rx_buffersize)) { ++ if (unlikely(len + ring->frameoffset > ring->rx_buffersize)) { + /* The data did not fit into one descriptor buffer + * and is split over multiple buffers. + * This should never happen, as we try to allocate buffers +diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h +index f0b0838..ceee7a3 100644 +--- a/drivers/net/wireless/b43/dma.h ++++ b/drivers/net/wireless/b43/dma.h +@@ -163,7 +163,7 @@ struct b43_dmadesc_generic { + /* DMA engine tuning knobs */ + #define B43_TXRING_SLOTS 256 + #define B43_RXRING_SLOTS 64 +-#define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN ++#define B43_DMA0_RX_BUFFERSIZE (B43_DMA0_RX_FRAMEOFFSET + IEEE80211_MAX_FRAME_LEN) + + + struct sk_buff; +diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c +index 0a2bf5c..54c3a9d 100644 +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -54,6 +54,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { + {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ + {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ + {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ ++ {USB_DEVICE(0x0bf8, 0x1007)}, /* Fujitsu E-5400 USB */ + {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ + {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */ + {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ +@@ -66,6 +67,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { + {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ + {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ + {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */ ++ {USB_DEVICE(0x2001, 0x3762)}, /* Conceptronic C54U */ + {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */ + {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ + +diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c +index 0b6b773..21c2181 100644 +--- a/drivers/rtc/rtc-ds1511.c ++++ b/drivers/rtc/rtc-ds1511.c +@@ -480,7 +480,7 @@ ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr, + static struct bin_attribute ds1511_nvram_attr = { + .attr = { + .name = "nvram", +- .mode = S_IRUGO | S_IWUGO, ++ .mode = S_IRUGO | S_IWUSR, + }, + .size = DS1511_RAM_MAX, + .read = ds1511_nvram_read, +diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c +index 3c8a024..3b082dd 100644 +--- a/drivers/scsi/ses.c ++++ b/drivers/scsi/ses.c +@@ -389,9 +389,9 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, + len = (desc_ptr[2] << 8) + desc_ptr[3]; + /* skip past overall descriptor */ + desc_ptr += len + 4; +- if (ses_dev->page10) +- addl_desc_ptr = ses_dev->page10 + 8; + } ++ if (ses_dev->page10) ++ addl_desc_ptr = ses_dev->page10 + 8; + type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; + components = 0; + for (i = 0; i < types; i++, type_ptr += 4) { +diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c +index 746370e..366dc95 100644 +--- a/drivers/staging/hv/Channel.c ++++ b/drivers/staging/hv/Channel.c +@@ -75,14 +75,14 @@ static void VmbusChannelSetEvent(struct vmbus_channel *Channel) + + if (Channel->OfferMsg.MonitorAllocated) { + /* Each u32 represents 32 channels */ +- set_bit(Channel->OfferMsg.ChildRelId & 31, ++ sync_set_bit(Channel->OfferMsg.ChildRelId & 31, + (unsigned long *) gVmbusConnection.SendInterruptPage + + (Channel->OfferMsg.ChildRelId >> 5)); + + monitorPage = gVmbusConnection.MonitorPages; + monitorPage++; /* Get the child to parent monitor page */ + +- set_bit(Channel->MonitorBit, ++ sync_set_bit(Channel->MonitorBit, + (unsigned long *)&monitorPage->TriggerGroup + [Channel->MonitorGroup].Pending); + +@@ -102,7 +102,7 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) + + if (Channel->OfferMsg.MonitorAllocated) { + /* Each u32 represents 32 channels */ +- clear_bit(Channel->OfferMsg.ChildRelId & 31, ++ sync_clear_bit(Channel->OfferMsg.ChildRelId & 31, + (unsigned long *)gVmbusConnection.SendInterruptPage + + (Channel->OfferMsg.ChildRelId >> 5)); + +@@ -110,7 +110,7 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) + (struct hv_monitor_page *)gVmbusConnection.MonitorPages; + monitorPage++; /* Get the child to parent monitor page */ + +- clear_bit(Channel->MonitorBit, ++ sync_clear_bit(Channel->MonitorBit, + (unsigned long *)&monitorPage->TriggerGroup + [Channel->MonitorGroup].Pending); + } +diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c +index 43c2e68..c8d073a 100644 +--- a/drivers/staging/hv/Connection.c ++++ b/drivers/staging/hv/Connection.c +@@ -284,7 +284,9 @@ void VmbusOnEvents(void) + for (dword = 0; dword < maxdword; dword++) { + if (recvInterruptPage[dword]) { + for (bit = 0; bit < 32; bit++) { +- if (test_and_clear_bit(bit, (unsigned long *)&recvInterruptPage[dword])) { ++ if (sync_test_and_clear_bit(bit, ++ (unsigned long *) ++ &recvInterruptPage[dword])) { + relid = (dword << 5) + bit; + DPRINT_DBG(VMBUS, "event detected for relid - %d", relid); + +@@ -329,7 +331,7 @@ int VmbusSetEvent(u32 childRelId) + DPRINT_ENTER(VMBUS); + + /* Each u32 represents 32 channels */ +- set_bit(childRelId & 31, ++ sync_set_bit(childRelId & 31, + (unsigned long *)gVmbusConnection.SendInterruptPage + + (childRelId >> 5)); + +diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c +index 35a023e..2a4ba03 100644 +--- a/drivers/staging/hv/Vmbus.c ++++ b/drivers/staging/hv/Vmbus.c +@@ -254,7 +254,7 @@ static int VmbusOnISR(struct hv_driver *drv) + event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; + + /* Since we are a child, we only need to check bit 0 */ +- if (test_and_clear_bit(0, (unsigned long *) &event->Flags32[0])) { ++ if (sync_test_and_clear_bit(0, (unsigned long *) &event->Flags32[0])) { + DPRINT_DBG(VMBUS, "received event %d", event->Flags32[0]); + ret |= 0x2; + } +diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h +index 05ad2c9..5a37cce 100644 +--- a/drivers/staging/hv/VmbusPrivate.h ++++ b/drivers/staging/hv/VmbusPrivate.h +@@ -32,6 +32,7 @@ + #include "ChannelInterface.h" + #include "RingBuffer.h" + #include <linux/list.h> ++#include <asm/sync_bitops.h> + + + /* +diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c +index a5101e3..44d8d6f 100644 +--- a/drivers/staging/hv/netvsc_drv.c ++++ b/drivers/staging/hv/netvsc_drv.c +@@ -44,6 +44,7 @@ struct net_device_context { + /* point back to our device context */ + struct device_context *device_ctx; + struct net_device_stats stats; ++ struct work_struct work; + }; + + struct netvsc_driver_context { +@@ -284,6 +285,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, + { + struct device_context *device_ctx = to_device_context(device_obj); + struct net_device *net = dev_get_drvdata(&device_ctx->device); ++ struct net_device_context *ndev_ctx; + + DPRINT_ENTER(NETVSC_DRV); + +@@ -297,6 +299,8 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, + netif_carrier_on(net); + netif_wake_queue(net); + netif_notify_peers(net); ++ ndev_ctx = netdev_priv(net); ++ schedule_work(&ndev_ctx->work); + } else { + netif_carrier_off(net); + netif_stop_queue(net); +@@ -398,6 +402,25 @@ static const struct net_device_ops device_ops = { + .ndo_set_mac_address = eth_mac_addr, + }; + ++/* ++ * Send GARP packet to network peers after migrations. ++ * After Quick Migration, the network is not immediately operational in the ++ * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add ++ * another netif_notify_peers() into a scheduled work, otherwise GARP packet ++ * will not be sent after quick migration, and cause network disconnection. ++ */ ++static void netvsc_send_garp(struct work_struct *w) ++{ ++ struct net_device_context *ndev_ctx; ++ struct net_device *net; ++ ++ msleep(20); ++ ndev_ctx = container_of(w, struct net_device_context, work); ++ net = dev_get_drvdata(&ndev_ctx->device_ctx->device); ++ netif_notify_peers(net); ++} ++ ++ + static int netvsc_probe(struct device *device) + { + struct driver_context *driver_ctx = +@@ -428,6 +451,7 @@ static int netvsc_probe(struct device *device) + net_device_ctx = netdev_priv(net); + net_device_ctx->device_ctx = device_ctx; + dev_set_drvdata(device, net); ++ INIT_WORK(&net_device_ctx->work, netvsc_send_garp); + + /* Notify the netvsc driver of the new device */ + ret = net_drv_obj->Base.OnDeviceAdd(device_obj, &device_info); +diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c +index 815fb7c..a9cdc4c 100644 +--- a/drivers/staging/usbip/stub_rx.c ++++ b/drivers/staging/usbip/stub_rx.c +@@ -168,33 +168,23 @@ static int tweak_set_configuration_cmd(struct urb *urb) + + static int tweak_reset_device_cmd(struct urb *urb) + { +- struct usb_ctrlrequest *req; +- __u16 value; +- __u16 index; +- int ret; +- +- req = (struct usb_ctrlrequest *) urb->setup_packet; +- value = le16_to_cpu(req->wValue); +- index = le16_to_cpu(req->wIndex); +- +- usbip_uinfo("reset_device (port %d) to %s\n", index, +- dev_name(&urb->dev->dev)); ++ struct stub_priv *priv = (struct stub_priv *) urb->context; ++ struct stub_device *sdev = priv->sdev; + +- /* all interfaces should be owned by usbip driver, so just reset it. */ +- ret = usb_lock_device_for_reset(urb->dev, NULL); +- if (ret < 0) { +- dev_err(&urb->dev->dev, "lock for reset\n"); +- return ret; +- } +- +- /* try to reset the device */ +- ret = usb_reset_device(urb->dev); +- if (ret < 0) +- dev_err(&urb->dev->dev, "device reset\n"); ++ usbip_uinfo("reset_device %s\n", dev_name(&urb->dev->dev)); + +- usb_unlock_device(urb->dev); +- +- return ret; ++ /* ++ * usb_lock_device_for_reset caused a deadlock: it causes the driver ++ * to unbind. In the shutdown the rx thread is signalled to shut down ++ * but this thread is pending in the usb_lock_device_for_reset. ++ * ++ * Instead queue the reset. ++ * ++ * Unfortunatly an existing usbip connection will be dropped due to ++ * driver unbinding. ++ */ ++ usb_queue_reset_device(sdev->interface); ++ return 0; + } + + /* +diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c +index e2ab4f3..523d7ff 100644 +--- a/drivers/staging/usbip/stub_tx.c ++++ b/drivers/staging/usbip/stub_tx.c +@@ -167,7 +167,6 @@ static int stub_send_ret_submit(struct stub_device *sdev) + struct stub_priv *priv, *tmp; + + struct msghdr msg; +- struct kvec iov[3]; + size_t txsize; + + size_t total_size = 0; +@@ -177,28 +176,73 @@ static int stub_send_ret_submit(struct stub_device *sdev) + struct urb *urb = priv->urb; + struct usbip_header pdu_header; + void *iso_buffer = NULL; ++ struct kvec *iov = NULL; ++ int iovnum = 0; + + txsize = 0; + memset(&pdu_header, 0, sizeof(pdu_header)); + memset(&msg, 0, sizeof(msg)); +- memset(&iov, 0, sizeof(iov)); + +- usbip_dbg_stub_tx("setup txdata urb %p\n", urb); ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ++ iovnum = 2 + urb->number_of_packets; ++ else ++ iovnum = 2; ++ ++ iov = kzalloc(iovnum * sizeof(struct kvec), GFP_KERNEL); + ++ if (!iov) { ++ usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC); ++ return -1; ++ } ++ ++ iovnum = 0; + + /* 1. setup usbip_header */ + setup_ret_submit_pdu(&pdu_header, urb); ++ usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", ++ pdu_header.base.seqnum, urb); ++ /*usbip_dump_header(pdu_header);*/ + usbip_header_correct_endian(&pdu_header, 1); + +- iov[0].iov_base = &pdu_header; +- iov[0].iov_len = sizeof(pdu_header); ++ iov[iovnum].iov_base = &pdu_header; ++ iov[iovnum].iov_len = sizeof(pdu_header); ++ iovnum++; + txsize += sizeof(pdu_header); + + /* 2. setup transfer buffer */ +- if (usb_pipein(urb->pipe) && urb->actual_length > 0) { +- iov[1].iov_base = urb->transfer_buffer; +- iov[1].iov_len = urb->actual_length; ++ if (usb_pipein(urb->pipe) && ++ usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS && ++ urb->actual_length > 0) { ++ iov[iovnum].iov_base = urb->transfer_buffer; ++ iov[iovnum].iov_len = urb->actual_length; ++ iovnum++; + txsize += urb->actual_length; ++ } else if (usb_pipein(urb->pipe) && ++ usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ /* ++ * For isochronous packets: actual length is the sum of ++ * the actual length of the individual, packets, but as ++ * the packet offsets are not changed there will be ++ * padding between the packets. To optimally use the ++ * bandwidth the padding is not transmitted. ++ */ ++ ++ int i; ++ for (i = 0; i < urb->number_of_packets; i++) { ++ iov[iovnum].iov_base = urb->transfer_buffer + urb->iso_frame_desc[i].offset; ++ iov[iovnum].iov_len = urb->iso_frame_desc[i].actual_length; ++ iovnum++; ++ txsize += urb->iso_frame_desc[i].actual_length; ++ } ++ ++ if (txsize != sizeof(pdu_header) + urb->actual_length) { ++ dev_err(&sdev->interface->dev, ++ "actual length of urb (%d) does not match iso packet sizes (%d)\n", ++ urb->actual_length, txsize-sizeof(pdu_header)); ++ kfree(iov); ++ usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); ++ return -1; ++ } + } + + /* 3. setup iso_packet_descriptor */ +@@ -209,32 +253,34 @@ static int stub_send_ret_submit(struct stub_device *sdev) + if (!iso_buffer) { + usbip_event_add(&sdev->ud, + SDEV_EVENT_ERROR_MALLOC); ++ kfree(iov); + return -1; + } + +- iov[2].iov_base = iso_buffer; +- iov[2].iov_len = len; ++ iov[iovnum].iov_base = iso_buffer; ++ iov[iovnum].iov_len = len; + txsize += len; ++ iovnum++; + } + +- ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, +- 3, txsize); ++ ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, ++ iov, iovnum, txsize); + if (ret != txsize) { + dev_err(&sdev->interface->dev, + "sendmsg failed!, retval %d for %zd\n", + ret, txsize); ++ kfree(iov); + kfree(iso_buffer); + usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); + return -1; + } + ++ kfree(iov); + kfree(iso_buffer); +- usbip_dbg_stub_tx("send txdata\n"); + + total_size += txsize; + } + +- + spin_lock_irqsave(&sdev->priv_lock, flags); + + list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) { +diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c +index ddb6f5f..719e0c1 100644 +--- a/drivers/staging/usbip/usbip_common.c ++++ b/drivers/staging/usbip/usbip_common.c +@@ -361,10 +361,11 @@ void usbip_dump_header(struct usbip_header *pdu) + usbip_udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum); + break; + case USBIP_RET_SUBMIT: +- usbip_udbg("RET_SUBMIT: st %d al %u sf %d ec %d\n", ++ usbip_udbg("RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n", + pdu->u.ret_submit.status, + pdu->u.ret_submit.actual_length, + pdu->u.ret_submit.start_frame, ++ pdu->u.ret_submit.number_of_packets, + pdu->u.ret_submit.error_count); + case USBIP_RET_UNLINK: + usbip_udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status); +@@ -686,6 +687,7 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, + rpdu->status = urb->status; + rpdu->actual_length = urb->actual_length; + rpdu->start_frame = urb->start_frame; ++ rpdu->number_of_packets = urb->number_of_packets; + rpdu->error_count = urb->error_count; + } else { + /* vhci_rx.c */ +@@ -693,6 +695,7 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, + urb->status = rpdu->status; + urb->actual_length = rpdu->actual_length; + urb->start_frame = rpdu->start_frame; ++ urb->number_of_packets = rpdu->number_of_packets; + urb->error_count = rpdu->error_count; + } + } +@@ -761,11 +764,13 @@ static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, + cpu_to_be32s(&pdu->status); + cpu_to_be32s(&pdu->actual_length); + cpu_to_be32s(&pdu->start_frame); ++ cpu_to_be32s(&pdu->number_of_packets); + cpu_to_be32s(&pdu->error_count); + } else { + be32_to_cpus(&pdu->status); + be32_to_cpus(&pdu->actual_length); + be32_to_cpus(&pdu->start_frame); ++ cpu_to_be32s(&pdu->number_of_packets); + be32_to_cpus(&pdu->error_count); + } + } +@@ -891,6 +896,7 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) + int size = np * sizeof(*iso); + int i; + int ret; ++ int total_length = 0; + + if (!usb_pipeisoc(urb->pipe)) + return 0; +@@ -920,19 +926,75 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) + return -EPIPE; + } + ++ + for (i = 0; i < np; i++) { + iso = buff + (i * sizeof(*iso)); + + usbip_iso_pakcet_correct_endian(iso, 0); + usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0); ++ total_length += urb->iso_frame_desc[i].actual_length; + } + + kfree(buff); + ++ if (total_length != urb->actual_length) { ++ dev_err(&urb->dev->dev, ++ "total length of iso packets (%d) not equal to actual length of buffer (%d)\n", ++ total_length, urb->actual_length); ++ ++ if (ud->side == USBIP_STUB) ++ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); ++ else ++ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); ++ ++ return -EPIPE; ++ } ++ + return ret; + } + EXPORT_SYMBOL_GPL(usbip_recv_iso); + ++/* ++ * This functions restores the padding which was removed for optimizing ++ * the bandwidth during transfer over tcp/ip ++ * ++ * buffer and iso packets need to be stored and be in propeper endian in urb ++ * before calling this function ++ */ ++int usbip_pad_iso(struct usbip_device *ud, struct urb *urb) ++{ ++ int np = urb->number_of_packets; ++ int i; ++ int ret; ++ int actualoffset = urb->actual_length; ++ ++ if (!usb_pipeisoc(urb->pipe)) ++ return 0; ++ ++ /* if no packets or length of data is 0, then nothing to unpack */ ++ if (np == 0 || urb->actual_length == 0) ++ return 0; ++ ++ /* ++ * if actual_length is transfer_buffer_length then no padding is ++ * present. ++ */ ++ if (urb->actual_length == urb->transfer_buffer_length) ++ return 0; ++ ++ /* ++ * loop over all packets from last to first (to prevent overwritting ++ * memory when padding) and move them into the proper place ++ */ ++ for (i = np-1; i > 0; i--) { ++ actualoffset -= urb->iso_frame_desc[i].actual_length; ++ memmove(urb->transfer_buffer + urb->iso_frame_desc[i].offset, ++ urb->transfer_buffer + actualoffset, ++ urb->iso_frame_desc[i].actual_length); ++ } ++ return ret; ++} ++EXPORT_SYMBOL_GPL(usbip_pad_iso); + + /* some members of urb must be substituted before. */ + int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) +diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h +index 1ca3eab..5e16bc3 100644 +--- a/drivers/staging/usbip/usbip_common.h ++++ b/drivers/staging/usbip/usbip_common.h +@@ -393,6 +393,8 @@ void usbip_header_correct_endian(struct usbip_header *pdu, int send); + int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); + /* some members of urb must be substituted before. */ + int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); ++/* some members of urb must be substituted before. */ ++int usbip_pad_iso(struct usbip_device *ud, struct urb *urb); + void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); + + +diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c +index 2d989c4..8ed5206 100644 +--- a/drivers/staging/usbip/vhci_rx.c ++++ b/drivers/staging/usbip/vhci_rx.c +@@ -97,6 +97,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, + if (usbip_recv_iso(ud, urb) < 0) + return; + ++ /* restore the padding in iso packets */ ++ if (usbip_pad_iso(ud, urb) < 0) ++ return; + + if (usbip_dbg_flag_vhci_rx) + usbip_dump_urb(urb); +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index 9f806dd..bb3c0f2 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -1182,6 +1182,8 @@ struct btrfs_root { + #define BTRFS_INODE_DIRSYNC (1 << 10) + + ++#define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) ++ + /* some macros to generate set/get funcs for the struct fields. This + * assumes there is a lefoo_to_cpu for every type, so lets make a simple + * one for u8: +@@ -2183,6 +2185,8 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); + int btrfs_find_orphan_roots(struct btrfs_root *tree_root); + int btrfs_set_root_node(struct btrfs_root_item *item, + struct extent_buffer *node); ++void btrfs_check_and_init_root_item(struct btrfs_root_item *item); ++ + /* dir-item.c */ + int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, const char *name, +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 2b59201..f447188 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -1145,8 +1145,10 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, + root->commit_root = btrfs_root_node(root); + BUG_ON(!root->node); + out: +- if (location->objectid != BTRFS_TREE_LOG_OBJECTID) ++ if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { + root->ref_cows = 1; ++ btrfs_check_and_init_root_item(&root->root_item); ++ } + + return root; + } +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 0bc5776..3359aff 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -285,6 +285,10 @@ static noinline int create_subvol(struct btrfs_root *root, + inode_item->nbytes = cpu_to_le64(root->leafsize); + inode_item->mode = cpu_to_le32(S_IFDIR | 0755); + ++ root_item.flags = 0; ++ root_item.byte_limit = 0; ++ inode_item->flags = cpu_to_le64(BTRFS_INODE_ROOT_ITEM_INIT); ++ + btrfs_set_root_bytenr(&root_item, leaf->start); + btrfs_set_root_generation(&root_item, trans->transid); + btrfs_set_root_level(&root_item, 0); +diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c +index 67fa2d2..3174255 100644 +--- a/fs/btrfs/root-tree.c ++++ b/fs/btrfs/root-tree.c +@@ -459,3 +459,21 @@ again: + btrfs_free_path(path); + return 0; + } ++ ++/* ++ * Old btrfs forgets to init root_item->flags and root_item->byte_limit ++ * for subvolumes. To work around this problem, we steal a bit from ++ * root_item->inode_item->flags, and use it to indicate if those fields ++ * have been properly initialized. ++ */ ++void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item) ++{ ++ u64 inode_flags = le64_to_cpu(root_item->inode.flags); ++ ++ if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) { ++ inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT; ++ root_item->inode.flags = cpu_to_le64(inode_flags); ++ root_item->flags = 0; ++ root_item->byte_limit = 0; ++ } ++} +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index b2acc79..b640fba 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -777,6 +777,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, + record_root_in_trans(trans, root); + btrfs_set_root_last_snapshot(&root->root_item, trans->transid); + memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); ++ btrfs_check_and_init_root_item(new_root_item); + + key.objectid = objectid; + /* record when the snapshot was created in key.offset */ +diff --git a/fs/compat.c b/fs/compat.c +index d576b55..d1e2411 100644 +--- a/fs/compat.c ++++ b/fs/compat.c +@@ -1353,6 +1353,10 @@ static int compat_count(compat_uptr_t __user *argv, int max) + argv++; + if (i++ >= max) + return -E2BIG; ++ ++ if (fatal_signal_pending(current)) ++ return -ERESTARTNOHAND; ++ cond_resched(); + } + } + return i; +@@ -1394,6 +1398,12 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv, + while (len > 0) { + int offset, bytes_to_copy; + ++ if (fatal_signal_pending(current)) { ++ ret = -ERESTARTNOHAND; ++ goto out; ++ } ++ cond_resched(); ++ + offset = pos % PAGE_SIZE; + if (offset == 0) + offset = PAGE_SIZE; +@@ -1410,18 +1420,8 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv, + if (!kmapped_page || kpos != (pos & PAGE_MASK)) { + struct page *page; + +-#ifdef CONFIG_STACK_GROWSUP +- ret = expand_stack_downwards(bprm->vma, pos); +- if (ret < 0) { +- /* We've exceed the stack rlimit. */ +- ret = -E2BIG; +- goto out; +- } +-#endif +- ret = get_user_pages(current, bprm->mm, pos, +- 1, 1, 1, &page, NULL); +- if (ret <= 0) { +- /* We've exceed the stack rlimit. */ ++ page = get_arg_page(bprm, pos, 1); ++ if (!page) { + ret = -E2BIG; + goto out; + } +@@ -1542,8 +1542,10 @@ int compat_do_execve(char * filename, + return retval; + + out: +- if (bprm->mm) ++ if (bprm->mm) { ++ acct_arg_size(bprm, 0); + mmput(bprm->mm); ++ } + + out_file: + if (bprm->file) { +diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c +index a0a7847..aa2480a 100644 +--- a/fs/ecryptfs/keystore.c ++++ b/fs/ecryptfs/keystore.c +@@ -1542,6 +1542,7 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, + printk(KERN_ERR "Could not find key with description: [%s]\n", + sig); + rc = process_request_key_err(PTR_ERR(*auth_tok_key)); ++ (*auth_tok_key) = NULL; + goto out; + } + (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); +diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c +index df4ce99..8721a89 100644 +--- a/fs/ecryptfs/mmap.c ++++ b/fs/ecryptfs/mmap.c +@@ -372,6 +372,11 @@ static int ecryptfs_write_begin(struct file *file, + && (pos != 0)) + zero_user(page, 0, PAGE_CACHE_SIZE); + out: ++ if (unlikely(rc)) { ++ unlock_page(page); ++ page_cache_release(page); ++ *pagep = NULL; ++ } + return rc; + } + +diff --git a/fs/exec.c b/fs/exec.c +index 68083fa..0cf881d 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -159,7 +159,22 @@ out: + + #ifdef CONFIG_MMU + +-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, ++void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) ++{ ++ struct mm_struct *mm = current->mm; ++ long diff = (long)(pages - bprm->vma_pages); ++ ++ if (!mm || !diff) ++ return; ++ ++ bprm->vma_pages = pages; ++ ++ down_write(&mm->mmap_sem); ++ mm->total_vm += diff; ++ up_write(&mm->mmap_sem); ++} ++ ++struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, + int write) + { + struct page *page; +@@ -181,6 +196,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, + unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; + struct rlimit *rlim; + ++ acct_arg_size(bprm, size / PAGE_SIZE); ++ + /* + * We've historically supported up to 32 pages (ARG_MAX) + * of argument strings even with small stacks +@@ -274,7 +291,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) + + #else + +-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, ++void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) ++{ ++} ++ ++struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, + int write) + { + struct page *page; +@@ -981,6 +1002,7 @@ int flush_old_exec(struct linux_binprm * bprm) + /* + * Release all of the old mmap stuff + */ ++ acct_arg_size(bprm, 0); + retval = exec_mmap(bprm->mm); + if (retval) + goto out; +@@ -1408,8 +1430,10 @@ int do_execve(char * filename, + return retval; + + out: +- if (bprm->mm) +- mmput (bprm->mm); ++ if (bprm->mm) { ++ acct_arg_size(bprm, 0); ++ mmput(bprm->mm); ++ } + + out_file: + if (bprm->file) { +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 1b23f9d..8572c79 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5458,13 +5458,12 @@ static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks, + /* if nrblocks are contiguous */ + if (chunk) { + /* +- * With N contiguous data blocks, it need at most +- * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) indirect blocks +- * 2 dindirect blocks +- * 1 tindirect block ++ * With N contiguous data blocks, we need at most ++ * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) + 1 indirect blocks, ++ * 2 dindirect blocks, and 1 tindirect block + */ +- indirects = nrblocks / EXT4_ADDR_PER_BLOCK(inode->i_sb); +- return indirects + 3; ++ return DIV_ROUND_UP(nrblocks, ++ EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4; + } + /* + * if nrblocks are not contiguous, worse case, each block touch +diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c +index b2786a5..cc2f505 100644 +--- a/fs/nfsd/lockd.c ++++ b/fs/nfsd/lockd.c +@@ -44,7 +44,6 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) + exp_readlock(); + nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp); + fh_put(&fh); +- rqstp->rq_client = NULL; + exp_readunlock(); + /* We return nlm error codes as nlm doesn't know + * about nfsd, but nfsd does know about nlm.. +diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c +index 30292df..9ad0035 100644 +--- a/fs/nilfs2/file.c ++++ b/fs/nilfs2/file.c +@@ -72,10 +72,9 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + /* + * check to see if the page is mapped already (no holes) + */ +- if (PageMappedToDisk(page)) { +- unlock_page(page); ++ if (PageMappedToDisk(page)) + goto mapped; +- } ++ + if (page_has_buffers(page)) { + struct buffer_head *bh, *head; + int fully_mapped = 1; +@@ -90,7 +89,6 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + + if (fully_mapped) { + SetPageMappedToDisk(page); +- unlock_page(page); + goto mapped; + } + } +@@ -105,16 +103,18 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + return VM_FAULT_SIGBUS; + + ret = block_page_mkwrite(vma, vmf, nilfs_get_block); +- if (unlikely(ret)) { ++ if (ret != VM_FAULT_LOCKED) { + nilfs_transaction_abort(inode->i_sb); + return ret; + } ++ nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, ++ 1 << (PAGE_SHIFT - inode->i_blkbits)); + nilfs_transaction_commit(inode->i_sb); + + mapped: + SetPageChecked(page); + wait_on_page_writeback(page); +- return 0; ++ return VM_FAULT_LOCKED; + } + + static const struct vm_operations_struct nilfs_file_vm_ops = { +diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c +index 5fc918c..35d256b 100644 +--- a/fs/ocfs2/aops.c ++++ b/fs/ocfs2/aops.c +@@ -1091,6 +1091,12 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno, + ocfs2_figure_cluster_boundaries(OCFS2_SB(inode->i_sb), cpos, + &cluster_start, &cluster_end); + ++ /* treat the write as new if the a hole/lseek spanned across ++ * the page boundary. ++ */ ++ new = new | ((i_size_read(inode) <= page_offset(page)) && ++ (page_offset(page) <= user_pos)); ++ + if (page == wc->w_target_page) { + map_from = user_pos & (PAGE_CACHE_SIZE - 1); + map_to = map_from + user_len; +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index 4fdb0eb..ce9a4f2 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -388,7 +388,7 @@ EXPORT_SYMBOL(dquot_acquire); + */ + int dquot_commit(struct dquot *dquot) + { +- int ret = 0, ret2 = 0; ++ int ret = 0; + struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + + mutex_lock(&dqopt->dqio_mutex); +@@ -400,15 +400,10 @@ int dquot_commit(struct dquot *dquot) + spin_unlock(&dq_list_lock); + /* Inactive dquot can be only if there was error during read/init + * => we have better not writing it */ +- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { ++ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); +- if (info_dirty(&dqopt->info[dquot->dq_type])) { +- ret2 = dqopt->ops[dquot->dq_type]->write_file_info( +- dquot->dq_sb, dquot->dq_type); +- } +- if (ret >= 0) +- ret = ret2; +- } ++ else ++ ret = -EIO; + out_sem: + mutex_unlock(&dqopt->dqio_mutex); + return ret; +diff --git a/fs/squashfs/dir.c b/fs/squashfs/dir.c +index 566b0ea..16c1b4a 100644 +--- a/fs/squashfs/dir.c ++++ b/fs/squashfs/dir.c +@@ -173,6 +173,11 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) + length += sizeof(dirh); + + dir_count = le32_to_cpu(dirh.count) + 1; ++ ++ /* dir_count should never be larger than 256 */ ++ if (dir_count > 256) ++ goto failed_read; ++ + while (dir_count--) { + /* + * Read directory entry. +@@ -184,6 +189,10 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) + + size = le16_to_cpu(dire->size) + 1; + ++ /* size should never be larger than SQUASHFS_NAME_LEN */ ++ if (size > SQUASHFS_NAME_LEN) ++ goto failed_read; ++ + err = squashfs_read_metadata(inode->i_sb, dire->name, + &block, &offset, size); + if (err < 0) +diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c +index 9e39865..ac52751 100644 +--- a/fs/squashfs/namei.c ++++ b/fs/squashfs/namei.c +@@ -175,6 +175,11 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, + length += sizeof(dirh); + + dir_count = le32_to_cpu(dirh.count) + 1; ++ ++ /* dir_count should never be larger than 256 */ ++ if (dir_count > 256) ++ goto data_error; ++ + while (dir_count--) { + /* + * Read directory entry. +@@ -186,6 +191,10 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, + + size = le16_to_cpu(dire->size) + 1; + ++ /* size should never be larger than SQUASHFS_NAME_LEN */ ++ if (size > SQUASHFS_NAME_LEN) ++ goto data_error; ++ + err = squashfs_read_metadata(dir->i_sb, dire->name, + &block, &offset, size); + if (err < 0) +@@ -227,6 +236,9 @@ exit_lookup: + d_add(dentry, inode); + return ERR_PTR(0); + ++data_error: ++ err = -EIO; ++ + read_failure: + ERROR("Unable to read directory block [%llx:%x]\n", + squashfs_i(dir)->start + msblk->directory_table, +diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c +index 4775af4..0d948f1 100644 +--- a/fs/ubifs/commit.c ++++ b/fs/ubifs/commit.c +@@ -518,7 +518,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) + size_t sz; + + if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX)) +- goto out; ++ return 0; + + INIT_LIST_HEAD(&list); + +diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c +index dbc093a..ace4d8d 100644 +--- a/fs/ubifs/debug.c ++++ b/fs/ubifs/debug.c +@@ -965,11 +965,39 @@ void dbg_dump_index(struct ubifs_info *c) + void dbg_save_space_info(struct ubifs_info *c) + { + struct ubifs_debug_info *d = c->dbg; +- +- ubifs_get_lp_stats(c, &d->saved_lst); ++ int freeable_cnt; + + spin_lock(&c->space_lock); ++ memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats)); ++ ++ /* ++ * We use a dirty hack here and zero out @c->freeable_cnt, because it ++ * affects the free space calculations, and UBIFS might not know about ++ * all freeable eraseblocks. Indeed, we know about freeable eraseblocks ++ * only when we read their lprops, and we do this only lazily, upon the ++ * need. So at any given point of time @c->freeable_cnt might be not ++ * exactly accurate. ++ * ++ * Just one example about the issue we hit when we did not zero ++ * @c->freeable_cnt. ++ * 1. The file-system is mounted R/O, c->freeable_cnt is %0. We save the ++ * amount of free space in @d->saved_free ++ * 2. We re-mount R/W, which makes UBIFS to read the "lsave" ++ * information from flash, where we cache LEBs from various ++ * categories ('ubifs_remount_fs()' -> 'ubifs_lpt_init()' ++ * -> 'lpt_init_wr()' -> 'read_lsave()' -> 'ubifs_lpt_lookup()' ++ * -> 'ubifs_get_pnode()' -> 'update_cats()' ++ * -> 'ubifs_add_to_cat()'). ++ * 3. Lsave contains a freeable eraseblock, and @c->freeable_cnt ++ * becomes %1. ++ * 4. We calculate the amount of free space when the re-mount is ++ * finished in 'dbg_check_space_info()' and it does not match ++ * @d->saved_free. ++ */ ++ freeable_cnt = c->freeable_cnt; ++ c->freeable_cnt = 0; + d->saved_free = ubifs_get_free_space_nolock(c); ++ c->freeable_cnt = freeable_cnt; + spin_unlock(&c->space_lock); + } + +@@ -986,12 +1014,15 @@ int dbg_check_space_info(struct ubifs_info *c) + { + struct ubifs_debug_info *d = c->dbg; + struct ubifs_lp_stats lst; +- long long avail, free; ++ long long free; ++ int freeable_cnt; + + spin_lock(&c->space_lock); +- avail = ubifs_calc_available(c, c->min_idx_lebs); ++ freeable_cnt = c->freeable_cnt; ++ c->freeable_cnt = 0; ++ free = ubifs_get_free_space_nolock(c); ++ c->freeable_cnt = freeable_cnt; + spin_unlock(&c->space_lock); +- free = ubifs_get_free_space(c); + + if (free != d->saved_free) { + ubifs_err("free space changed from %lld to %lld", +diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c +index b2792e8..d0dfe7a 100644 +--- a/fs/ubifs/lpt.c ++++ b/fs/ubifs/lpt.c +@@ -1269,10 +1269,9 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) + lnum = branch->lnum; + offs = branch->offs; + pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS); +- if (!pnode) { +- err = -ENOMEM; +- goto out; +- } ++ if (!pnode) ++ return -ENOMEM; ++ + if (lnum == 0) { + /* + * This pnode was not written which just means that the LEB +diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c +index 61496c6..942362f 100644 +--- a/fs/xfs/linux-2.6/xfs_ioctl.c ++++ b/fs/xfs/linux-2.6/xfs_ioctl.c +@@ -697,14 +697,19 @@ xfs_ioc_fsgeometry_v1( + xfs_mount_t *mp, + void __user *arg) + { +- xfs_fsop_geom_v1_t fsgeo; ++ xfs_fsop_geom_t fsgeo; + int error; + +- error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3); ++ error = xfs_fs_geometry(mp, &fsgeo, 3); + if (error) + return -error; + +- if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) ++ /* ++ * Caller should have passed an argument of type ++ * xfs_fsop_geom_v1_t. This is a proper subset of the ++ * xfs_fsop_geom_t that xfs_fs_geometry() fills in. ++ */ ++ if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t))) + return -XFS_ERROR(EFAULT); + return 0; + } +diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c +index 6f83f58..785b2a2 100644 +--- a/fs/xfs/xfs_fsops.c ++++ b/fs/xfs/xfs_fsops.c +@@ -56,6 +56,9 @@ xfs_fs_geometry( + xfs_fsop_geom_t *geo, + int new_version) + { ++ ++ memset(geo, 0, sizeof(*geo)); ++ + geo->blocksize = mp->m_sb.sb_blocksize; + geo->rtextsize = mp->m_sb.sb_rextsize; + geo->agblocks = mp->m_sb.sb_agblocks; +diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h +index 340f441..a3d802e 100644 +--- a/include/linux/binfmts.h ++++ b/include/linux/binfmts.h +@@ -29,6 +29,7 @@ struct linux_binprm{ + char buf[BINPRM_BUF_SIZE]; + #ifdef CONFIG_MMU + struct vm_area_struct *vma; ++ unsigned long vma_pages; + #else + # define MAX_ARG_PAGES 32 + struct page *page[MAX_ARG_PAGES]; +@@ -59,6 +60,10 @@ struct linux_binprm{ + unsigned long loader, exec; + }; + ++extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages); ++extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, ++ int write); ++ + #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 + #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) + +diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h +index f097ae3..de8e180 100644 +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -446,7 +446,7 @@ static inline int scsi_device_qas(struct scsi_device *sdev) + } + static inline int scsi_device_enclosure(struct scsi_device *sdev) + { +- return sdev->inquiry[6] & (1<<6); ++ return sdev->inquiry ? (sdev->inquiry[6] & (1<<6)) : 1; + } + + static inline int scsi_device_protection(struct scsi_device *sdev) +diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h +index c1410e3..511b623 100644 +--- a/include/sound/soc-dapm.h ++++ b/include/sound/soc-dapm.h +@@ -46,25 +46,25 @@ + /* platform domain */ + #define SND_SOC_DAPM_INPUT(wname) \ + { .id = snd_soc_dapm_input, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0} ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM } + #define SND_SOC_DAPM_OUTPUT(wname) \ + { .id = snd_soc_dapm_output, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0} ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM } + #define SND_SOC_DAPM_MIC(wname, wevent) \ + { .id = snd_soc_dapm_mic, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} + #define SND_SOC_DAPM_HP(wname, wevent) \ + { .id = snd_soc_dapm_hp, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} + #define SND_SOC_DAPM_SPK(wname, wevent) \ + { .id = snd_soc_dapm_spk, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} + #define SND_SOC_DAPM_LINE(wname, wevent) \ + { .id = snd_soc_dapm_line, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} + + /* path domain */ +@@ -129,11 +129,11 @@ + /* events that are pre and post DAPM */ + #define SND_SOC_DAPM_PRE(wname, wevent) \ + { .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD} + #define SND_SOC_DAPM_POST(wname, wevent) \ + { .id = snd_soc_dapm_post, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD} + + /* stream domain */ +diff --git a/kernel/kgdb.c b/kernel/kgdb.c +index 9147a31..53dae4b 100644 +--- a/kernel/kgdb.c ++++ b/kernel/kgdb.c +@@ -1001,10 +1001,8 @@ static void gdb_cmd_query(struct kgdb_state *ks) + switch (remcom_in_buffer[1]) { + case 's': + case 'f': +- if (memcmp(remcom_in_buffer + 2, "ThreadInfo", 10)) { +- error_packet(remcom_out_buffer, -EINVAL); ++ if (memcmp(remcom_in_buffer + 2, "ThreadInfo", 10)) + break; +- } + + i = 0; + remcom_out_buffer[0] = 'm'; +@@ -1045,10 +1043,9 @@ static void gdb_cmd_query(struct kgdb_state *ks) + pack_threadid(remcom_out_buffer + 2, thref); + break; + case 'T': +- if (memcmp(remcom_in_buffer + 1, "ThreadExtraInfo,", 16)) { +- error_packet(remcom_out_buffer, -EINVAL); ++ if (memcmp(remcom_in_buffer + 1, "ThreadExtraInfo,", 16)) + break; +- } ++ + ks->threadid = 0; + ptr = remcom_in_buffer + 17; + kgdb_hex2long(&ptr, &ks->threadid); +diff --git a/kernel/perf_event.c b/kernel/perf_event.c +index 183d437..fc5ab8e 100644 +--- a/kernel/perf_event.c ++++ b/kernel/perf_event.c +@@ -69,7 +69,8 @@ static inline bool perf_paranoid_kernel(void) + return sysctl_perf_event_paranoid > 1; + } + +-int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */ ++/* Minimum for 128 pages + 1 for the user control page */ ++int sysctl_perf_event_mlock __read_mostly = 516; /* 'free' kb per user */ + + /* + * max perf event sample rate +diff --git a/kernel/signal.c b/kernel/signal.c +index e26d423..2494827 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2353,7 +2353,7 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, + /* Not even root can pretend to send signals from the kernel. + * Nor can they impersonate a kill()/tgkill(), which adds source info. + */ +- if (info.si_code != SI_QUEUE) { ++ if (info.si_code >= 0 || info.si_code == SI_TKILL) { + /* We used to allow any < 0 si_code */ + WARN_ON_ONCE(info.si_code < 0); + return -EPERM; +@@ -2373,7 +2373,7 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) + /* Not even root can pretend to send signals from the kernel. + * Nor can they impersonate a kill()/tgkill(), which adds source info. + */ +- if (info->si_code != SI_QUEUE) { ++ if (info->si_code >= 0 || info->si_code == SI_TKILL) { + /* We used to allow any < 0 si_code */ + WARN_ON_ONCE(info->si_code < 0); + return -EPERM; +diff --git a/mm/mremap.c b/mm/mremap.c +index 166b824..3e98d79 100644 +--- a/mm/mremap.c ++++ b/mm/mremap.c +@@ -275,9 +275,16 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr, + if (old_len > vma->vm_end - addr) + goto Efault; + +- if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) { +- if (new_len > old_len) ++ /* Need to be careful about a growing mapping */ ++ if (new_len > old_len) { ++ unsigned long pgoff; ++ ++ if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) + goto Efault; ++ pgoff = (addr - vma->vm_start) >> PAGE_SHIFT; ++ pgoff += vma->vm_pgoff; ++ if (pgoff + (new_len >> PAGE_SHIFT) < pgoff) ++ goto Einval; + } + + if (vma->vm_flags & VM_LOCKED) { +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index f454607..608a97b 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -1391,6 +1391,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, + ax25_cb *ax25; + int err = 0; + ++ memset(fsa, 0, sizeof(fsa)); + lock_sock(sk); + ax25 = ax25_sk(sk); + +@@ -1402,7 +1403,6 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, + + fsa->fsa_ax25.sax25_family = AF_AX25; + fsa->fsa_ax25.sax25_call = ax25->dest_addr; +- fsa->fsa_ax25.sax25_ndigis = 0; + + if (ax25->digipeat != NULL) { + ndigi = ax25->digipeat->ndigi; +diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c +index e857628..efc85dc 100644 +--- a/net/bluetooth/bnep/sock.c ++++ b/net/bluetooth/bnep/sock.c +@@ -88,6 +88,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long + sockfd_put(nsock); + return -EBADFD; + } ++ ca.device[sizeof(ca.device)-1] = 0; + + err = bnep_add_connection(&ca, nsock); + if (!err) { +diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c +index 5c0685e..e52443c 100644 +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -700,6 +700,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user + break; + } + ++ memset(&cinfo, 0, sizeof(cinfo)); + cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle; + memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); + +diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c +index 0b7f262..d73d47f 100644 +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -979,6 +979,8 @@ static int do_replace(struct net *net, void __user *user, unsigned int len) + if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) + return -ENOMEM; + ++ tmp.name[sizeof(tmp.name) - 1] = 0; ++ + countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids; + newinfo = vmalloc(sizeof(*newinfo) + countersize); + if (!newinfo) +diff --git a/net/can/bcm.c b/net/can/bcm.c +index 4a192f7..029dcc2 100644 +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -124,7 +124,7 @@ struct bcm_sock { + struct list_head tx_ops; + unsigned long dropped_usr_msgs; + struct proc_dir_entry *bcm_proc_read; +- char procname [20]; /* pointer printed in ASCII with \0 */ ++ char procname [32]; /* inode number in decimal with \0 */ + }; + + static inline struct bcm_sock *bcm_sk(const struct sock *sk) +@@ -1519,7 +1519,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, + + if (proc_dir) { + /* unique socket address as filename */ +- sprintf(bo->procname, "%p", sock); ++ sprintf(bo->procname, "%lu", sock_i_ino(sk)); + bo->bcm_proc_read = proc_create_data(bo->procname, 0644, + proc_dir, + &bcm_proc_fops, sk); +diff --git a/net/core/dev.c b/net/core/dev.c +index 49e3782..64eb849 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2614,6 +2614,8 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) + { + __skb_pull(skb, skb_headlen(skb)); + skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); ++ skb->dev = napi->dev; ++ skb->iif = 0; + + napi->skb = skb; + } +diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c +index 85672e7..2a3b4e7 100644 +--- a/net/econet/af_econet.c ++++ b/net/econet/af_econet.c +@@ -428,10 +428,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, + udpdest.sin_addr.s_addr = htonl(network | addr.station); + } + ++ memset(&ah, 0, sizeof(ah)); + ah.port = port; + ah.cb = cb & 0x7f; + ah.code = 2; /* magic */ +- ah.pad = 0; + + /* tack our header on the front of the iovec */ + size = sizeof(struct aunhdr); +@@ -843,9 +843,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len) + { + struct iphdr *ip = ip_hdr(skb); + unsigned char stn = ntohl(ip->saddr) & 0xff; ++ struct dst_entry *dst = skb_dst(skb); ++ struct ec_device *edev = NULL; + struct sock *sk; + struct sk_buff *newskb; +- struct ec_device *edev = skb->dev->ec_ptr; ++ ++ if (dst) ++ edev = dst->dev->ec_ptr; + + if (! edev) + goto bad; +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index a706a47..6fe360f 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -489,9 +489,11 @@ static int inet_csk_diag_dump(struct sock *sk, + { + struct inet_diag_req *r = NLMSG_DATA(cb->nlh); + +- if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { ++ if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { + struct inet_diag_entry entry; +- struct rtattr *bc = (struct rtattr *)(r + 1); ++ const struct nlattr *bc = nlmsg_find_attr(cb->nlh, ++ sizeof(*r), ++ INET_DIAG_REQ_BYTECODE); + struct inet_sock *inet = inet_sk(sk); + + entry.family = sk->sk_family; +@@ -511,7 +513,7 @@ static int inet_csk_diag_dump(struct sock *sk, + entry.dport = ntohs(inet->dport); + entry.userlocks = sk->sk_userlocks; + +- if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) ++ if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) + return 0; + } + +@@ -526,9 +528,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, + { + struct inet_diag_req *r = NLMSG_DATA(cb->nlh); + +- if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { ++ if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { + struct inet_diag_entry entry; +- struct rtattr *bc = (struct rtattr *)(r + 1); ++ const struct nlattr *bc = nlmsg_find_attr(cb->nlh, ++ sizeof(*r), ++ INET_DIAG_REQ_BYTECODE); + + entry.family = tw->tw_family; + #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +@@ -547,7 +551,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, + entry.dport = ntohs(tw->tw_dport); + entry.userlocks = 0; + +- if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) ++ if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) + return 0; + } + +@@ -617,7 +621,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, + struct inet_diag_req *r = NLMSG_DATA(cb->nlh); + struct inet_connection_sock *icsk = inet_csk(sk); + struct listen_sock *lopt; +- struct rtattr *bc = NULL; ++ const struct nlattr *bc = NULL; + struct inet_sock *inet = inet_sk(sk); + int j, s_j; + int reqnum, s_reqnum; +@@ -637,8 +641,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, + if (!lopt || !lopt->qlen) + goto out; + +- if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { +- bc = (struct rtattr *)(r + 1); ++ if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { ++ bc = nlmsg_find_attr(cb->nlh, sizeof(*r), ++ INET_DIAG_REQ_BYTECODE); + entry.sport = inet->num; + entry.userlocks = sk->sk_userlocks; + } +@@ -671,8 +676,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, + &ireq->rmt_addr; + entry.dport = ntohs(ireq->rmt_port); + +- if (!inet_diag_bc_run(RTA_DATA(bc), +- RTA_PAYLOAD(bc), &entry)) ++ if (!inet_diag_bc_run(nla_data(bc), ++ nla_len(bc), &entry)) + continue; + } + +diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c +index 98442f3..c8b0cc3 100644 +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -1086,6 +1086,7 @@ static int do_replace(struct net *net, void __user *user, unsigned int len) + /* overflow check */ + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1508,6 +1509,7 @@ static int compat_do_replace(struct net *net, void __user *user, + return -ENOMEM; + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1763,6 +1765,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len + ret = -EFAULT; + break; + } ++ rev.name[sizeof(rev.name)-1] = 0; + + try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name, + rev.revision, 1, &ret), +diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c +index 62aff31..0606db1 100644 +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -1290,6 +1290,7 @@ do_replace(struct net *net, void __user *user, unsigned int len) + /* overflow check */ + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1820,6 +1821,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) + return -ENOMEM; + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -2044,6 +2046,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + ret = -EFAULT; + break; + } ++ rev.name[sizeof(rev.name)-1] = 0; + + if (cmd == IPT_SO_GET_REVISION_TARGET) + target = 1; +diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c +index 2e4f98b..edd8205 100644 +--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c ++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c +@@ -666,8 +666,11 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input, + struct clusterip_config *c = pde->data; + unsigned long nodenum; + +- if (copy_from_user(buffer, input, PROC_WRITELEN)) ++ if (size > PROC_WRITELEN) ++ return -EIO; ++ if (copy_from_user(buffer, input, size)) + return -EFAULT; ++ buffer[size] = 0; + + if (*buffer == '+') { + nodenum = simple_strtoul(buffer+1, NULL, 10); +diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c +index 1de56fdf..78b5a36 100644 +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -1323,6 +1323,7 @@ do_replace(struct net *net, void __user *user, unsigned int len) + /* overflow check */ + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1855,6 +1856,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) + return -ENOMEM; + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -2079,6 +2081,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + ret = -EFAULT; + break; + } ++ rev.name[sizeof(rev.name)-1] = 0; + + if (cmd == IP6T_SO_GET_REVISION_TARGET) + target = 1; +diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c +index b6cef980..476b24e 100644 +--- a/net/irda/af_irda.c ++++ b/net/irda/af_irda.c +@@ -2164,6 +2164,14 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, + + switch (optname) { + case IRLMP_ENUMDEVICES: ++ ++ /* Offset to first device entry */ ++ offset = sizeof(struct irda_device_list) - ++ sizeof(struct irda_device_info); ++ ++ if (len < offset) ++ return -EINVAL; ++ + /* Ask lmp for the current discovery log */ + discoveries = irlmp_get_discoveries(&list.len, self->mask.word, + self->nslots); +@@ -2173,15 +2181,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, + err = 0; + + /* Write total list length back to client */ +- if (copy_to_user(optval, &list, +- sizeof(struct irda_device_list) - +- sizeof(struct irda_device_info))) ++ if (copy_to_user(optval, &list, offset)) + err = -EFAULT; + +- /* Offset to first device entry */ +- offset = sizeof(struct irda_device_list) - +- sizeof(struct irda_device_info); +- + /* Copy the list itself - watch for overflow */ + if(list.len > 2048) + { +diff --git a/net/irda/iriap.c b/net/irda/iriap.c +index f7d6150..35a338b 100644 +--- a/net/irda/iriap.c ++++ b/net/irda/iriap.c +@@ -655,10 +655,16 @@ static void iriap_getvaluebyclass_indication(struct iriap_cb *self, + n = 1; + + name_len = fp[n++]; ++ ++ IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;); ++ + memcpy(name, fp+n, name_len); n+=name_len; + name[name_len] = '\0'; + + attr_len = fp[n++]; ++ ++ IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;); ++ + memcpy(attr, fp+n, attr_len); n+=attr_len; + attr[attr_len] = '\0'; + +diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c +index 7dea882..38997cd 100644 +--- a/net/irda/irnet/irnet_ppp.c ++++ b/net/irda/irnet/irnet_ppp.c +@@ -106,6 +106,9 @@ irnet_ctrl_write(irnet_socket * ap, + while(isspace(start[length - 1])) + length--; + ++ DABORT(length < 5 || length > NICKNAME_MAX_LEN + 5, ++ -EINVAL, CTRL_ERROR, "Invalid nickname.\n"); ++ + /* Copy the name for later reuse */ + memcpy(ap->rname, start + 5, length - 5); + ap->rname[length - 5] = '\0'; +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 594f231..7de0c24 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -276,6 +276,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, + memcpy(sta->sta.addr, addr, ETH_ALEN); + sta->local = local; + sta->sdata = sdata; ++ sta->last_rx = jiffies; + + sta->rate_ctrl = rate_control_get(local->rate_ctrl); + sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 41866eb..9d9b78e 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -1526,7 +1526,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, + uaddr->sa_family = AF_PACKET; + dev = dev_get_by_index(sock_net(sk), pkt_sk(sk)->ifindex); + if (dev) { +- strlcpy(uaddr->sa_data, dev->name, 15); ++ strncpy(uaddr->sa_data, dev->name, 14); + dev_put(dev); + } else + memset(uaddr->sa_data, 0, 14); +@@ -1549,6 +1549,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, + sll->sll_family = AF_PACKET; + sll->sll_ifindex = po->ifindex; + sll->sll_protocol = po->num; ++ sll->sll_pkttype = 0; + dev = dev_get_by_index(sock_net(sk), po->ifindex); + if (dev) { + sll->sll_hatype = dev->type; +diff --git a/net/rds/rdma.c b/net/rds/rdma.c +index 6b09b94..f7d8c08 100644 +--- a/net/rds/rdma.c ++++ b/net/rds/rdma.c +@@ -473,6 +473,14 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, + + max_pages = max(nr, max_pages); + nr_pages += nr; ++ ++ /* ++ * nr_pages for one entry is limited to (UINT_MAX>>PAGE_SHIFT)+1, ++ * so tot_pages cannot overflow without first going negative. ++ */ ++ if ((int)nr_pages < 0) ++ ret = -EINVAL; ++ goto out; + } + + pages = kcalloc(max_pages, sizeof(struct page *), GFP_KERNEL); +diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c +index b05108f..07bca7d 100644 +--- a/net/rose/rose_subr.c ++++ b/net/rose/rose_subr.c +@@ -289,10 +289,15 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * + facilities->source_ndigis = 0; + facilities->dest_ndigis = 0; + for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) { +- if (pt[6] & AX25_HBIT) ++ if (pt[6] & AX25_HBIT) { ++ if (facilities->dest_ndigis >= ROSE_MAX_DIGIS) ++ return -1; + memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN); +- else ++ } else { ++ if (facilities->source_ndigis >= ROSE_MAX_DIGIS) ++ return -1; + memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN); ++ } + } + } + p += l + 2; +@@ -332,6 +337,11 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac + + case 0xC0: + l = p[1]; ++ ++ /* Prevent overflows*/ ++ if (l < 10 || l > 20) ++ return -1; ++ + if (*p == FAC_CCITT_DEST_NSAP) { + memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); + memcpy(callsign, p + 12, l - 10); +@@ -372,12 +382,16 @@ int rose_parse_facilities(unsigned char *p, + switch (*p) { + case FAC_NATIONAL: /* National */ + len = rose_parse_national(p + 1, facilities, facilities_len - 1); ++ if (len < 0) ++ return 0; + facilities_len -= len + 1; + p += len + 1; + break; + + case FAC_CCITT: /* CCITT */ + len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); ++ if (len < 0) ++ return 0; + facilities_len -= len + 1; + p += len + 1; + break; +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c +index c4cf362..feedee7 100644 +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -230,7 +230,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, + sp = sctp_sk(asoc->base.sk); + num_types = sp->pf->supported_addrs(sp, types); + +- chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); ++ chunksize = sizeof(init) + addrs_len; ++ chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types)); + chunksize += sizeof(ecap_param); + + if (sctp_prsctp_enable) +@@ -260,14 +261,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, + /* Add HMACS parameter length if any were defined */ + auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; + if (auth_hmacs->length) +- chunksize += ntohs(auth_hmacs->length); ++ chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); + else + auth_hmacs = NULL; + + /* Add CHUNKS parameter length */ + auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; + if (auth_chunks->length) +- chunksize += ntohs(auth_chunks->length); ++ chunksize += WORD_ROUND(ntohs(auth_chunks->length)); + else + auth_chunks = NULL; + +@@ -277,7 +278,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, + + /* If we have any extensions to report, account for that */ + if (num_ext) +- chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; ++ chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + ++ num_ext); + + /* RFC 2960 3.3.2 Initiation (INIT) (1) + * +@@ -419,13 +421,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, + + auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; + if (auth_hmacs->length) +- chunksize += ntohs(auth_hmacs->length); ++ chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); + else + auth_hmacs = NULL; + + auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; + if (auth_chunks->length) +- chunksize += ntohs(auth_chunks->length); ++ chunksize += WORD_ROUND(ntohs(auth_chunks->length)); + else + auth_chunks = NULL; + +@@ -434,7 +436,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, + } + + if (num_ext) +- chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; ++ chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + ++ num_ext); + + /* Now allocate and fill out the chunk. */ + retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index e6d9abf..8ebf4975 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -393,6 +393,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, + struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; + struct tipc_sock *tsock = tipc_sk(sock->sk); + ++ memset(addr, 0, sizeof(*addr)); + if (peer) { + if ((sock->state != SS_CONNECTED) && + ((peer != 2) || (sock->state != SS_DISCONNECTING))) +diff --git a/sound/core/init.c b/sound/core/init.c +index ec4a50c..82f350e 100644 +--- a/sound/core/init.c ++++ b/sound/core/init.c +@@ -848,6 +848,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) + return -ENOMEM; + mfile->file = file; + mfile->disconnected_f_op = NULL; ++ INIT_LIST_HEAD(&mfile->shutdown_list); + spin_lock(&card->files_lock); + if (card->shutdown) { + spin_unlock(&card->files_lock); +@@ -883,6 +884,9 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) + list_for_each_entry(mfile, &card->files_list, list) { + if (mfile->file == file) { + list_del(&mfile->list); ++ spin_lock(&shutdown_lock); ++ list_del(&mfile->shutdown_list); ++ spin_unlock(&shutdown_lock); + if (mfile->disconnected_f_op) + fops_put(mfile->disconnected_f_op); + found = mfile; +diff --git a/sound/oss/dev_table.h b/sound/oss/dev_table.h +index b7617be..0199a31 100644 +--- a/sound/oss/dev_table.h ++++ b/sound/oss/dev_table.h +@@ -271,7 +271,7 @@ struct synth_operations + void (*reset) (int dev); + void (*hw_control) (int dev, unsigned char *event); + int (*load_patch) (int dev, int format, const char __user *addr, +- int offs, int count, int pmgr_flag); ++ int count, int pmgr_flag); + void (*aftertouch) (int dev, int voice, int pressure); + void (*controller) (int dev, int voice, int ctrl_num, int value); + void (*panning) (int dev, int voice, int value); +diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c +index 9e45098..978423e 100644 +--- a/sound/oss/midi_synth.c ++++ b/sound/oss/midi_synth.c +@@ -476,7 +476,7 @@ EXPORT_SYMBOL(midi_synth_hw_control); + + int + midi_synth_load_patch(int dev, int format, const char __user *addr, +- int offs, int count, int pmgr_flag) ++ int count, int pmgr_flag) + { + int orig_dev = synth_devs[dev]->midi_dev; + +@@ -491,39 +491,37 @@ midi_synth_load_patch(int dev, int format, const char __user *addr, + if (!prefix_cmd(orig_dev, 0xf0)) + return 0; + ++ /* Invalid patch format */ + if (format != SYSEX_PATCH) +- { +-/* printk("MIDI Error: Invalid patch format (key) 0x%x\n", format);*/ + return -EINVAL; +- } ++ ++ /* Patch header too short */ + if (count < hdr_size) +- { +-/* printk("MIDI Error: Patch header too short\n");*/ + return -EINVAL; +- } ++ + count -= hdr_size; + + /* +- * Copy the header from user space but ignore the first bytes which have +- * been transferred already. ++ * Copy the header from user space + */ + +- if(copy_from_user(&((char *) &sysex)[offs], &(addr)[offs], hdr_size - offs)) ++ if (copy_from_user(&sysex, addr, hdr_size)) + return -EFAULT; +- +- if (count < sysex.len) +- { +-/* printk(KERN_WARNING "MIDI Warning: Sysex record too short (%d<%d)\n", count, (int) sysex.len);*/ ++ ++ /* Sysex record too short */ ++ if ((unsigned)count < (unsigned)sysex.len) + sysex.len = count; +- } +- left = sysex.len; +- src_offs = 0; ++ ++ left = sysex.len; ++ src_offs = 0; + + for (i = 0; i < left && !signal_pending(current); i++) + { + unsigned char data; + +- get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i])); ++ if (get_user(data, ++ (unsigned char __user *)(addr + hdr_size + i))) ++ return -EFAULT; + + eox_seen = (i > 0 && data & 0x80); /* End of sysex */ + +diff --git a/sound/oss/midi_synth.h b/sound/oss/midi_synth.h +index 6bc9d00..b64ddd6 100644 +--- a/sound/oss/midi_synth.h ++++ b/sound/oss/midi_synth.h +@@ -8,7 +8,7 @@ int midi_synth_open (int dev, int mode); + void midi_synth_close (int dev); + void midi_synth_hw_control (int dev, unsigned char *event); + int midi_synth_load_patch (int dev, int format, const char __user * addr, +- int offs, int count, int pmgr_flag); ++ int count, int pmgr_flag); + void midi_synth_panning (int dev, int channel, int pressure); + void midi_synth_aftertouch (int dev, int channel, int pressure); + void midi_synth_controller (int dev, int channel, int ctrl_num, int value); +diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c +index 7781c13..4e912dd 100644 +--- a/sound/oss/opl3.c ++++ b/sound/oss/opl3.c +@@ -819,7 +819,7 @@ static void opl3_hw_control(int dev, unsigned char *event) + } + + static int opl3_load_patch(int dev, int format, const char __user *addr, +- int offs, int count, int pmgr_flag) ++ int count, int pmgr_flag) + { + struct sbi_instrument ins; + +@@ -829,11 +829,7 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, + return -EINVAL; + } + +- /* +- * What the fuck is going on here? We leave junk in the beginning +- * of ins and then check the field pretty close to that beginning? +- */ +- if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs)) ++ if (copy_from_user(&ins, addr, sizeof(ins))) + return -EFAULT; + + if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) +@@ -848,6 +844,10 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, + + static void opl3_panning(int dev, int voice, int value) + { ++ ++ if (voice < 0 || voice >= devc->nr_voice) ++ return; ++ + devc->voc[voice].panning = value; + } + +@@ -1065,8 +1065,15 @@ static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info + + static void opl3_setup_voice(int dev, int voice, int chn) + { +- struct channel_info *info = +- &synth_devs[dev]->chn_info[chn]; ++ struct channel_info *info; ++ ++ if (voice < 0 || voice >= devc->nr_voice) ++ return; ++ ++ if (chn < 0 || chn > 15) ++ return; ++ ++ info = &synth_devs[dev]->chn_info[chn]; + + opl3_set_instr(dev, voice, info->pgm_num); + +diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c +index c798746..5cb171d 100644 +--- a/sound/oss/sequencer.c ++++ b/sound/oss/sequencer.c +@@ -241,7 +241,7 @@ int sequencer_write(int dev, struct file *file, const char __user *buf, int coun + return -ENXIO; + + fmt = (*(short *) &event_rec[0]) & 0xffff; +- err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0); ++ err = synth_devs[dev]->load_patch(dev, fmt, buf + p, c, 0); + if (err < 0) + return err; + +diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c +index 2b82c5c..fc948a7 100644 +--- a/sound/pci/ens1370.c ++++ b/sound/pci/ens1370.c +@@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force)."); + #define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */ + #define ES_1371_CODEC_RDY (1<<31) /* codec ready */ + #define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */ ++#define EV_1938_CODEC_MAGIC (1<<26) + #define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */ + #define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0)) + #define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD) +@@ -603,12 +604,18 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531, + + #ifdef CHIP1371 + ++static inline bool is_ev1938(struct ensoniq *ensoniq) ++{ ++ return ensoniq->pci->device == 0x8938; ++} ++ + static void snd_es1371_codec_write(struct snd_ac97 *ac97, + unsigned short reg, unsigned short val) + { + struct ensoniq *ensoniq = ac97->private_data; +- unsigned int t, x; ++ unsigned int t, x, flag; + ++ flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; + mutex_lock(&ensoniq->src_mutex); + for (t = 0; t < POLL_COUNT; t++) { + if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { +@@ -630,7 +637,8 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, + 0x00010000) + break; + } +- outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC)); ++ outl(ES_1371_CODEC_WRITE(reg, val) | flag, ++ ES_REG(ensoniq, 1371_CODEC)); + /* restore SRC reg */ + snd_es1371_wait_src_ready(ensoniq); + outl(x, ES_REG(ensoniq, 1371_SMPRATE)); +@@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, + unsigned short reg) + { + struct ensoniq *ensoniq = ac97->private_data; +- unsigned int t, x, fail = 0; ++ unsigned int t, x, flag, fail = 0; + ++ flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; + __again: + mutex_lock(&ensoniq->src_mutex); + for (t = 0; t < POLL_COUNT; t++) { +@@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, + 0x00010000) + break; + } +- outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC)); ++ outl(ES_1371_CODEC_READS(reg) | flag, ++ ES_REG(ensoniq, 1371_CODEC)); + /* restore SRC reg */ + snd_es1371_wait_src_ready(ensoniq); + outl(x, ES_REG(ensoniq, 1371_SMPRATE)); +@@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, + /* now wait for the stinkin' data (RDY) */ + for (t = 0; t < POLL_COUNT; t++) { + if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { ++ if (is_ev1938(ensoniq)) { ++ for (t = 0; t < 100; t++) ++ inl(ES_REG(ensoniq, CONTROL)); ++ x = inl(ES_REG(ensoniq, 1371_CODEC)); ++ } + mutex_unlock(&ensoniq->src_mutex); + return ES_1371_CODEC_READ(x); + } +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 34e7ec9..ed550e4 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -1153,7 +1153,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) + case 0x10ec0883: + case 0x10ec0885: + case 0x10ec0887: +- case 0x10ec0889: ++ /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ + alc889_coef_init(codec); + break; + case 0x10ec0888: diff --git a/2.6.32/1037_linux-2.6.32.38.patch b/2.6.32/1037_linux-2.6.32.38.patch new file mode 100644 index 0000000..8dcf5ca --- /dev/null +++ b/2.6.32/1037_linux-2.6.32.38.patch @@ -0,0 +1,19 @@ +diff --git a/net/rds/rdma.c b/net/rds/rdma.c +index f7d8c08..6b09b94 100644 +--- a/net/rds/rdma.c ++++ b/net/rds/rdma.c +@@ -473,14 +473,6 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, + + max_pages = max(nr, max_pages); + nr_pages += nr; +- +- /* +- * nr_pages for one entry is limited to (UINT_MAX>>PAGE_SHIFT)+1, +- * so tot_pages cannot overflow without first going negative. +- */ +- if ((int)nr_pages < 0) +- ret = -EINVAL; +- goto out; + } + + pages = kcalloc(max_pages, sizeof(struct page *), GFP_KERNEL); diff --git a/2.6.32/4425_grsec-pax-without-grsec.patch b/2.6.32/4425_grsec-pax-without-grsec.patch index baaabdb..c6e9159 100644 --- a/2.6.32/4425_grsec-pax-without-grsec.patch +++ b/2.6.32/4425_grsec-pax-without-grsec.patch @@ -36,7 +36,7 @@ diff -Naur linux-2.6.32-hardened-r44.orig/arch/x86/mm/fault.c linux-2.6.32-harde diff -Naur linux-2.6.32-hardened-r44.orig/fs/exec.c linux-2.6.32-hardened-r44/fs/exec.c --- linux-2.6.32-hardened-r44.orig/fs/exec.c 2011-04-17 18:15:55.000000000 -0400 +++ linux-2.6.32-hardened-r44/fs/exec.c 2011-04-17 18:29:40.000000000 -0400 -@@ -1792,9 +1792,11 @@ +@@ -1794,9 +1794,11 @@ } up_read(&mm->mmap_sem); } @@ -48,7 +48,7 @@ diff -Naur linux-2.6.32-hardened-r44.orig/fs/exec.c linux-2.6.32-hardened-r44/fs printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset); printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, " "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk), -@@ -1809,10 +1811,12 @@ +@@ -1811,10 +1813,12 @@ #ifdef CONFIG_PAX_REFCOUNT void pax_report_refcount_overflow(struct pt_regs *regs) { @@ -61,7 +61,7 @@ diff -Naur linux-2.6.32-hardened-r44.orig/fs/exec.c linux-2.6.32-hardened-r44/fs printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n", current->comm, task_pid_nr(current), current_uid(), current_euid()); print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs)); -@@ -1872,10 +1876,12 @@ +@@ -1874,10 +1878,12 @@ void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type) { |