This is the start of the longterm review cycle for the 2.6.32.37 release.
There are 74 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let us know. If anyone is a maintainer of the proper subsystem, and
wants to add a Signed-off-by: line to the patch, please respond with it.
Responses should be made by Friday, Apr 15 2011, 15:00:00 UTC.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v2.6/longterm-review/patch-2.6.32.37-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Makefile | 2 +-
arch/powerpc/kernel/crash.c | 4 ++
arch/x86/kernel/cpu/mtrr/main.c | 20 ++++++--
arch/x86/kernel/head64.c | 3 +
arch/x86/kernel/microcode_amd.c | 72 +++++++++++++++++++------------
arch/x86/kernel/setup.c | 5 --
arch/x86/mm/init.c | 19 ++++++++
arch/x86/mm/init_64.c | 11 ++---
drivers/atm/solos-pci.c | 9 +++-
drivers/block/cciss.h | 1 +
drivers/bluetooth/btusb.c | 3 +
drivers/char/tpm/tpm.c | 2 +-
drivers/mfd/ab3100-core.c | 4 +-
drivers/misc/ep93xx_pwm.c | 6 +-
drivers/net/myri10ge/myri10ge.c | 1 +
drivers/net/wireless/ath/ath9k/main.c | 4 ++
drivers/net/wireless/b43/dma.c | 2 +-
drivers/net/wireless/b43/dma.h | 2 +-
drivers/net/wireless/p54/p54usb.c | 2 +
drivers/rtc/rtc-ds1511.c | 2 +-
drivers/scsi/ses.c | 4 +-
drivers/staging/hv/Channel.c | 8 ++--
drivers/staging/hv/Connection.c | 6 ++-
drivers/staging/hv/Vmbus.c | 2 +-
drivers/staging/hv/VmbusPrivate.h | 1 +
drivers/staging/hv/netvsc_drv.c | 24 ++++++++++
drivers/staging/usbip/stub_rx.c | 40 ++++++-----------
drivers/staging/usbip/stub_tx.c | 74 ++++++++++++++++++++++++++------
drivers/staging/usbip/usbip_common.c | 64 +++++++++++++++++++++++++++-
drivers/staging/usbip/usbip_common.h | 2 +
drivers/staging/usbip/vhci_rx.c | 3 +
fs/btrfs/ctree.h | 4 ++
fs/btrfs/disk-io.c | 4 +-
fs/btrfs/ioctl.c | 4 ++
fs/btrfs/root-tree.c | 18 ++++++++
fs/btrfs/transaction.c | 1 +
fs/compat.c | 28 ++++++------
fs/ecryptfs/keystore.c | 1 +
fs/ecryptfs/mmap.c | 5 ++
fs/exec.c | 32 ++++++++++++--
fs/ext4/inode.c | 11 ++---
fs/nfsd/lockd.c | 1 -
fs/nilfs2/file.c | 12 +++---
fs/ocfs2/aops.c | 6 +++
fs/quota/dquot.c | 13 ++----
fs/squashfs/dir.c | 9 ++++
fs/squashfs/namei.c | 12 +++++
fs/ubifs/commit.c | 2 +-
fs/ubifs/debug.c | 41 +++++++++++++++--
fs/ubifs/lpt.c | 7 +--
fs/xfs/xfs_fsops.c | 3 +
include/linux/binfmts.h | 5 ++
include/scsi/scsi_device.h | 2 +-
include/sound/soc-dapm.h | 16 +++---
kernel/kgdb.c | 9 +---
kernel/perf_event.c | 3 +-
kernel/signal.c | 4 +-
mm/mremap.c | 11 ++++-
net/ax25/af_ax25.c | 2 +-
net/bluetooth/bnep/sock.c | 1 +
net/bluetooth/sco.c | 1 +
net/bridge/netfilter/ebtables.c | 2 +
net/can/bcm.c | 4 +-
net/core/dev.c | 2 +
net/econet/af_econet.c | 8 +++-
net/ipv4/inet_diag.c | 27 +++++++-----
net/ipv4/netfilter/arp_tables.c | 3 +
net/ipv4/netfilter/ip_tables.c | 3 +
net/ipv4/netfilter/ipt_CLUSTERIP.c | 5 ++-
net/ipv6/netfilter/ip6_tables.c | 3 +
net/irda/af_irda.c | 16 ++++---
net/irda/iriap.c | 6 +++
net/irda/irnet/irnet_ppp.c | 3 +
net/mac80211/sta_info.c | 1 +
net/netfilter/nf_conntrack_h323_asn1.c | 2 +-
net/packet/af_packet.c | 3 +-
net/rds/rdma.c | 8 +++
net/rose/rose_subr.c | 18 +++++++-
net/sctp/sm_make_chunk.c | 17 ++++---
net/tipc/socket.c | 1 +
sound/core/init.c | 4 ++
sound/oss/dev_table.h | 2 +-
sound/oss/midi_synth.c | 34 +++++++--------
sound/oss/midi_synth.h | 2 +-
sound/oss/opl3.c | 23 ++++++---
sound/oss/sequencer.c | 2 +-
sound/pci/ens1370.c | 23 ++++++++--
sound/pci/hda/patch_realtek.c | 2 +-
88 files changed, 652 insertions(+), 242 deletions(-)
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Takashi Iwai <[email protected]>
commit a45e3d6b13e97506b616980c0f122c3389bcefa4 upstream.
This patch fixes a race between snd_card_file_remove() and
snd_card_disconnect(). When the card is added to shutdown_files list
in snd_card_disconnect(), but it's freed in snd_card_file_remove() at
the same time, the shutdown_files list gets corrupted. The list member
must be freed in snd_card_file_remove() as well.
Reported-and-tested-by: Russ Dill <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/core/init.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -848,6 +848,7 @@ int snd_card_file_add(struct snd_card *c
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
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Tyler Hicks <[email protected]>
commit 50f198ae16ac66508d4b8d5a40967a8507ad19ee upstream.
Unlock the page in error path of ecryptfs_write_begin(). This may
happen, for example, if decryption fails while bring the page
up-to-date.
Signed-off-by: Tyler Hicks <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ecryptfs/mmap.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -372,6 +372,11 @@ static int ecryptfs_write_begin(struct f
&& (pos != 0))
zero_user(page, 0, PAGE_CACHE_SIZE);
out:
+ if (unlikely(rc)) {
+ unlock_page(page);
+ page_cache_release(page);
+ *pagep = NULL;
+ }
return rc;
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Ryusuke Konishi <[email protected]>
commit 34094537943113467faee98fe67c8a3d3f9a0a8b upstream.
>From the result of a function test of mmap, mmap write to shared pages
turned out to be broken for hole blocks. It doesn't write out filled
blocks and the data will be lost after umount. This is due to a bug
that the target file is not queued for log writer when filling hole
blocks.
Also, nilfs_page_mkwrite function exits normal code path even after
successfully filled hole blocks due to a change of block_page_mkwrite
function; just after nilfs was merged into the mainline,
block_page_mkwrite() started to return VM_FAULT_LOCKED instead of zero
by the patch "mm: close page_mkwrite races" (commit:
b827e496c893de0c). The current nilfs_page_mkwrite() is not handling
this value properly.
This corrects nilfs_page_mkwrite() and will resolve the data loss
problem in mmap write.
[This should be applied to every kernel since 2.6.30 but a fix is
needed for 2.6.37 and prior kernels]
Signed-off-by: Ryusuke Konishi <[email protected]>
Tested-by: Ryusuke Konishi <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/nilfs2/file.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -72,10 +72,9 @@ static int nilfs_page_mkwrite(struct vm_
/*
* 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_
if (fully_mapped) {
SetPageMappedToDisk(page);
- unlock_page(page);
goto mapped;
}
}
@@ -105,16 +103,18 @@ static int nilfs_page_mkwrite(struct vm_
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 = {
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Bud Brown <[email protected]>
commit 1ddd5049545e0aa1a0ed19bca4d9c9c3ce1ac8a2 upstream.
Under certain workloads a command may seem to get lost. IOW, the Smart Array
thinks all commands have been completed but we still have commands in our
completion queue. This may lead to system instability, filesystems going
read-only, or even panics depending on the affected filesystem. We add an
extra read to force the write to complete.
Testing shows this extra read avoids the problem.
Signed-off-by: Mike Miller <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/block/cciss.h | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -165,6 +165,7 @@ static void SA5_submit_command( ctlr_inf
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Felix Fietkau <[email protected]>
commit 8bc8aecdc5e26cfda12dbd6867af4aa67836da6a upstream.
This field is used to determine the inactivity time. When in AP mode,
hostapd uses it for kicking out inactive clients after a while. Without this
patch, hostapd immediately deauthenticates a new client if it checks the
inactivity time before the client sends its first data frame.
Signed-off-by: Felix Fietkau <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/mac80211/sta_info.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -276,6 +276,7 @@ struct sta_info *sta_info_alloc(struct i
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,
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Roberto Sassu <[email protected]>
commit 1821df040ac3cd6a57518739f345da6d50ea9d3f upstream.
The pointer '(*auth_tok_key)' is set to NULL in case request_key()
fails, in order to prevent its use by functions calling
ecryptfs_keyring_auth_tok_for_sig().
Signed-off-by: Roberto Sassu <[email protected]>
Signed-off-by: Tyler Hicks <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ecryptfs/keystore.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1542,6 +1542,7 @@ int ecryptfs_keyring_auth_tok_for_sig(st
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Christian Lamparter <[email protected]>
commit 220107610c7c2c9703e09eb363e8ab31025b9315 upstream.
Reported-by: Mark Davis [via p54/devices wiki]
Signed-off-by: Christian Lamparter <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/p54/p54usb.c | 2 ++
1 file changed, 2 insertions(+)
--- 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[]
{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[]
{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 */
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 42eab94fff18cb1091d3501cd284d6bd6cc9c143 upstream.
Structures ipt_replace, compat_ipt_replace, and xt_get_revision are
copied from userspace. Fields of these structs that are
zero-terminated strings are not checked. When they are used as argument
to a format string containing "%s" in request_module(), some sensitive
information is leaked to userspace via argument of spawned modprobe
process.
The first bug was introduced before the git epoch; the second is
introduced by 6b7d31fc (v2.6.15-rc1); the third is introduced by
6b7d31fc (v2.6.15-rc1). To trigger the bug one should have
CAP_NET_ADMIN.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/ipv4/netfilter/arp_tables.c | 3 +++
1 file changed, 3 insertions(+)
--- 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, v
/* 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
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 *
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),
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit fdac1e0697356ac212259f2147aa60c72e334861 upstream.
If the user-provided len is less than the expected offset, the
IRLMP_ENUMDEVICES getsockopt will do a copy_to_user() with a very large
size value. While this isn't be a security issue on x86 because it will
get caught by the access_ok() check, it may leak large amounts of kernel
heap on other architectures. In any event, this patch fixes it.
Signed-off-by: Dan Rosenberg <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/irda/af_irda.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -2164,6 +2164,14 @@ static int irda_getsockopt(struct socket
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
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)
{
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Nelson Elhage <[email protected]>
commit 22e76c849d505d87c5ecf3d3e6742a65f0ff4860 upstream.
We were using nlmsg_find_attr() to look up the bytecode by attribute when
auditing, but then just using the first attribute when actually running
bytecode. So, if we received a message with two attribute elements, where only
the second had type INET_DIAG_REQ_BYTECODE, we would validate and run different
bytecode strings.
Fix this by consistently using nlmsg_find_attr everywhere.
Signed-off-by: Nelson Elhage <[email protected]>
Signed-off-by: Thomas Graf <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
[jmm: Slightly adapted to apply against 2.6.32]
Cc: Moritz Muehlenhoff <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/ipv4/inet_diag.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -489,9 +489,11 @@ static int inet_csk_diag_dump(struct soc
{
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 soc
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 in
{
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 in
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
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
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
&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;
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 67286640f638f5ad41a946b9a3dc75327950248f upstream.
packet_getname_spkt() doesn't initialize all members of sa_data field of
sockaddr struct if strlen(dev->name) < 13. This structure is then copied
to userland. It leads to leaking of contents of kernel stack memory.
We have to fully fill sa_data with strncpy() instead of strlcpy().
The same with packet_getname(): it doesn't initialize sll_pkttype field of
sockaddr_ll. Set it to zero.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
[jmm: Backported to 2.6.32]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/packet/af_packet.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1526,7 +1526,7 @@ static int packet_getname_spkt(struct so
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
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 9f260e0efa4766e56d0ac14f1aeea6ee5eb8fe83 upstream.
Since the socket address is just being used as a unique identifier, its
inode number is an alternative that does not leak potentially sensitive
information.
CC-ing stable because MITRE has assigned CVE-2010-4565 to the issue.
Signed-off-by: Dan Rosenberg <[email protected]>
Acked-by: Oliver Hartkopp <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/can/bcm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- 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 *so
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit 1b1f693d7ad6d193862dcb1118540a030c5e761f upstream.
As reported by Thomas Pollet, the rdma page counting can overflow. We
get the rdma sizes in 64-bit unsigned entities, but then limit it to
UINT_MAX bytes and shift them down to pages (so with a possible "+1" for
an unaligned address).
So each individual page count fits comfortably in an 'unsigned int' (not
even close to overflowing into signed), but as they are added up, they
might end up resulting in a signed return value. Which would be wrong.
Catch the case of tot_pages turning negative, and return the appropriate
error code.
Reported-by: Thomas Pollet <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Andy Grover <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/rds/rdma.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -473,6 +473,14 @@ static struct rds_rdma_op *rds_rdma_prep
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: David S. Miller <[email protected]>
commit 4e085e76cbe558b79b54cbab772f61185879bc64 upstream.
Unconditional use of skb->dev won't work here,
try to fetch the econet device via skb_dst()->dev
instead.
Suggested by Eric Dumazet.
Reported-by: Nelson Elhage <[email protected]>
Tested-by: Nelson Elhage <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
[jmm: Slightly adapted for 2.6.32]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/econet/af_econet.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -843,9 +843,13 @@ static void aun_incoming(struct sk_buff
{
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Oleg Nesterov <[email protected]>
commit 114279be2120a916e8a04feeb2ac976a10016f2f upstream.
Note: this patch targets 2.6.37 and tries to be as simple as possible.
That is why it adds more copy-and-paste horror into fs/compat.c and
uglifies fs/exec.c, this will be cleanuped later.
compat_copy_strings() plays with bprm->vma/mm directly and thus has
two problems: it lacks the RLIMIT_STACK check and argv/envp memory
is not visible to oom killer.
Export acct_arg_size() and get_arg_page(), change compat_copy_strings()
to use get_arg_page(), change compat_do_execve() to do acct_arg_size(0)
as do_execve() does.
Add the fatal_signal_pending/cond_resched checks into compat_count() and
compat_copy_strings(), this matches the code in fs/exec.c and certainly
makes sense.
Signed-off-by: Oleg Nesterov <[email protected]>
Cc: KOSAKI Motohiro <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/compat.c | 28 +++++++++++++++-------------
fs/exec.c | 8 ++++----
include/linux/binfmts.h | 4 ++++
3 files changed, 23 insertions(+), 17 deletions(-)
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1353,6 +1353,10 @@ static int compat_count(compat_uptr_t __
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,
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,
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) {
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -159,7 +159,7 @@ out:
#ifdef CONFIG_MMU
-static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
{
struct mm_struct *mm = current->mm;
long diff = (long)(pages - bprm->vma_pages);
@@ -174,7 +174,7 @@ static void acct_arg_size(struct linux_b
up_write(&mm->mmap_sem);
}
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
int write)
{
struct page *page;
@@ -291,11 +291,11 @@ static bool valid_arg_len(struct linux_b
#else
-static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
{
}
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
int write)
{
struct page *page;
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -60,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)
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Oleg Nesterov <[email protected]>
commit 3c77f845722158206a7209c45ccddc264d19319c upstream.
Brad Spengler published a local memory-allocation DoS that
evades the OOM-killer (though not the virtual memory RLIMIT):
http://www.grsecurity.net/~spender/64bit_dos.c
execve()->copy_strings() can allocate a lot of memory, but
this is not visible to oom-killer, nobody can see the nascent
bprm->mm and take it into account.
With this patch get_arg_page() increments current's MM_ANONPAGES
counter every time we allocate the new page for argv/envp. When
do_execve() succeds or fails, we change this counter back.
Technically this is not 100% correct, we can't know if the new
page is swapped out and turn MM_ANONPAGES into MM_SWAPENTS, but
I don't think this really matters and everything becomes correct
once exec changes ->mm or fails.
Reported-by: Brad Spengler <[email protected]>
Reviewed-and-discussed-by: KOSAKI Motohiro <[email protected]>
Signed-off-by: Oleg Nesterov <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/exec.c | 28 ++++++++++++++++++++++++++--
include/linux/binfmts.h | 1 +
2 files changed, 27 insertions(+), 2 deletions(-)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -159,6 +159,21 @@ out:
#ifdef CONFIG_MMU
+static 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);
+}
+
static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
int write)
{
@@ -181,6 +196,8 @@ static struct page *get_arg_page(struct
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,6 +291,10 @@ static bool valid_arg_len(struct linux_b
#else
+static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+}
+
static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
int write)
{
@@ -981,6 +1002,7 @@ int flush_old_exec(struct linux_binprm *
/*
* 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) {
--- 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];
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
This reverts upstream commit e5f15b45ddf3afa2bbbb10c7ea34fb32b6de0a0e
It caused problems in the stable tree and should not have been there.
Cc: Yinghai Lu <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/x86/kernel/head64.c | 3 +++
arch/x86/kernel/setup.c | 5 -----
arch/x86/mm/init.c | 19 +++++++++++++++++++
arch/x86/mm/init_64.c | 11 +++++------
4 files changed, 27 insertions(+), 11 deletions(-)
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -76,6 +76,9 @@ void __init x86_64_start_kernel(char * r
/* 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]);
--- 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 */
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -287,6 +287,25 @@ unsigned long __init_refok init_memory_m
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)
--- 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(unsign
* 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)
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: J. Bruce Fields <[email protected]>
commit 954032d2527f2fce7355ba70709b5e143d6b686f upstream.
This was noticed by users who performed more than 2^32 lock operations
and hence made this counter overflow (eventually leading to
use-after-free's). Setting rq_client to NULL here means that it won't
later get auth_domain_put() when it should be.
Appears to have been introduced in 2.5.42 by "[PATCH] kNFSd: Move auth
domain lookup into svcauth" which moved most of the rq_client handling
to common svcauth code, but left behind this one line.
Cc: Neil Brown <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/nfsd/lockd.c | 1 -
1 file changed, 1 deletion(-)
--- a/fs/nfsd/lockd.c
+++ b/fs/nfsd/lockd.c
@@ -44,7 +44,6 @@ nlm_fopen(struct svc_rqst *rqstp, struct
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..
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Philip A. Prindeville <[email protected]>
commit 18b429e74eeafe42e947b1b0f9a760c7153a0b5c upstream.
Omit pkt_hdr preamble when dumping transmitted packet as hex-dump;
we can pull this up because the frame has already been sent, and
dumping it is the last thing we do with it before freeing it.
Also include the size, vpi, and vci in the debug as is done on
receive.
Use "port" consistently instead of "device" intermittently.
Signed-off-by: Philip Prindeville <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/atm/solos-pci.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- 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_car
/* 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);
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Kulikov Vasiliy <[email protected]>
commit 88f8a5e3e7defccd3925cabb1ee4d3994e5cdb52 upstream.
Structure sockaddr_tipc is copied to userland with padding bytes after
"id" field in union field "name" unitialized. It leads to leaking of
contents of kernel stack memory. We have to initialize them to zero.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/tipc/socket.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -393,6 +393,7 @@ static int get_name(struct socket *sock,
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)))
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Yongqiang Yang <[email protected]>
commit 5b41395fcc0265fc9f193aef9df39ce49d64677c upstream.
When writing a contiguous set of blocks, two indirect blocks could be
needed depending on how the blocks are aligned, so we need to increase
the number of credits needed by one.
[ Also fixed a another bug which could further underestimate the
number of journal credits needed by 1; the code was using integer
division instead of DIV_ROUND_UP() -- tytso]
Signed-off-by: Yongqiang Yang <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ext4/inode.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5458,13 +5458,12 @@ static int ext4_indirect_trans_blocks(st
/* 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
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Kamalesh Babulal <[email protected]>
powerpc: Fix default_machine_crash_shutdown #ifdef botch
Commit: c2be05481f6125254c45b78f334d4dd09c701c82 upstream
crash_kexec_wait_realmode() is defined only if CONFIG_PPC_STD_MMU_64
and CONFIG_SMP, but is called if CONFIG_PPC_STD_MMU_64 even if !CONFIG_SMP.
Fix the conditional compilation around the invocation.
Reported-by: Ben Hutchings <[email protected]>
Signed-off-by: Paul E. McKenney <[email protected]>
Acked-by: Michael Neuling <[email protected]>
Signed-off-by: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Kamalesh Babulal <[email protected]>
cc: Anton Blanchard <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/powerpc/kernel/crash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -447,7 +447,7 @@ void default_machine_crash_shutdown(stru
crash_kexec_prepare_cpus(crashing_cpu);
cpu_set(crashing_cpu, cpus_in_crash);
crash_kexec_stop_spus();
-#ifdef CONFIG_PPC_STD_MMU_64
+#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
crash_kexec_wait_realmode(crashing_cpu);
#endif
if (ppc_md.kexec_cpu_down)
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Wei Yongjun <[email protected]>
commit a8170c35e738d62e9919ce5b109cf4ed66e95bde upstream.
When calculating the INIT/INIT-ACK chunk length, we should not
only account the length of parameters, but also the parameters
zero padding length, such as AUTH HMACS parameter and CHUNKS
parameter. Without the parameters zero padding length we may get
following oops.
skb_over_panic: text:ce2068d2 len:130 put:6 head:cac3fe00 data:cac3fe00 tail:0xcac3fe82 end:0xcac3fe80 dev:<NULL>
------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:127!
invalid opcode: 0000 [#2] SMP
last sysfs file: /sys/module/aes_generic/initstate
Modules linked in: authenc ......
Pid: 4102, comm: sctp_darn Tainted: G D 2.6.34-rc2 #6
EIP: 0060:[<c0607630>] EFLAGS: 00010282 CPU: 0
EIP is at skb_over_panic+0x37/0x3e
EAX: 00000078 EBX: c07c024b ECX: c07c02b9 EDX: cb607b78
ESI: 00000000 EDI: cac3fe7a EBP: 00000002 ESP: cb607b74
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process sctp_darn (pid: 4102, ti=cb607000 task=cabdc990 task.ti=cb607000)
Stack:
c07c02b9 ce2068d2 00000082 00000006 cac3fe00 cac3fe00 cac3fe82 cac3fe80
<0> c07c024b cac3fe7c cac3fe7a c0608dec ca986e80 ce2068d2 00000006 0000007a
<0> cb8120ca ca986e80 cb812000 00000003 cb8120c4 ce208a25 cb8120ca cadd9400
Call Trace:
[<ce2068d2>] ? sctp_addto_chunk+0x45/0x85 [sctp]
[<c0608dec>] ? skb_put+0x2e/0x32
[<ce2068d2>] ? sctp_addto_chunk+0x45/0x85 [sctp]
[<ce208a25>] ? sctp_make_init+0x279/0x28c [sctp]
[<c0686a92>] ? apic_timer_interrupt+0x2a/0x30
[<ce1fdc0b>] ? sctp_sf_do_prm_asoc+0x2b/0x7b [sctp]
[<ce202823>] ? sctp_do_sm+0xa0/0x14a [sctp]
[<ce2133b9>] ? sctp_pname+0x0/0x14 [sctp]
[<ce211d72>] ? sctp_primitive_ASSOCIATE+0x2b/0x31 [sctp]
[<ce20f3cf>] ? sctp_sendmsg+0x7a0/0x9eb [sctp]
[<c064eb1e>] ? inet_sendmsg+0x3b/0x43
[<c04244b7>] ? task_tick_fair+0x2d/0xd9
[<c06031e1>] ? sock_sendmsg+0xa7/0xc1
[<c0416afe>] ? smp_apic_timer_interrupt+0x6b/0x75
[<c0425123>] ? dequeue_task_fair+0x34/0x19b
[<c0446abb>] ? sched_clock_local+0x17/0x11e
[<c052ea87>] ? _copy_from_user+0x2b/0x10c
[<c060ab3a>] ? verify_iovec+0x3c/0x6a
[<c06035ca>] ? sys_sendmsg+0x186/0x1e2
[<c042176b>] ? __wake_up_common+0x34/0x5b
[<c04240c2>] ? __wake_up+0x2c/0x3b
[<c057e35c>] ? tty_wakeup+0x43/0x47
[<c04430f2>] ? remove_wait_queue+0x16/0x24
[<c0580c94>] ? n_tty_read+0x5b8/0x65e
[<c042be02>] ? default_wake_function+0x0/0x8
[<c0604e0e>] ? sys_socketcall+0x17f/0x1cd
[<c040264c>] ? sysenter_do_call+0x12/0x22
Code: 0f 45 de 53 ff b0 98 00 00 00 ff b0 94 ......
EIP: [<c0607630>] skb_over_panic+0x37/0x3e SS:ESP 0068:cb607b74
To reproduce:
# modprobe sctp
# echo 1 > /proc/sys/net/sctp/addip_enable
# echo 1 > /proc/sys/net/sctp/auth_enable
# sctp_test -H 3ffe:501:ffff:100:20c:29ff:fe4d:f37e -P 800 -l
# sctp_darn -H 3ffe:501:ffff:100:20c:29ff:fe4d:f37e -P 900 -h 192.168.0.21 -p 800 -I -s -t
sctp_darn ready to send...
3ffe:501:ffff:100:20c:29ff:fe4d:f37e:900-192.168.0.21:800 Interactive mode> bindx-add=192.168.0.21
3ffe:501:ffff:100:20c:29ff:fe4d:f37e:900-192.168.0.21:800 Interactive mode> bindx-add=192.168.1.21
3ffe:501:ffff:100:20c:29ff:fe4d:f37e:900-192.168.0.21:800 Interactive mode> snd=10
------------------------------------------------------------------
eth0 has addresses: 3ffe:501:ffff:100:20c:29ff:fe4d:f37e and 192.168.0.21
eth1 has addresses: 192.168.1.21
------------------------------------------------------------------
Reported-by: George Cheimonidis <[email protected]>
Signed-off-by: Wei Yongjun <[email protected]>
Signed-off-by: Vlad Yasevich <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/sctp/sm_make_chunk.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
--- 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
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
/* 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
/* 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(co
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(co
}
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit fe10ae53384e48c51996941b7720ee16995cbcb7 upstream.
Sometimes ax25_getname() doesn't initialize all members of fsa_digipeater
field of fsa struct, also the struct has padding bytes between
sax25_call and sax25_ndigis fields. This structure is then copied to
userland. It leads to leaking of contents of kernel stack memory.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Moritz Muehlenhoff <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/ax25/af_ax25.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1391,6 +1391,7 @@ static int ax25_getname(struct socket *s
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 *s
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Phillip Lougher <[email protected]>
commit 44cff8a9ee8a974f9e931df910688e7fc1f0b0f9 upstream.
Handle the rare case where a directory metadata block is uncompressed and
corrupted, leading to a kernel oops in directory scanning (memcpy).
Normally corruption is detected at the decompression stage and dealt with
then, however, this will not happen if:
- metadata isn't compressed (users can optionally request no metadata
compression), or
- the compressed metadata block was larger than the original, in which
case the uncompressed version was used, or
- the data was corrupt after decompression
This patch fixes this by adding some sanity checks against known maximum
values.
Signed-off-by: Phillip Lougher <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/squashfs/dir.c | 9 +++++++++
fs/squashfs/namei.c | 12 ++++++++++++
2 files changed, 21 insertions(+)
--- a/fs/squashfs/dir.c
+++ b/fs/squashfs/dir.c
@@ -173,6 +173,11 @@ static int squashfs_readdir(struct file
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
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)
--- a/fs/squashfs/namei.c
+++ b/fs/squashfs/namei.c
@@ -175,6 +175,11 @@ static struct dentry *squashfs_lookup(st
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(st
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,
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Peter Huewe <[email protected]>
commit 1309d7afbed112f0e8e90be9af975550caa0076b upstream.
This patch fixes information leakage to the userspace by initializing
the data buffer to zero.
Reported-by: Peter Huewe <[email protected]>
Signed-off-by: Peter Huewe <[email protected]>
Signed-off-by: Marcel Selhorst <[email protected]>
[ Also removed the silly "* sizeof(u8)". If that isn't 1, we have way
deeper problems than a simple multiplication can fix. - Linus ]
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/tpm/tpm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -969,7 +969,7 @@ int tpm_open(struct inode *inode, struct
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Kamalesh Babulal <[email protected]>
powerpc/kexec: Add ifdef CONFIG_PPC_STD_MMU_64 to PPC64 code
This patch introduces PPC64 specific #ifdef bits from the upstream
commit: b3df895aebe091b1657a42a8c859bd49fc96646b.
Reported-and-tested-by: dann frazier <[email protected]>
Signed-off-by: Kumar Gala <[email protected]>
Signed-off-by: Kamalesh Babulal <[email protected]>
cc: Benjamin Herrenschmidt <[email protected]>
cc: Anton Blanchard <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/powerpc/kernel/crash.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int
}
/* 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(in
}
mb();
}
+#endif
/*
* This function will be called by secondary cpus or by kexec cpu
@@ -445,7 +447,9 @@ void default_machine_crash_shutdown(stru
crash_kexec_prepare_cpus(crashing_cpu);
cpu_set(crashing_cpu, cpus_in_crash);
crash_kexec_stop_spus();
+#ifdef CONFIG_PPC_STD_MMU_64
crash_kexec_wait_realmode(crashing_cpu);
+#endif
if (ppc_md.kexec_cpu_down)
ppc_md.kexec_cpu_down(1, 0);
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Borislav Petkov <[email protected]>
Upstream commit: 44d60c0f5c58c2168f31df9a481761451840eb54
The different families have a different max size for the ucode patch,
adjust size checking to the family we're running on. Also, do not
vzalloc the max size of the ucode but only the actual size that is
passed on from the firmware loader.
Cc: <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/x86/kernel/microcode_amd.c | 63 +++++++++++++++++++++++++++-------------
1 file changed, 44 insertions(+), 19 deletions(-)
--- 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
@@ -125,6 +124,37 @@ static int get_matching_microcode(int cp
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;
@@ -164,11 +194,11 @@ static int get_ucode_data(void *to, cons
}
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;
@@ -179,23 +209,18 @@ get_next_ucode(const u8 *buf, unsigned i
return NULL;
}
- total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
+ 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;
}
@@ -264,7 +289,7 @@ generic_load_microcode(int cpu, const u8
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit f8a0697722d12a201588225999cfc8bfcbc82781 upstream.
Don't allow everybody to change device hardware registers.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/mfd/ab3100-core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -591,7 +591,7 @@ static void ab3100_setup_debugfs(struct
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_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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Andreas Herrmann <[email protected]>
Upstream commit: 6e18da75c28b592594fd632cf3e6eb09d3d078de
Signed-off-by: Andreas Herrmann <[email protected]>
Cc: Borislav Petkov <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/x86/kernel/microcode_amd.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -109,12 +109,8 @@ static int get_matching_microcode(int cp
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) {
@@ -185,9 +181,6 @@ get_next_ucode(const u8 *buf, unsigned i
total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
- printk(KERN_DEBUG "microcode: size %u, total_size %u\n",
- size, total_size);
-
if (total_size > size || total_size > UCODE_MAX_SIZE) {
printk(KERN_ERR "microcode: error: size mismatch\n");
return NULL;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 78b79876761b86653df89c48a7010b5cbd41a84a upstream.
Structures ipt_replace, compat_ipt_replace, and xt_get_revision are
copied from userspace. Fields of these structs that are
zero-terminated strings are not checked. When they are used as argument
to a format string containing "%s" in request_module(), some sensitive
information is leaked to userspace via argument of spawned modprobe
process.
The first and the third bugs were introduced before the git epoch; the
second was introduced in 2722971c (v2.6.17-rc1). To trigger the bug
one should have CAP_NET_ADMIN.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/ipv4/netfilter/ip_tables.c | 3 +++
1 file changed, 3 insertions(+)
--- 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
/* 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
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,
ret = -EFAULT;
break;
}
+ rev.name[sizeof(rev.name)-1] = 0;
if (cmd == IPT_SO_GET_REVISION_TARGET)
target = 1;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Andy Gospodarek <[email protected]>
commit 6d152e23ad1a7a5b40fef1f42e017d66e6115159 upstream.
Like Herbert's change from a few days ago:
66c46d741e2e60f0e8b625b80edb0ab820c46d7a gro: Reset dev pointer on reuse
this may not be necessary at this point, but we should still clean up
the skb->skb_iif. If not we may end up with an invalid valid for
skb->skb_iif when the skb is reused and the check is done in
__netif_receive_skb.
Signed-off-by: Andy Gospodarek <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Brandon Philips <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/core/dev.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2615,6 +2615,7 @@ void napi_reuse_skb(struct napi_struct *
__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;
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
commit 66c46d741e2e60f0e8b625b80edb0ab820c46d7a upstream.
On older kernels the VLAN code may zero skb->dev before dropping
it and causing it to be reused by GRO.
Unfortunately we didn't reset skb->dev in that case which causes
the next GRO user to get a bogus skb->dev pointer.
This particular problem no longer happens with the current upstream
kernel due to changes in VLAN processing.
However, for correctness we should still reset the skb->dev pointer
in the GRO reuse function in case a future user does the same thing.
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Brandon Philips <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/core/dev.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2614,6 +2614,7 @@ void napi_reuse_skb(struct napi_struct *
{
__skb_pull(skb, skb_headlen(skb));
skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
+ skb->dev = napi->dev;
napi->skb = skb;
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Jason Wessel <[email protected]>
commit fb82c0ff27b2c40c6f7a3d1a94cafb154591fa80 upstream.
The gdbserial protocol handler should return an empty packet instead
of an error string when ever it responds to a command it does not
implement.
The problem cases come from a debugger client sending
qTBuffer, qTStatus, qSearch, qSupported.
The incorrect response from the gdbstub leads the debugger clients to
not function correctly. Recent versions of gdb will not detach correctly as a result of this behavior.
Backport-request-by: Frank Pan <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
Signed-off-by: Dongdong Deng <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/kgdb.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -1001,10 +1001,8 @@ static void gdb_cmd_query(struct kgdb_st
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_st
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Kulikov Vasiliy <[email protected]>
commit b3390ceab95601afc12213c3ec5551d3bc7b638f upstream.
get_user() may fail, if so return -EFAULT.
Signed-off-by: Kulikov Vasiliy <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/oss/midi_synth.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/sound/oss/midi_synth.c
+++ b/sound/oss/midi_synth.c
@@ -519,7 +519,9 @@ midi_synth_load_patch(int dev, int forma
{
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 */
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit b769f49463711205d57286e64cf535ed4daf59e9 upstream.
Was: [PATCH] sound/oss/midi_synth: prevent underflow, use of
uninitialized value, and signedness issue
The offset passed to midi_synth_load_patch() can be essentially
arbitrary. If it's greater than the header length, this will result in
a copy_from_user(dst, src, negative_val). While this will just return
-EFAULT on x86, on other architectures this may cause memory corruption.
Additionally, the length field of the sysex_info structure may not be
initialized prior to its use. Finally, a signed comparison may result
in an unintentionally large loop.
On suggestion by Takashi Iwai, version two removes the offset argument
from the load_patch callbacks entirely, which also resolves similar
issues in opl3. Compile tested only.
v3 adjusts comments and hopefully gets copy offsets right.
Signed-off-by: Dan Rosenberg <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/oss/dev_table.h | 2 +-
sound/oss/midi_synth.c | 30 +++++++++++++-----------------
sound/oss/midi_synth.h | 2 +-
sound/oss/opl3.c | 8 ++------
sound/oss/sequencer.c | 2 +-
5 files changed, 18 insertions(+), 26 deletions(-)
--- 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);
--- 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,33 +491,29 @@ midi_synth_load_patch(int dev, int forma
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++)
{
--- 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);
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -819,7 +819,7 @@ static void opl3_hw_control(int dev, uns
}
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
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)
--- a/sound/oss/sequencer.c
+++ b/sound/oss/sequencer.c
@@ -241,7 +241,7 @@ int sequencer_write(int dev, struct file
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 6a8ab060779779de8aea92ce3337ca348f973f54 upstream.
Structures ip6t_replace, compat_ip6t_replace, and xt_get_revision are
copied from userspace. Fields of these structs that are
zero-terminated strings are not checked. When they are used as argument
to a format string containing "%s" in request_module(), some sensitive
information is leaked to userspace via argument of spawned modprobe
process.
The first bug was introduced before the git epoch; the second was
introduced in 3bc3fe5e (v2.6.25-rc1); the third is introduced by
6b7d31fc (v2.6.15-rc1). To trigger the bug one should have
CAP_NET_ADMIN.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/ipv6/netfilter/ip6_tables.c | 3 +++
1 file changed, 3 insertions(+)
--- 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
/* 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
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
ret = -EFAULT;
break;
}
+ rev.name[sizeof(rev.name)-1] = 0;
if (cmd == IP6T_SO_GET_REVISION_TARGET)
target = 1;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: David Sterba <[email protected]>
commit b4232a22776aa5d063f890d21ca69870dbbe431b upstream.
Static analyzer of clang found a dead store which appears to be a bug in
reading count of items in SEQOF field, only the lower byte of word is
stored. This may lead to corrupted read and communication shutdown.
The bug has been in the module since it's first inclusion into linux
kernel.
[Patrick: the bug is real, but without practical consequence since the
largest amount of sequence-of members we parse is 30.]
Signed-off-by: David Sterba <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/netfilter/nf_conntrack_h323_asn1.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/netfilter/nf_conntrack_h323_asn1.c
+++ b/net/netfilter/nf_conntrack_h323_asn1.c
@@ -631,7 +631,7 @@ static int decode_seqof(bitstr_t *bs, co
CHECK_BOUND(bs, 2);
count = *bs->cur++;
count <<= 8;
- count = *bs->cur++;
+ count += *bs->cur++;
break;
case SEMI:
BYTE_ALIGN(bs);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 67c5c6cb8129c595f21e88254a3fc6b3b841ae8e upstream.
struct aunhdr has 4 padding bytes between 'pad' and 'handle' fields on
x86_64. These bytes are not initialized in the variable 'ah' before
sending 'ah' to the network. This leads to 4 bytes kernel stack
infoleak.
This bug was introduced before the git epoch.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Acked-by: Phil Blundell <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/econet/af_econet.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -428,10 +428,10 @@ static int econet_sendmsg(struct kiocb *
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 961ed183a9fd080cf306c659b8736007e44065a5 upstream.
'buffer' string is copied from userspace. It is not checked whether it is
zero terminated. This may lead to overflow inside of simple_strtoul().
Changli Gao suggested to copy not more than user supplied 'size' bytes.
It was introduced before the git epoch. Files "ipt_CLUSTERIP/*" are
root writable only by default, however, on some setups permissions might be
relaxed to e.g. network admin user.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Acked-by: Changli Gao <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/ipv4/netfilter/ipt_CLUSTERIP.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -666,8 +666,11 @@ static ssize_t clusterip_proc_write(stru
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit deb187e72470b0382d4f0cb859e76e1ebc3a1082 upstream.
Don't allow everybody to change device settings.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Acked-by: Hartley Sweeten <[email protected]>
Cc: Matthieu Crapet <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/misc/ep93xx_pwm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/misc/ep93xx_pwm.c
+++ b/drivers/misc/ep93xx_pwm.c
@@ -248,11 +248,11 @@ static ssize_t ep93xx_pwm_set_invert(str
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[] = {
Am 13.04.2011 17:51, schrieb Greg KH:
> 2.6.32-longterm review patch. If anyone has any objections, please let us know.
>
> ------------------
>
> From: David Sterba <[email protected]>
>
> commit b4232a22776aa5d063f890d21ca69870dbbe431b upstream.
>
> Static analyzer of clang found a dead store which appears to be a bug in
> reading count of items in SEQOF field, only the lower byte of word is
> stored. This may lead to corrupted read and communication shutdown.
>
> The bug has been in the module since it's first inclusion into linux
> kernel.
>
> [Patrick: the bug is real, but without practical consequence since the
> largest amount of sequence-of members we parse is 30.]
As mentioned in the changelog, I don't think this patch is of any
relevance for -stable since its a purely theoretical problem.
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 49d50fb1c28738ef6bad0c2b87d5355a1653fed5 upstream.
Don't allow everybogy to write to NVRAM.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Cc: Andy Sharp <[email protected]>
Cc: Alessandro Zummo <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/rtc/rtc-ds1511.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -480,7 +480,7 @@ ds1511_nvram_write(struct kobject *kobj,
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,
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Goldwyn Rodrigues <[email protected]>
commit 272b62c1f0f6f742046e45b50b6fec98860208a0 upstream.
When a hole spans across page boundaries, the next write forces
a read of the block. This could end up reading existing garbage
data from the disk in ocfs2_map_page_blocks. This leads to
non-zero holes. In order to avoid this, mark the writes as new
when the holes span across page boundaries.
Signed-off-by: Goldwyn Rodrigues <[email protected]>
Signed-off-by: jlbec <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ocfs2/aops.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1091,6 +1091,12 @@ static int ocfs2_prepare_page_for_write(
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Marc-Antoine Perennou <[email protected]>
commit 63a8588debd4dc72becb9e27add9343c76301c7d upstream.
Just adding the vendor details makes it work fine.
Signed-off-by: Marc-Antoine Perennou <[email protected]>
Signed-off-by: Gustavo F. Padovan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/bluetooth/btusb.c | 3 +++
1 file changed, 3 insertions(+)
--- 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) },
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
commit c85ce65ecac078ab1a1835c87c4a6319cf74660a upstream.
Otherwise, skb_put inside of dma_rx can fail...
https://bugzilla.kernel.org/show_bug.cgi?id=32042
Signed-off-by: John W. Linville <[email protected]>
Acked-by: Larry Finger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/b43/dma.c | 2 +-
drivers/net/wireless/b43/dma.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- 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 *r
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
--- 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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit d846f71195d57b0bbb143382647c2c6638b04c5a upstream.
Struct tmp is copied from userspace. It is not checked whether the "name"
field is NULL terminated. This may lead to buffer overflow and passing
contents of kernel stack as a module name to try_then_request_module() and,
consequently, to modprobe commandline. It would be seen by all userspace
processes.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/bridge/netfilter/ebtables.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -979,6 +979,8 @@ static int do_replace(struct net *net, v
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)
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 43629f8f5ea32a998d06d1bb41eefa0e821ff573 upstream.
Struct ca is copied from userspace. It is not checked whether the "device"
field is NULL terminated. This potentially leads to BUG() inside of
alloc_netdev_mqs() and/or information leak by creating a device with a name
made of contents of kernel stack.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: Gustavo F. Padovan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/bluetooth/bnep/sock.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -88,6 +88,7 @@ static int bnep_sock_ioctl(struct socket
sockfd_put(nsock);
return -EBADFD;
}
+ ca.device[sizeof(ca.device)-1] = 0;
err = bnep_add_connection(&ca, nsock);
if (!err) {
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Suresh Siddha <[email protected]>
commit 84ac7cdbdd0f04df6b96153f7a79127fd6e45467 upstream.
On laptops with core i5/i7, there were reports that after resume
graphics workloads were performing poorly on a specific AP, while
the other cpu's were ok. This was observed on a 32bit kernel
specifically.
Debug showed that the PAT init was not happening on that AP
during resume and hence it contributing to the poor workload
performance on that cpu.
On this system, resume flow looked like this:
1. BP starts the resume sequence and we reinit BP's MTRR's/PAT
early on using mtrr_bp_restore()
2. Resume sequence brings all AP's online
3. Resume sequence now kicks off the MTRR reinit on all the AP's.
4. For some reason, between point 2 and 3, we moved from BP
to one of the AP's. My guess is that printk() during resume
sequence is contributing to this. We don't see similar
behavior with the 64bit kernel but there is no guarantee that
at this point the remaining resume sequence (after AP's bringup)
has to happen on BP.
5. set_mtrr() was assuming that we are still on BP and skipped the
MTRR/PAT init on that cpu (because of 1 above)
6. But we were on an AP and this led to not reprogramming PAT
on this cpu leading to bad performance.
Fix this by doing unconditional mtrr_if->set_all() in set_mtrr()
during MTRR/PAT init. This might be unnecessary if we are still
running on BP. But it is of no harm and will guarantee that after
resume, all the cpu's will be in sync with respect to the
MTRR/PAT registers.
Signed-off-by: Suresh Siddha <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Eric Anholt <[email protected]>
Tested-by: Keith Packard <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/x86/kernel/cpu/mtrr/main.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
--- 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
/*
* 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 */
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit c4c896e1471aec3b004a693c689f60be3b17ac86 upstream.
struct sco_conninfo has one padding byte in the end. Local variable
cinfo of type sco_conninfo is copied to userspace with this uninizialized
one byte, leading to old stack contents leak.
Signed-off-by: Vasiliy Kulikov <[email protected]>
Signed-off-by: Gustavo F. Padovan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/bluetooth/sco.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -700,6 +700,7 @@ static int sco_sock_getsockopt_old(struc
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit 982134ba62618c2d69fbbbd166d0a11ee3b7e3d8 upstream.
The normal mmap paths all avoid creating a mapping where the pgoff
inside the mapping could wrap around due to overflow. However, an
expanding mremap() can take such a non-wrapping mapping and make it
bigger and cause a wrapping condition.
Noticed by Robert Swiecki when running a system call fuzzer, where it
caused a BUG_ON() due to terminally confusing the vma_prio_tree code. A
vma dumping patch by Hugh then pinpointed the crazy wrapped case.
Reported-and-tested-by: Robert Swiecki <[email protected]>
Acked-by: Hugh Dickins <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
mm/mremap.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -275,9 +275,16 @@ static struct vm_area_struct *vma_to_res
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) {
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Felix Fietkau <[email protected]>
commit f62d816fc4324afbb7cf90110c70b6a14139b225 upstream.
When the chip is still asleep when ath9k_start is called,
ath9k_hw_configpcipowersave can trigger a data bus error.
Signed-off-by: Felix Fietkau <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 4 ++++
1 file changed, 4 insertions(+)
--- 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_
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_
mutex_unlock:
mutex_unlock(&sc->mutex);
+ ath9k_ps_restore(sc);
+
return r;
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Jan Kara <[email protected]>
commit b03f24567ce7caf2420b8be4c6eb74c191d59a91 upstream.
There's no reason to write quota info in dquot_commit(). The writing is a
relict from the old days when we didn't have dquot_acquire() and
dquot_release() and thus dquot_commit() could have created / removed quota
structures from the file. These days dquot_commit() only updates usage counters
/ limits in quota structure and thus there's no need to write quota info.
This also fixes an issue with journaling filesystem which didn't reserve
enough space in the transaction for write of quota info (it could have been
dirty at the time of dquot_commit() because of a race with other operation
changing it).
Reported-and-tested-by: Lukas Czerner <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/quota/dquot.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
--- 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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Artem Bityutskiy <[email protected]>
commit 8b229c76765816796eec7ccd428f03bd8de8b525 upstream.
This fix makes the 'dbg_check_old_index()' function return
immediately if debugging is disabled, instead of executing
incorrect 'goto out' which causes UBIFS to:
1. Allocate memory
2. Read the flash
On every commit. OK, we do not commit that often, but it is
still silly to do unneeded I/O anyway.
Credits to coverity for spotting this silly issue.
Signed-off-by: Artem Bityutskiy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ubifs/commit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -518,7 +518,7 @@ int dbg_check_old_index(struct ubifs_inf
size_t sz;
if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX))
- goto out;
+ return 0;
INIT_LIST_HEAD(&list);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Artem Bityutskiy <[email protected]>
commit 7da6443aca9be29c6948dcbd636ad50154d0bc0c upstream.
This patch fixes a debugging failure with which looks like this:
UBIFS error (pid 32313): dbg_check_space_info: free space changed from 6019344 to 6022654
The reason for this failure is described in the comment this patch adds
to the code. But in short - 'c->freeable_cnt' may be different before
and after re-mounting, and this is normal. So the debugging code should
make sure that free space calculations do not depend on 'c->freeable_cnt'.
A similar issue has been reported here:
http://lists.infradead.org/pipermail/linux-mtd/2011-April/034647.html
This patch should fix it.
For the -stable guys: this patch is only relevant for kernels 2.6.30
onwards.
Signed-off-by: Artem Bityutskiy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ubifs/debug.c | 41 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 36 insertions(+), 5 deletions(-)
--- 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_in
{
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",
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Artem Bityutskiy <[email protected]>
commit 54acbaaa523ca0bd284a18f67ad213c379679e86 upstream.
Thanks to coverity which spotted that UBIFS will oops if 'kmalloc()'
in 'read_pnode()' fails and we dereference a NULL 'pnode' pointer
when we 'goto out'.
Signed-off-by: Artem Bityutskiy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/ubifs/lpt.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -1269,10 +1269,9 @@ static int read_pnode(struct ubifs_info
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
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Li Zefan <[email protected]>
commit 08fe4db170b4193603d9d31f40ebaf652d07ac9c upstream.
root_item->flags and root_item->byte_limit are not initialized when
a subvolume is created. This bug is not revealed until we added
readonly snapshot support - now you mount a btrfs filesystem and you
may find the subvolumes in it are readonly.
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.
When we read a tree root from disk, we check if the bit is set, and if
not we'll set the flag and initialize the two fields of the root item.
Reported-by: Andreas Philipp <[email protected]>
Signed-off-by: Li Zefan <[email protected]>
Tested-by: Andreas Philipp <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/btrfs/ctree.h | 4 ++++
fs/btrfs/disk-io.c | 4 +++-
fs/btrfs/ioctl.c | 4 ++++
fs/btrfs/root-tree.c | 18 ++++++++++++++++++
fs/btrfs/transaction.c | 1 +
5 files changed, 30 insertions(+), 1 deletion(-)
--- 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_r
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,
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1145,8 +1145,10 @@ struct btrfs_root *btrfs_read_fs_root_no
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;
}
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -285,6 +285,10 @@ static noinline int create_subvol(struct
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);
--- 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;
+ }
+}
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -777,6 +777,7 @@ static noinline int create_pending_snaps
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 */
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Mark Brown <[email protected]>
commit 0ca03cd7d0fa3bfbd56958136a10f19733c4ce12 upstream.
This stops code that handles widgets generically from attempting to access
registers for these widgets.
Signed-off-by: Mark Brown <[email protected]>
Acked-by: Liam Girdwood <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/sound/soc-dapm.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--- 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 */
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit be20250c13f88375345ad99950190685eda51eb8 upstream.
When parsing the FAC_NATIONAL_DIGIS facilities field, it's possible for
a remote host to provide more digipeaters than expected, resulting in
heap corruption. Check against ROSE_MAX_DIGIS to prevent overflows, and
abort facilities parsing on failure.
Additionally, when parsing the FAC_CCITT_DEST_NSAP and
FAC_CCITT_SRC_NSAP facilities fields, a remote host can provide a length
of less than 10, resulting in an underflow in a memcpy size, causing a
kernel panic due to massive heap corruption. A length of greater than
20 results in a stack overflow of the callsign array. Abort facilities
parsing on these invalid length values.
Signed-off-by: Dan Rosenberg <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/rose/rose_subr.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -289,10 +289,15 @@ static int rose_parse_national(unsigned
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 cha
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
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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Clemens Ladisch <[email protected]>
commit 6ebb8a4a43e34f999ab36f27f972f3cd751cda4f upstream.
To make the EV1938 chip work, add a magic bit and an extra delay.
Signed-off-by: Clemens Ladisch <[email protected]>
Tested-by: Tino Schmidt <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/ens1370.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rea
#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(struc
#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(struc
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_r
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_r
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_r
/* 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);
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit d50e7e3604778bfc2dc40f440e0742dbae399d54 upstream.
Invalid nicknames containing only spaces will result in an underflow in
a memcpy size calculation, subsequently destroying the heap and
panicking.
v2 also catches the case where the provided nickname is longer than the
buffer size, which can result in controllable heap corruption.
Signed-off-by: Dan Rosenberg <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/irda/irnet/irnet_ppp.c | 3 +++
1 file changed, 3 insertions(+)
--- 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';
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit d370af0ef7951188daeb15bae75db7ba57c67846 upstream.
Length fields provided by a peer for names and attributes may be longer
than the destination array sizes. Validate lengths to prevent stack
buffer overflows.
Signed-off-by: Dan Rosenberg <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/irda/iriap.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -655,10 +655,16 @@ static void iriap_getvaluebyclass_indica
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';
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit c4d0c3b097f7584772316ee4d64a09fe0e4ddfca upstream.
The FSGEOMETRY_V1 ioctl (and its compat equivalent) calls out to
xfs_fs_geometry() with a version number of 3. This code path does not
fill in the logsunit member of the passed xfs_fsop_geom_t, leading to
the leaking of four bytes of uninitialized stack data to potentially
unprivileged callers.
v2 switches to memset() to avoid future issues if structure members
change, on suggestion of Dave Chinner.
Signed-off-by: Dan Rosenberg <[email protected]>
Reviewed-by: Eugene Teo <[email protected]>
Signed-off-by: Alex Elder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/xfs/xfs_fsops.c | 3 +++
1 file changed, 3 insertions(+)
--- 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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Roland Dreier <[email protected]>
commit 243b422af9ea9af4ead07a8ad54c90d4f9b6081a upstream.
Commit da48524eb206 ("Prevent rt_sigqueueinfo and rt_tgsigqueueinfo
from spoofing the signal code") made the check on si_code too strict.
There are several legitimate places where glibc wants to queue a
negative si_code different from SI_QUEUE:
- This was first noticed with glibc's aio implementation, which wants
to queue a signal with si_code SI_ASYNCIO; the current kernel
causes glibc's tst-aio4 test to fail because rt_sigqueueinfo()
fails with EPERM.
- Further examination of the glibc source shows that getaddrinfo_a()
wants to use SI_ASYNCNL (which the kernel does not even define).
The timer_create() fallback code wants to queue signals with SI_TIMER.
As suggested by Oleg Nesterov <[email protected]>, loosen the check to
forbid only the problematic SI_TKILL case.
Reported-by: Klaus Dittrich <[email protected]>
Acked-by: Julien Tinnes <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/signal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2353,7 +2353,7 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t,
/* 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, pi
/* 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;
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Arjan Mels <[email protected]>
commit 1325f85fa49f57df034869de430f7c302ae23109 upstream.
The number_of_packets was not transmitted for RET_SUBMIT packets. The
linux client used the stored number_of_packet from the submitted
request. The windows userland client does not do this however and needs
to know the number_of_packets to determine the size of the transmission.
Signed-off-by: Arjan Mels <[email protected]>
Cc: Takahiro Hirofuchi <[email protected]>
Cc: Max Vozeler <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/staging/usbip/usbip_common.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -361,10 +361,11 @@ void usbip_dump_header(struct usbip_head
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
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
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(st
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);
}
}
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Olaf Hering <[email protected]>
commit 22356585712d1ff08fbfed152edd8b386873b238 upstream.
Locking is required when tweaking bits located in a shared page, use the
sync_ version of bitops. Without this change vmbus_on_event() will miss
events and as a result, vmbus_isr() will not schedule the receive tasklet.
[Backported to 2.6.32 stable kernel by Haiyang Zhang <[email protected]>]
Signed-off-by: Olaf Hering <[email protected]>
Acked-by: Haiyang Zhang <[email protected]>
Acked-by: Hank Janssen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/staging/hv/Channel.c | 8 ++++----
drivers/staging/hv/Connection.c | 6 ++++--
drivers/staging/hv/Vmbus.c | 2 +-
drivers/staging/hv/VmbusPrivate.h | 1 +
4 files changed, 10 insertions(+), 7 deletions(-)
--- a/drivers/staging/hv/Channel.c
+++ b/drivers/staging/hv/Channel.c
@@ -75,14 +75,14 @@ static void VmbusChannelSetEvent(struct
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(struc
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(struc
(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);
}
--- 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));
--- a/drivers/staging/hv/Vmbus.c
+++ b/drivers/staging/hv/Vmbus.c
@@ -254,7 +254,7 @@ static int VmbusOnISR(struct hv_driver *
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;
}
--- 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>
/*
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Haiyang Zhang <[email protected]>
commit c996edcf1c451b81740abbcca5257ed7e353fcc6 upstream.
After Quick Migration, the network is not immediately operational in the
current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, I added
another netif_notify_peers() into a scheduled work, otherwise GARP packet will
not be sent after quick migration, and cause network disconnection.
Thanks to Mike Surcouf <[email protected]> for reporting the bug and
testing the patch.
Reported-by: Mike Surcouf <[email protected]>
Tested-by: Mike Surcouf <[email protected]>
Signed-off-by: Haiyang Zhang <[email protected]>
Signed-off-by: Hank Janssen <[email protected]>
Signed-off-by: Abhishek Kane <[email protected]>
Signed-off-by: K. Y. Srinivasan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/staging/hv/netvsc_drv.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
--- 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(s
{
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(s
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 devic
.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 *d
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Arjan Mels <[email protected]>
commit d2dd0b07c3e725d386d20294ec906f7ddef207fa upstream.
When doing a usb port reset do a queued reset instead to prevent a
deadlock: the reset will cause the driver to unbind, causing the
usb_driver_lock_for_reset to stall.
Signed-off-by: Arjan Mels <[email protected]>
Cc: Takahiro Hirofuchi <[email protected]>
Cc: Max Vozeler <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/staging/usbip/stub_rx.c | 40 +++++++++++++++-------------------------
1 file changed, 15 insertions(+), 25 deletions(-)
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -168,33 +168,23 @@ static int tweak_set_configuration_cmd(s
static int tweak_reset_device_cmd(struct urb *urb)
{
- struct usb_ctrlrequest *req;
- __u16 value;
- __u16 index;
- int ret;
+ struct stub_priv *priv = (struct stub_priv *) urb->context;
+ struct stub_device *sdev = priv->sdev;
- req = (struct usb_ctrlrequest *) urb->setup_packet;
- value = le16_to_cpu(req->wValue);
- index = le16_to_cpu(req->wIndex);
+ usbip_uinfo("reset_device %s\n", dev_name(&urb->dev->dev));
- usbip_uinfo("reset_device (port %d) to %s\n", index,
- dev_name(&urb->dev->dev));
-
- /* 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");
-
- 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;
}
/*
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Arjan Mels <[email protected]>
commit 28276a28d8b3cd19f4449991faad4945fe557656 upstream.
For isochronous packets the actual_length is the sum of the actual
length of each of the packets, however between the packets might be
padding, so it is not sufficient to just send the first actual_length
bytes of the buffer. To fix this and simultanesouly optimize the
bandwidth the content of the isochronous packets are send without the
padding, the padding is restored on the receiving end.
Signed-off-by: Arjan Mels <[email protected]>
Cc: Takahiro Hirofuchi <[email protected]>
Cc: Max Vozeler <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/staging/usbip/stub_tx.c | 74 ++++++++++++++++++++++++++++-------
drivers/staging/usbip/usbip_common.c | 57 ++++++++++++++++++++++++++
drivers/staging/usbip/usbip_common.h | 2
drivers/staging/usbip/vhci_rx.c | 3 +
4 files changed, 122 insertions(+), 14 deletions(-)
--- 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 s
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 s
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 s
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) {
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -896,6 +896,7 @@ int usbip_recv_iso(struct usbip_device *
int size = np * sizeof(*iso);
int i;
int ret;
+ int total_length = 0;
if (!usb_pipeisoc(urb->pipe))
return 0;
@@ -925,19 +926,75 @@ int usbip_recv_iso(struct usbip_device *
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)
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -393,6 +393,8 @@ void usbip_header_correct_endian(struct
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);
--- 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
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Krishnasamy, Somasundaram <[email protected]>
commit d1e12de804f9d8ad114786ca7c2ce593cba79891 upstream.
During device discovery, scsi mid layer sends INQUIRY command to LUN
0. If the LUN 0 is not mapped to host, it creates a temporary
scsi_device with LUN id 0 and sends REPORT_LUNS command to it. After
the REPORT_LUNS succeeds, it walks through the LUN table and adds each
LUN found to sysfs. At the end of REPORT_LUNS lun table scan, it will
delete the temporary scsi_device of LUN 0.
When scsi devices are added to sysfs, it calls add_dev function of all
the registered class interfaces. If ses driver has been registered,
ses_intf_add() of ses module will be called. This function calls
scsi_device_enclosure() to check the inquiry data for EncServ
bit. Since inquiry was not allocated for temporary LUN 0 scsi_device,
it will cause NULL pointer exception.
To fix the problem, sdev->inquiry is checked for NULL before reading it.
Signed-off-by: Somasundaram Krishnasamy <[email protected]>
Signed-off-by: Babu Moger <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/scsi/scsi_device.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -446,7 +446,7 @@ static inline int scsi_device_qas(struct
}
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)
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: John Hughes <[email protected]>
commit 877a55979c189c590e819a61cbbe2b7947875f17 upstream.
enclosure page 7 gives us the "pretty" names of the enclosure slots.
Without a page 7, we can still use the enclosure code as long as we
make up numeric names for the slots. Unfortunately, the current code
fails to add any devices because the check for page 10 is in the wrong
place if we have no page 7. Fix it so that devices show up even if
the enclosure has no page 7.
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/ses.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -389,9 +389,9 @@ static void ses_enclosure_data_process(s
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) {
On Wed, Apr 13, 2011 at 06:03:39PM +0200, Patrick McHardy wrote:
> Am 13.04.2011 17:51, schrieb Greg KH:
> > 2.6.32-longterm review patch. If anyone has any objections, please let us know.
> >
> > ------------------
> >
> > From: David Sterba <[email protected]>
> >
> > commit b4232a22776aa5d063f890d21ca69870dbbe431b upstream.
> >
> > Static analyzer of clang found a dead store which appears to be a bug in
> > reading count of items in SEQOF field, only the lower byte of word is
> > stored. This may lead to corrupted read and communication shutdown.
> >
> > The bug has been in the module since it's first inclusion into linux
> > kernel.
> >
> > [Patrick: the bug is real, but without practical consequence since the
> > largest amount of sequence-of members we parse is 30.]
>
> As mentioned in the changelog, I don't think this patch is of any
> relevance for -stable since its a purely theoretical problem.
Ok, thanks, now removed from the queue.
greg k-h
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 4d00135a680727f6c3be78f8befaac009030e4df upstream.
User-controllable indexes for voice and channel values may cause reading
and writing beyond the bounds of their respective arrays, leading to
potentially exploitable memory corruption. Validate these indexes.
Signed-off-by: Dan Rosenberg <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/oss/opl3.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -848,6 +848,10 @@ static int opl3_load_patch(int dev, int
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 +1069,15 @@ static int opl3_alloc_voice(int dev, int
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit cda6587c21a887254c8ed4b58da8fcc4040ab557 upstream.
Rmmod myri10ge crash at free_netdev() -> netif_napi_del(), because napi
structures are already deallocated. To fix call netif_napi_del() before
kfree() at myri10ge_free_slices().
Signed-off-by: Stanislaw Gruszka <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/myri10ge/myri10ge.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -3640,6 +3640,7 @@ static void myri10ge_free_slices(struct
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);
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Takashi Iwai <[email protected]>
commit 20b67dddcc5f29d3d0c900225d85e0ac655bc69d upstream.
The commit 5a8cfb4e8ae317d283f84122ed20faa069c5e0c4
ALSA: hda - Use ALC_INIT_DEFAULT for really default initialization
changed to use the default initialization method for ALC889, but
this caused a regression on SPDIF output on some machines.
This seems due to the COEF setup included in the default init procedure.
For making SPDIF working again, the COEF-setup has to be avoided for
the id 0889.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=24342
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/hda/patch_realtek.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- 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
case 0x10ec0883:
case 0x10ec0885:
case 0x10ec0887:
- case 0x10ec0889:
+ /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
alc889_coef_init(codec);
break;
case 0x10ec0888:
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Frederic Weisbecker <[email protected]>
commit 880f57318450dbead6a03f9e31a1468924d6dd88 upstream.
The maximum kilobytes of locked memory that an unprivileged user
can reserve is of 512 kB = 128 pages by default, scaled to the
number of onlined CPUs, which fits well with the tools that use
128 data pages by default.
However tools actually use 129 pages, because they need one more
for the user control page. Thus the default mlock threshold is
not sufficient for the default tools needs and we always end up
to evaluate the constant mlock rlimit policy, which doesn't have
this scaling with the number of online CPUs.
Hence, on systems that have more than 16 CPUs, we overlap the
rlimit threshold and fail to mmap:
$ perf record ls
Error: failed to mmap with 1 (Operation not permitted)
Just increase the max unprivileged mlock threshold by one page
so that it supports well perf tools even after 16 CPUs.
Reported-by: Han Pingtian <[email protected]>
Reported-by: Peter Zijlstra <[email protected]>
Reported-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Frederic Weisbecker <[email protected]>
Acked-by: Arnaldo Carvalho de Melo <[email protected]>
Cc: Stephane Eranian <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/perf_event.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -69,7 +69,8 @@ static inline bool perf_paranoid_kernel(
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
On Wed, 2011-04-13 at 08:50 -0700, Greg KH wrote:
> 2.6.32-longterm review patch. If anyone has any objections, please let us know.
>
> ------------------
>
> From: Dan Rosenberg <[email protected]>
>
> commit c4d0c3b097f7584772316ee4d64a09fe0e4ddfca upstream.
>
> The FSGEOMETRY_V1 ioctl (and its compat equivalent) calls out to
> xfs_fs_geometry() with a version number of 3. This code path does not
> fill in the logsunit member of the passed xfs_fsop_geom_t, leading to
> the leaking of four bytes of uninitialized stack data to potentially
> unprivileged callers.
[...]
This caused a serious regression and requires a second fix:
commit af24ee9ea8d532e16883251a6684dfa1be8eec29
Author: Alex Elder <[email protected]>
Date: Tue Mar 1 17:50:00 2011 +0000
xfs: zero proper structure size for geometry calls
Ben.
--
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
On Wed, 2011-04-13 at 08:50 -0700, Greg KH wrote:
> 2.6.32-longterm review patch. If anyone has any objections, please let us know.
>
> ------------------
>
> From: Jan Kara <[email protected]>
>
> commit b03f24567ce7caf2420b8be4c6eb74c191d59a91 upstream.
>
> There's no reason to write quota info in dquot_commit(). The writing is a
> relict from the old days when we didn't have dquot_acquire() and
> dquot_release() and thus dquot_commit() could have created / removed quota
> structures from the file. These days dquot_commit() only updates usage counters
> / limits in quota structure and thus there's no need to write quota info.
>
> This also fixes an issue with journaling filesystem which didn't reserve
> enough space in the transaction for write of quota info (it could have been
> dirty at the time of dquot_commit() because of a race with other operation
> changing it).
[...]
> @@ -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;
[...]
Why is the return value for the flag-not-set case changed from 0 to
-EIO? Is this really part of the same bug fix?
Ben.
--
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
On Wed, 2011-04-13 at 08:51 -0700, Greg KH wrote:
> 2.6.32-longterm review patch. If anyone has any objections, please let us know.
>
> ------------------
>
>
> From: Borislav Petkov <[email protected]>
>
> Upstream commit: 44d60c0f5c58c2168f31df9a481761451840eb54
>
> The different families have a different max size for the ucode patch,
> adjust size checking to the family we're running on. Also, do not
> vzalloc the max size of the ucode but only the actual size that is
> passed on from the firmware loader.
[...]
> @@ -125,6 +124,37 @@ static int get_matching_microcode(int cp
> 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) {
Surely:
if (actual_size + UCODE_CONTAINER_SECTION_HDR > size || ...
> + pr_err("section size mismatch\n");
> + return 0;
> + }
> +
> + return actual_size;
> +}
> +
> static int apply_microcode_amd(int cpu)
> {
> u32 rev, dummy;
> @@ -164,11 +194,11 @@ static int get_ucode_data(void *to, cons
> }
>
> 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;
Dummy initialisations mean the compiler won't warn if you fail to
properly initialise them later.
> if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR))
> return NULL;
> @@ -179,23 +209,18 @@ get_next_ucode(const u8 *buf, unsigned i
> return NULL;
> }
>
> - total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
> + 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);
[...]
So I wondered why the result of get_ucode_data() is no longer being
checked. And the answer is: because it's a trivial wrapper for
memcpy(), but with a 'return 0'. So the memset() is redundant.
Good thing nothing important depends on this validation, oh wait...
Ben.
--
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
Hi Ben,
I appreciate the review, thanks.
On Wed, Apr 13, 2011 at 11:37:03PM -0400, Ben Hutchings wrote:
> On Wed, 2011-04-13 at 08:51 -0700, Greg KH wrote:
> > 2.6.32-longterm review patch. If anyone has any objections, please let us know.
> >
> > ------------------
> >
> >
> > From: Borislav Petkov <[email protected]>
> >
> > Upstream commit: 44d60c0f5c58c2168f31df9a481761451840eb54
> >
> > The different families have a different max size for the ucode patch,
> > adjust size checking to the family we're running on. Also, do not
> > vzalloc the max size of the ucode but only the actual size that is
> > passed on from the firmware loader.
> [...]
> > @@ -125,6 +124,37 @@ static int get_matching_microcode(int cp
> > 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) {
>
> Surely:
>
> if (actual_size + UCODE_CONTAINER_SECTION_HDR > size || ...
Well, not really because the UCODE_CONTAINER_SECTION_HDR is just 8 bytes
of patch header before each ucode patch and we don't copy it. So the
first part of the check is to see whether the ucode patch we're looking
at is incomplete and the ucode file is truncated.
That's why we skip the 8 bytes when we do get_ucode_data() later.
> > + pr_err("section size mismatch\n");
> > + return 0;
> > + }
> > +
> > + return actual_size;
> > +}
> > +
> > static int apply_microcode_amd(int cpu)
> > {
> > u32 rev, dummy;
> > @@ -164,11 +194,11 @@ static int get_ucode_data(void *to, cons
> > }
> >
> > 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;
>
> Dummy initialisations mean the compiler won't warn if you fail to
> properly initialise them later.
I don't see why that matters here since we write into it the vmalloc()
allocation result and check its validity after the vmalloc too.
>
> > if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR))
> > return NULL;
> > @@ -179,23 +209,18 @@ get_next_ucode(const u8 *buf, unsigned i
> > return NULL;
> > }
> >
> > - total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
> > + 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);
> [...]
>
> So I wondered why the result of get_ucode_data() is no longer being
> checked. And the answer is: because it's a trivial wrapper for
> memcpy(), but with a 'return 0'. So the memset() is redundant.
Fair enough. Upstream was converted to vzalloc some time ago so it
should be converted back to vmalloc since we overwrite the buffer right
afterwards and we could save us the __GFP_ZERO memset :)
> Good thing nothing important depends on this validation, oh wait...
Oh wait, please don't tell me that you really think that the CPU relies
completely on software to do its ucode validation and accepts the "good"
ucode binary patch blindly...
Thanks.
--
Regards/Gruss,
Boris.
Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
On Thu, Apr 14, 2011 at 03:41:25AM -0400, Borislav Petkov wrote:
[..]
> > > +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) {
> >
> > Surely:
> >
> > if (actual_size + UCODE_CONTAINER_SECTION_HDR > size || ...
>
> Well, not really because the UCODE_CONTAINER_SECTION_HDR is just 8 bytes
> of patch header before each ucode patch and we don't copy it. So the
> first part of the check is to see whether the ucode patch we're looking
> at is incomplete and the ucode file is truncated.
>
> That's why we skip the 8 bytes when we do get_ucode_data() later.
Actually, scratch that. I think you're right - this is a bug in the
original code since the check there ignored those 8 bytes too:
total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
printk(KERN_DEBUG "microcode: size %u, total_size %u\n",
size, total_size);
if (total_size > size || total_size > UCODE_MAX_SIZE) {
printk(KERN_ERR "microcode: error: size mismatch\n");
return NULL;
}
Btw, while staring at it, I've found another discrepancy that needs to
be fixed, I'll whip up a patch soon.
Thanks.
--
Regards/Gruss,
Boris.
Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
On Thu 14-04-11 04:09:45, Ben Hutchings wrote:
> On Wed, 2011-04-13 at 08:50 -0700, Greg KH wrote:
> > 2.6.32-longterm review patch. If anyone has any objections, please let us know.
> >
> > ------------------
> >
> > From: Jan Kara <[email protected]>
> >
> > commit b03f24567ce7caf2420b8be4c6eb74c191d59a91 upstream.
> >
> > There's no reason to write quota info in dquot_commit(). The writing is a
> > relict from the old days when we didn't have dquot_acquire() and
> > dquot_release() and thus dquot_commit() could have created / removed quota
> > structures from the file. These days dquot_commit() only updates usage counters
> > / limits in quota structure and thus there's no need to write quota info.
> >
> > This also fixes an issue with journaling filesystem which didn't reserve
> > enough space in the transaction for write of quota info (it could have been
> > dirty at the time of dquot_commit() because of a race with other operation
> > changing it).
> [...]
> > @@ -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;
> [...]
>
> Why is the return value for the flag-not-set case changed from 0 to
> -EIO? Is this really part of the same bug fix?
Yes, it is part of my original patch. It's a small unrelated cleanup I
did when already changing that code. Frankly, the effect won't be big
because
a) DQ_ACTIVE_B is not set only when we for some reason failed to read the
structure from disk.
b) Only dqput() currently checks the return value of this callback and it
calls it only when DQ_ACTIVE_B is set.
So I'm pretty sure it does not change anything.
Honza
--
Jan Kara <[email protected]>
SUSE Labs, CR
On Thu, Apr 14, 2011 at 03:54:45AM +0100, Ben Hutchings wrote:
> On Wed, 2011-04-13 at 08:50 -0700, Greg KH wrote:
> > 2.6.32-longterm review patch. If anyone has any objections, please let us know.
> >
> > ------------------
> >
> > From: Dan Rosenberg <[email protected]>
> >
> > commit c4d0c3b097f7584772316ee4d64a09fe0e4ddfca upstream.
> >
> > The FSGEOMETRY_V1 ioctl (and its compat equivalent) calls out to
> > xfs_fs_geometry() with a version number of 3. This code path does not
> > fill in the logsunit member of the passed xfs_fsop_geom_t, leading to
> > the leaking of four bytes of uninitialized stack data to potentially
> > unprivileged callers.
> [...]
>
> This caused a serious regression and requires a second fix:
>
> commit af24ee9ea8d532e16883251a6684dfa1be8eec29
> Author: Alex Elder <[email protected]>
> Date: Tue Mar 1 17:50:00 2011 +0000
>
> xfs: zero proper structure size for geometry calls
Thanks for letting me know, I've queued up this patch as well.
greg k-h
On 11-04-13 11:51 AM, Greg KH wrote:
> 2.6.32-longterm review patch. If anyone has any objections, please let us know.
>
> ------------------
>
> From: Linus Torvalds <[email protected]>
>
> commit 1b1f693d7ad6d193862dcb1118540a030c5e761f upstream.
>
> As reported by Thomas Pollet, the rdma page counting can overflow. We
> get the rdma sizes in 64-bit unsigned entities, but then limit it to
> UINT_MAX bytes and shift them down to pages (so with a possible "+1" for
> an unaligned address).
>
> So each individual page count fits comfortably in an 'unsigned int' (not
> even close to overflowing into signed), but as they are added up, they
> might end up resulting in a signed return value. Which would be wrong.
>
> Catch the case of tot_pages turning negative, and return the appropriate
> error code.
>
> Reported-by: Thomas Pollet <[email protected]>
> Signed-off-by: Linus Torvalds <[email protected]>
> Signed-off-by: Andy Grover <[email protected]>
> Signed-off-by: David S. Miller <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> ---
> net/rds/rdma.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> --- a/net/rds/rdma.c
> +++ b/net/rds/rdma.c
> @@ -473,6 +473,14 @@ static struct rds_rdma_op *rds_rdma_prep
>
> 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)
Sorry if this doesn't make the review cutoff; just noticed it now.
A cosmetic note -- I think the comment no longer matches the code for
the backport, in that it is now misleading, and should instead be:
* nr for one entry is limited to (UINT_MAX>>PAGE_SHIFT)+1,
* so nr_pages cannot overflow without first going negative.
For context, the original upstream was:
tot_pages += nr_pages;
+
+ /*
+ * nr_pages for one entry is limited to (UINT_MAX>>PAGE_SHIFT)+1,
+ * so tot_pages cannot overflow without first going negative.
+ */
+ if ((int)tot_pages < 0)
+ return -EINVAL;
Paul.
On Wed, Apr 13, 2011 at 8:51 AM, Greg KH <[email protected]> wrote:
> +
> + ? ? ? ? ? ? ? /*
> + ? ? ? ? ? ? ? ?* 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;
> ? ? ? ?}
Yeah, what the heck happened there. That won't work.
As Paul says, the original was just a "return -EINVAL", and when the
backport changed it into a "ret = " + "goto out", it really needs a
couple of braces.
As it is, the patch is just broken. Think about it.
Linus
On Fri, Apr 15, 2011 at 10:10:13AM -0700, Linus Torvalds wrote:
> On Wed, Apr 13, 2011 at 8:51 AM, Greg KH <[email protected]> wrote:
> > +
> > + ? ? ? ? ? ? ? /*
> > + ? ? ? ? ? ? ? ?* 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;
> > ? ? ? ?}
>
> Yeah, what the heck happened there. That won't work.
>
> As Paul says, the original was just a "return -EINVAL", and when the
> backport changed it into a "ret = " + "goto out", it really needs a
> couple of braces.
>
> As it is, the patch is just broken. Think about it.
Ah crap, that's my fault, I did the backport totally wrong here.
I'll fix this up and push an updated version out in a few hours when I
get back from my daughter's earth-day field trip...
thanks,
greg k-h
On Thu, 14 Apr 2011, Borislav Petkov wrote:
> > Good thing nothing important depends on this validation, oh wait...
>
> Oh wait, please don't tell me that you really think that the CPU relies
> completely on software to do its ucode validation and accepts the "good"
> ucode binary patch blindly...
http://www.securiteam.com/securityreviews/5FP0M1PDFO.html
If it is not a hoax, circa 2004 K8s would accept any crap that passed a
simple checksum test.
I don't trust the claims of strong crypto usage by Intel either,
especially since AFAIK Intel itself never claimed to use anything strong,
just that its microcode was "encrypted".
I sure hope real crypto is used on the more recent cores from both
vendors, though. Too bad we cannot lock down further microcode updates
until the next hard reset...
--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh
On Wednesday 13 April 2011, Greg KH wrote:
> From: Arjan Mels <[email protected]>
>
> commit d2dd0b07c3e725d386d20294ec906f7ddef207fa upstream.
>
> When doing a usb port reset do a queued reset instead to prevent a
> deadlock: the reset will cause the driver to unbind, causing the
> usb_driver_lock_for_reset to stall.
>
> Signed-off-by: Arjan Mels <[email protected]>
> Cc: Takahiro Hirofuchi <[email protected]>
> Cc: Max Vozeler <[email protected]>
> Cc: Arnd Bergmann <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
I think either the subject line is misleading or the patch is not
needed in -stable. The kthread conversion was done in 2.6.38, so
any bug introduced by it would not need to be fixed in an earlier
version, afaict.
Arnd
On Sun, Apr 17, 2011 at 10:15:01PM +0200, Arnd Bergmann wrote:
> On Wednesday 13 April 2011, Greg KH wrote:
> > From: Arjan Mels <[email protected]>
> >
> > commit d2dd0b07c3e725d386d20294ec906f7ddef207fa upstream.
> >
> > When doing a usb port reset do a queued reset instead to prevent a
> > deadlock: the reset will cause the driver to unbind, causing the
> > usb_driver_lock_for_reset to stall.
> >
> > Signed-off-by: Arjan Mels <[email protected]>
> > Cc: Takahiro Hirofuchi <[email protected]>
> > Cc: Max Vozeler <[email protected]>
> > Cc: Arnd Bergmann <[email protected]>
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> >
>
> I think either the subject line is misleading or the patch is not
> needed in -stable. The kthread conversion was done in 2.6.38, so
> any bug introduced by it would not need to be fixed in an earlier
> version, afaict.
Yes, the Subject: was incorrect, and I only realized it after it was
committed to the tree, sorry.
The bug fixes were still real.
thanks,
greg k-h
I agree that the bugfix will do no harm on older versions. I have however not seen this particular deadlock occurring on versions before the kthread conversion: the thread termination works differently here (not by polling), so the fix is probably not necessary on older versions.
Apologies for not responding to this before: these were my first patches and I had not realized bugfixes would also be backported to older versions.
Best Regards,
Arjan Mels
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Arjan Mels
Principal Engineer
Device Physics / Wafer Technology and Foundry Organization (WT&FO) / Operations
NXP Semiconductors
FB 3.057, Gerstweg 2, 6534AE Nijmegen, The Netherlands
Phone : + 31 24 353 5330
E-mail : [email protected]
XFB : nlv07682@seri02
-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: Monday, April 18, 2011 08:03
To: Arnd Bergmann
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Arjan Mels; Takahiro Hirofuchi; Max Vozeler
Subject: Re: [12/74] staging: usbip: bugfixes related to kthread conversion
On Sun, Apr 17, 2011 at 10:15:01PM +0200, Arnd Bergmann wrote:
> On Wednesday 13 April 2011, Greg KH wrote:
> > From: Arjan Mels <[email protected]>
> >
> > commit d2dd0b07c3e725d386d20294ec906f7ddef207fa upstream.
> >
> > When doing a usb port reset do a queued reset instead to prevent a
> > deadlock: the reset will cause the driver to unbind, causing the
> > usb_driver_lock_for_reset to stall.
> >
> > Signed-off-by: Arjan Mels <[email protected]>
> > Cc: Takahiro Hirofuchi <[email protected]>
> > Cc: Max Vozeler <[email protected]>
> > Cc: Arnd Bergmann <[email protected]>
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> >
>
> I think either the subject line is misleading or the patch is not
> needed in -stable. The kthread conversion was done in 2.6.38, so
> any bug introduced by it would not need to be fixed in an earlier
> version, afaict.
Yes, the Subject: was incorrect, and I only realized it after it was
committed to the tree, sorry.
The bug fixes were still real.
thanks,
greg k-h
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
Commit-ID: 40b7f3dfcc5ab211a0b8d916751bb22ac2290806
Gitweb: http://git.kernel.org/tip/40b7f3dfcc5ab211a0b8d916751bb22ac2290806
Author: Borislav Petkov <[email protected]>
AuthorDate: Wed, 15 Jun 2011 15:34:57 +0200
Committer: Borislav Petkov <[email protected]>
CommitDate: Thu, 16 Jun 2011 17:23:54 +0200
x86, microcode, AMD: Fix section header size check
The ucode size check has to take the section header size into account
too when sanity checking the section length. Shorten and clarify define
names, while at it.
Caught-by: Ben Hutchings <[email protected]>
Link: http://lkml.kernel.org/r/1302752223.5282.674.camel@localhost
Signed-off-by: Borislav Petkov <[email protected]>
---
arch/x86/kernel/microcode_amd.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index d30d67c..591be0e 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -66,8 +66,8 @@ struct microcode_amd {
unsigned int mpb[0];
};
-#define UCODE_CONTAINER_SECTION_HDR 8
-#define UCODE_CONTAINER_HEADER_SIZE 12
+#define SECTION_HDR_SIZE 8
+#define CONTAINER_HDR_SZ 12
static struct equiv_cpu_entry *equiv_cpu_table;
@@ -177,7 +177,7 @@ static unsigned int verify_ucode_size(int cpu, const u8 *buf, unsigned int size)
actual_size = *(u32 *)(buf + 4);
- if (actual_size > size || actual_size > max_size) {
+ if (actual_size + SECTION_HDR_SIZE > size || actual_size > max_size) {
pr_err("section size mismatch\n");
return 0;
}
@@ -204,8 +204,8 @@ get_next_ucode(int cpu, const u8 *buf, unsigned int size, unsigned int *mc_size)
if (!mc)
goto out;
- get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, actual_size);
- *mc_size = actual_size + UCODE_CONTAINER_SECTION_HDR;
+ get_ucode_data(mc, buf + SECTION_HDR_SIZE, actual_size);
+ *mc_size = actual_size + SECTION_HDR_SIZE;
out:
return mc;
@@ -229,9 +229,10 @@ static int install_equiv_cpu_table(const u8 *buf)
return -ENOMEM;
}
- get_ucode_data(equiv_cpu_table, buf + UCODE_CONTAINER_HEADER_SIZE, size);
+ get_ucode_data(equiv_cpu_table, buf + CONTAINER_HDR_SZ, size);
- return size + UCODE_CONTAINER_HEADER_SIZE; /* add header length */
+ /* add header length */
+ return size + CONTAINER_HDR_SZ;
}
static void free_equiv_cpu_table(void)
On 11-04-13 11:51 AM, Greg KH wrote:
> 2.6.32-longterm review patch. If anyone has any objections, please let us know.
This introduces new compile warnings, albeit reasonably harmless ones:
net/ipv4/inet_diag.c: In function ?inet_csk_diag_dump?:
net/ipv4/inet_diag.c:496:10: warning: passing argument 1 of ?nlmsg_find_attr? discards qualifiers from pointer target type
include/net/netlink.h:387:30: note: expected ?struct nlmsghdr *? but argument is of type ?const struct nlmsghdr *?
and more instances of the same. Grabbing the following commit in
conjunction with this existing one fixes it to be quiet again.
commit 6b8c92ba07287578718335ce409de8e8d7217e40
Author: Nelson Elhage <[email protected]>
Date: Wed Nov 3 16:35:40 2010 +0000
netlink: Make nlmsg_find_attr take a const nlmsghdr*.
This will let us use it on a nlmsghdr stored inside a netlink_callback.
Signed-off-by: Nelson Elhage <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Thanks,
Paul.
>
> ------------------
>
> From: Nelson Elhage <[email protected]>
>
> commit 22e76c849d505d87c5ecf3d3e6742a65f0ff4860 upstream.
>
> We were using nlmsg_find_attr() to look up the bytecode by attribute when
> auditing, but then just using the first attribute when actually running
> bytecode. So, if we received a message with two attribute elements, where only
> the second had type INET_DIAG_REQ_BYTECODE, we would validate and run different
> bytecode strings.
>
> Fix this by consistently using nlmsg_find_attr everywhere.
>
> Signed-off-by: Nelson Elhage <[email protected]>
> Signed-off-by: Thomas Graf <[email protected]>
> Signed-off-by: David S. Miller <[email protected]>
> [jmm: Slightly adapted to apply against 2.6.32]
> Cc: Moritz Muehlenhoff <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
>
> ---
> net/ipv4/inet_diag.c | 27 ++++++++++++++++-----------
> 1 file changed, 16 insertions(+), 11 deletions(-)
>
> --- a/net/ipv4/inet_diag.c
> +++ b/net/ipv4/inet_diag.c
> @@ -489,9 +489,11 @@ static int inet_csk_diag_dump(struct soc
> {
> 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 soc
> 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 in
> {
> 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 in
> 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
> 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
> 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
> &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;
> }
>
>
>
> _______________________________________________
> stable mailing list
> [email protected]
> http://linux.kernel.org/mailman/listinfo/stable
>