Merge changes from sid up to 3.2.29-1

Most of the patches added to sid are already in 3.5 and could be dropped.
Some others needed to be re-generated without the backporting changes.

Ignore the rt changes as there is no rt featureset for 3.5.

svn path=/dists/trunk/linux/; revision=19387
This commit is contained in:
Ben Hutchings 2012-09-17 02:19:21 +00:00
commit af9147122a
81 changed files with 2915 additions and 1115 deletions

View File

@ -274,7 +274,7 @@ class Gencontrol(Base):
p = self.process_packages(self.templates['control.xen-linux-system'], vars)
l = PackageRelationGroup()
for xen_flavour in config_entry_xen['flavours']:
l.append("xen-hypervisor-%s" % xen_flavour)
l.append("xen-system-%s" % xen_flavour)
p[0]['Depends'].append(l)
packages_dummy.extend(p)

157
debian/changelog vendored
View File

@ -159,6 +159,163 @@ linux-2.6 (3.3~rc6-1~experimental.1) experimental; urgency=low
-- Ben Hutchings <ben@decadent.org.uk> Sun, 04 Mar 2012 20:27:42 +0000
linux (3.2.29-1) unstable; urgency=low
* New upstream stable update:
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.24
- sched/nohz: Rewrite and fix load-avg computation -- again
(Closes: #674153)
- libsas: fix taskfile corruption in sas_ata_qc_fill_rtf
- md/raid1: fix use-after-free bug in RAID1 data-check code.
- PCI: EHCI: fix crash during suspend on ASUS computers
- cpufreq / ACPI: Fix not loading acpi-cpufreq driver (regression in 3.2.2)
- block: fix infinite loop in __getblk_slow (regression in 3.2.19)
(Closes: #684293)
- PM / Hibernate: Hibernate/thaw fixes/improvements
- tcm_fc: Fix crash seen with aborts and large reads
- fifo: Do not restart open() if it already found a partner
- cifs: on CONFIG_HIGHMEM machines, limit the rsize/wsize to the kmap space
- UBIFS: fix a bug in empty space fix-up
- ore: Fix NFS crash by supporting any unaligned RAID IO
- ore: Remove support of partial IO request (NFS crash)
- pnfs-obj: don't leak objio_state if ore_write/read fails
- pnfs-obj: Fix __r4w_get_page when offset is beyond i_size
- dm raid1: fix crash with mirror recovery and discard
- dm raid1: set discard_zeroes_data_unsupported
- time: Fix bugs in leap-second handling (Closes: #679882)
+ ntp: Fix leap-second hrtimer livelock
+ timekeeping: Fix leapsecond triggered load spike issue
- bnx2x: fix checksum validation
- bnx2x: fix panic when TX ring is full
- eCryptfs: Gracefully refuse miscdev file ops on inherited/passed files
- ACPI / PM: Make acpi_pm_device_sleep_state() follow the specification
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.25
- mm: Fix various performance problems, particularly affecting use of
transparent hugepages (Closes: #675493)
- target: Add range checking to UNMAP emulation
- target: Fix reading of data length fields for UNMAP commands
- target: Fix possible integer underflow in UNMAP emulation
- target: Check number of unmap descriptors against our limit
- ext4: don't let i_reserved_meta_blocks go negative
- ext4: undo ext4_calc_metadata_amount if we fail to claim space
- locks: fix checking of fcntl_setlease argument
- Btrfs: call the ordered free operation without any locks held
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.26
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.27
- lirc_sir: make device registration work (Closes: #680762)
- random: Improve random number generation on non-interactive systems
+ random: Use arch_get_random_int instead of cycle counter if avail
+ random: Use arch-specific RNG to initialize the entropy store
+ random: make 'add_interrupt_randomness()' do something sane
+ usb: feed USB device information to the /dev/random driver
+ net: feed /dev/random with the MAC address when registering a device
+ rtc: wm831x: Feed the write counter into device_add_randomness()
+ mfd: wm831x: Feed the device UUID into device_add_randomness()
- futex: Test for pi_mutex on fault in futex_wait_requeue_pi()
- futex: Forbid uaddr == uaddr2 in futex_wait_requeue_pi()
- s390/mm: downgrade page table after fork of a 31 bit process
- asus-wmi: use ASUS_WMI_METHODID_DSTS2 as default DSTS ID.
(Closes: #679158)
- md/raid1: don't abort a resync on the first badblock.
- [arm] 7467/1: mutex: use generic xchg-based implementation for ARMv6+
- [arm] 7476/1: vfp: only clear vfp state for current cpu in vfp_pm_suspend
- [arm] 7477/1: vfp: Always save VFP state in vfp_pm_suspend on UP
- [arm] 7478/1: errata: extend workaround for erratum #720789
- [arm] Fix undefined instruction exception handling
- mm: mmu_notifier: fix freed page still mapped in secondary MMU
- mm: hugetlbfs: close race during teardown of hugetlbfs shared page tables
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.28
- bnx2: Fix bug in bnx2_free_tx_skbs().
- sch_sfb: Fix missing NULL check
- sctp: Fix list corruption resulting from freeing an association on a list
- cipso: don't follow a NULL pointer when setsockopt() is called
- caif: fix NULL pointer check
- net/tun: fix ioctl() based info leaks
- rtlwifi: rtl8192cu: Change buffer allocation for synchronous reads
- hfsplus: fix overflow in sector calculations in hfsplus_submit_bio
- drm/i915: fixup seqno allocation logic for lazy_request
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.29
- pnfs: defer release of pages in layoutget
- fuse: verify all ioctl retry iov elements
- usb: serial: mos7840: Fixup mos7840_chars_in_buffer()
- sched: fix divide by zero at {thread_group,task}_times
- vfs: canonicalize create mode in build_open_flags()
- dccp: check ccid before dereferencing
- md: Don't truncate size at 4TB for RAID0 and Linear
- target: fix NULL pointer dereference bug alloc_page() fails to get memory
- USB: CDC ACM: Fix NULL pointer dereference
- alpha: Don't export SOCK_NONBLOCK to user space. (Closes: #658460)
- radeon: Fix various bugs in reading vbios (Closes: #685604)
- vfs: missed source of ->f_pos races
- svcrpc: fix BUG() in svc_tcp_clear_pages
- svcrpc: sends on closed socket should stop immediately
- fbcon: fix race condition between console lock and cursor timer (v1.1)
- mm: hugetlbfs: correctly populate shared pmd
- fs/buffer.c: remove BUG() in possible but rare condition
- block: replace __getblk_slow misfix by grow_dev_page fix
- Staging: speakup: fix an improperly-declared variable. (Closes: #685953)
- NFS: Fix Oopses in nfs_lookup_revalidate and nfs4_lookup_revalidate
[ Ben Hutchings ]
* Bump ABI to 4
* linux-image: Include package version in utsname version string
('uname -v' output) (Closes: #638878)
* linux-source: Drop support for version.$DISTRIBUTION
* [arm,ia64,powerpc,s390,sh,x86] linux-image: Include package version
in stack traces from WARN, BUG, Oops etc.
* udeb: Add snd-hda-codec-ca0132 to sound-modules (Closes: #682368)
* linux-source: Suggest pkg-config, needed to build kconfig GUIs
(Closes: #682726)
* debugfs: Add mode, uid and gid mount options; set default mode to 700
(Closes: #681418)
* net: new counter for tx_timeout errors in sysfs
* net: Add byte queue limits (bql) for reduced buffer-bloat
* bnx2,bnx2x,e1000e,forcedeth,igb,ixgbe,sfc,skge,sky2,tg3:
Add support for bql
* fs: Update link security restrictions to match Linux 3.6:
- Drop kconfig options; restrictions can only be disabled by sysctl
- Change the audit message type from AUDIT_AVC (1400) to
AUDIT_ANON_LINK (1702)
* [rt] Update to 3.2.28-rt42:
- time/rt: Fix up leap-second backport for RT changes
- fix printk flush of messages
* rds: set correct msg_namelen (CVE-2012-3430)
* e1000: add dropped DMA receive enable back in for WoL (Closes: #684618)
* PCI/PM/Runtime: make PCI traces quieter (Closes: #684049)
* rc: ite-cir: Initialise ite_dev::rdev earlier (Closes: #684441)
* input: Enable TOUCHSCREEN_ATMEL_MXT as module (Closes: #685123)
* usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams
(Closes: #668211)
* [alpha] Use gcc-4.6 (Closes: #685894)
- Use large data model to work around link failure
* [i386/486] video: Change FB_GEODE_LX from built-in to module (lxfb)
(Closes: #686528)
* [i386/686-pae] video: Disable Geode framebuffer drivers, not used with
any chips that support PAE
* [x86] drm/i915: Fix i8xx interrupt handling (Closes: #655152)
* [armel/kirkwood] ahci: Add JMicron 362 device IDs (Closes: #634180)
* speakup: lower default software speech rate (Closes: #686742)
* e1000e: Fix potential DoS when TSO enabled
* mm: Remove user-triggerable BUG from mpol_to_str
* sfc: Fix maximum number of TSO segments and minimum TX queue size
(CVE-2012-3412)
- tcp: Apply device TSO segment limit earlier
* net_sched: gact: Fix potential panic in tcf_gact().
* af_packet: remove BUG statement in tpacket_destruct_skb
* net: Fix various information leaks
* af_packet: don't emit packet on orig fanout group
* af_netlink: force credentials passing (CVE-2012-3520)
* netlink: fix possible spoofing from non-root processes
* net: ipv4: ipmr_expire_timer causes crash when removing net namespace
* [i386] i810fb: Enable FB_I810_GTF, FB_I810_I2C (Closes: #687644)
* udeb: Add fuse-modules to support os-prober (see #684265)
[ Bastian Blank ]
* Make xen-linux-system meta-packages depend on xen-system. This allows
automatic updates. (closes: #681637)
-- Ben Hutchings <ben@decadent.org.uk> Sun, 16 Sep 2012 06:16:38 +0100
linux (3.2.23-1) unstable; urgency=low
* New upstream stable update:

View File

@ -1,7 +1,6 @@
[base]
flavours: alpha-generic alpha-smp alpha-legacy
kernel-arch: alpha
compiler: gcc-4.5
[image]
suggests: aboot, fdutils

View File

@ -780,7 +780,7 @@ CONFIG_TOUCHSCREEN_AD7877=m
CONFIG_TOUCHSCREEN_AD7879=m
CONFIG_TOUCHSCREEN_AD7879_I2C=m
# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
# CONFIG_TOUCHSCREEN_BU21013 is not set
# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
CONFIG_TOUCHSCREEN_DYNAPRO=m

View File

@ -131,7 +131,10 @@ CONFIG_MOXA_INTELLIO=m
##
## file: drivers/video/geode/Kconfig
##
CONFIG_FB_GEODE_LX=y
CONFIG_FB_GEODE=y
CONFIG_FB_GEODE_LX=m
CONFIG_FB_GEODE_GX=m
CONFIG_FB_GEODE_GX1=m
##
## file: mm/Kconfig

View File

@ -1505,6 +1505,11 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
##
## file: drivers/video/geode/Kconfig
##
# CONFIG_FB_GEODE is not set
##
## file: drivers/watchdog/Kconfig
##

View File

@ -466,7 +466,8 @@ CONFIG_SERIAL_8250_EXAR_ST16C554=m
## file: drivers/video/Kconfig
##
CONFIG_FB_I810=m
# CONFIG_FB_I810_GTF is not set
CONFIG_FB_I810_GTF=y
CONFIG_FB_I810_I2C=y
CONFIG_FB_MATROX_G=y
CONFIG_FB_MATROX_MAVEN=m
CONFIG_FB_ATY_GENERIC_LCD=y
@ -477,14 +478,6 @@ CONFIG_FB_SAVAGE_I2C=y
##
CONFIG_MDA_CONSOLE=m
##
## file: drivers/video/geode/Kconfig
##
CONFIG_FB_GEODE=y
CONFIG_FB_GEODE_LX=m
CONFIG_FB_GEODE_GX=m
CONFIG_FB_GEODE_GX1=m
##
## file: drivers/watchdog/Kconfig
##

View File

@ -102,11 +102,6 @@ CONFIG_FB_MATROX_MAVEN=m
# CONFIG_FB_ATY_GENERIC_LCD is not set
# CONFIG_FB_SAVAGE_I2C is not set
##
## file: drivers/video/geode/Kconfig
##
# CONFIG_FB_GEODE is not set
##
## file: init/Kconfig
##

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

1
debian/installer/modules/fuse-modules vendored Normal file
View File

@ -0,0 +1 @@
fuse

View File

@ -64,6 +64,7 @@ snd-gusmax ?
snd-harmony ?
snd-hda-codec-analog ?
snd-hda-codec-ca0110 ?
snd-hda-codec-ca0132 ?
snd-hda-codec-cirrus ?
snd-hda-codec-cmedia ?
snd-hda-codec-conexant ?

View File

@ -460,3 +460,9 @@ Depends: kernel-image, crc-modules
Priority: extra
Description: UDF modules
This package contains the UDF filesystem module.
Package: fuse-modules
Depends: kernel-image
Priority: extra
Description: FUSE modules
This package contains the Filesystem in Userspace (FUSE) module.

View File

@ -0,0 +1 @@
#include "../powerpc/fuse-modules"

View File

@ -0,0 +1 @@
#include "../powerpc/fuse-modules"

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1,91 @@
From: Eric Dumazet <edumazet@google.com>
Date: Tue, 21 Aug 2012 06:21:17 +0000
Subject: af_netlink: force credentials passing [CVE-2012-3520]
[ Upstream commit e0e3cea46d31d23dc40df0a49a7a2c04fe8edfea ]
Pablo Neira Ayuso discovered that avahi and
potentially NetworkManager accept spoofed Netlink messages because of a
kernel bug. The kernel passes all-zero SCM_CREDENTIALS ancillary data
to the receiver if the sender did not provide such data, instead of not
including any such data at all or including the correct data from the
peer (as it is the case with AF_UNIX).
This bug was introduced in commit 16e572626961
(af_unix: dont send SCM_CREDENTIALS by default)
This patch forces passing credentials for netlink, as
before the regression.
Another fix would be to not add SCM_CREDENTIALS in
netlink messages if not provided by the sender, but it
might break some programs.
With help from Florian Weimer & Petr Matousek
This issue is designated as CVE-2012-3520
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Petr Matousek <pmatouse@redhat.com>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
include/net/scm.h | 4 +++-
net/netlink/af_netlink.c | 2 +-
net/unix/af_unix.c | 4 ++--
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/include/net/scm.h b/include/net/scm.h
index d456f4c..0c0017c 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -71,9 +71,11 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
}
static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
- struct scm_cookie *scm)
+ struct scm_cookie *scm, bool forcecreds)
{
memset(scm, 0, sizeof(*scm));
+ if (forcecreds)
+ scm_set_cred(scm, task_tgid(current), current_cred());
unix_get_peersec_dgram(sock, scm);
if (msg->msg_controllen <= 0)
return 0;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index a99fb41..1af8542 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1333,7 +1333,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
if (NULL == siocb->scm)
siocb->scm = &scm;
- err = scm_send(sock, msg, siocb->scm);
+ err = scm_send(sock, msg, siocb->scm, true);
if (err < 0)
return err;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d99678a..317bfe3 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1435,7 +1435,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
if (NULL == siocb->scm)
siocb->scm = &tmp_scm;
wait_for_unix_gc();
- err = scm_send(sock, msg, siocb->scm);
+ err = scm_send(sock, msg, siocb->scm, false);
if (err < 0)
return err;
@@ -1596,7 +1596,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
if (NULL == siocb->scm)
siocb->scm = &tmp_scm;
wait_for_unix_gc();
- err = scm_send(sock, msg, siocb->scm);
+ err = scm_send(sock, msg, siocb->scm, false);
if (err < 0)
return err;

View File

@ -0,0 +1,102 @@
From: Eric Leblond <eric@regit.org>
Date: Thu, 16 Aug 2012 22:02:58 +0000
Subject: af_packet: don't emit packet on orig fanout group
[ Upstream commit c0de08d04215031d68fa13af36f347a6cfa252ca ]
If a packet is emitted on one socket in one group of fanout sockets,
it is transmitted again. It is thus read again on one of the sockets
of the fanout group. This result in a loop for software which
generate packets when receiving one.
This retransmission is not the intended behavior: a fanout group
must behave like a single socket. The packet should not be
transmitted on a socket if it originates from a socket belonging
to the same fanout group.
This patch fixes the issue by changing the transmission check to
take fanout group info account.
Reported-by: Aleksandr Kotov <a1k@mail.ru>
Signed-off-by: Eric Leblond <eric@regit.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
include/linux/netdevice.h | 2 ++
net/core/dev.c | 16 ++++++++++++++--
net/packet/af_packet.c | 9 +++++++++
3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d178fb8..00ca32b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1513,6 +1513,8 @@ struct packet_type {
struct sk_buff **(*gro_receive)(struct sk_buff **head,
struct sk_buff *skb);
int (*gro_complete)(struct sk_buff *skb);
+ bool (*id_match)(struct packet_type *ptype,
+ struct sock *sk);
void *af_packet_priv;
struct list_head list;
};
diff --git a/net/core/dev.c b/net/core/dev.c
index 75da76d..832ba6d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1631,6 +1631,19 @@ static inline int deliver_skb(struct sk_buff *skb,
return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
}
+static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb)
+{
+ if (ptype->af_packet_priv == NULL)
+ return false;
+
+ if (ptype->id_match)
+ return ptype->id_match(ptype, skb->sk);
+ else if ((struct sock *)ptype->af_packet_priv == skb->sk)
+ return true;
+
+ return false;
+}
+
/*
* Support routine. Sends outgoing frames to any network
* taps currently in use.
@@ -1648,8 +1661,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
* they originated from - MvS (miquels@drinkel.ow.org)
*/
if ((ptype->dev == dev || !ptype->dev) &&
- (ptype->af_packet_priv == NULL ||
- (struct sock *)ptype->af_packet_priv != skb->sk)) {
+ (!skb_loop_sk(ptype, skb))) {
if (pt_prev) {
deliver_skb(skb2, pt_prev, skb->dev);
pt_prev = ptype;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 13b14dc..85afc13 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1281,6 +1281,14 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po)
spin_unlock(&f->lock);
}
+bool match_fanout_group(struct packet_type *ptype, struct sock * sk)
+{
+ if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout)
+ return true;
+
+ return false;
+}
+
static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
{
struct packet_sock *po = pkt_sk(sk);
@@ -1333,6 +1341,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
match->prot_hook.dev = po->prot_hook.dev;
match->prot_hook.func = packet_rcv_fanout;
match->prot_hook.af_packet_priv = match;
+ match->prot_hook.id_match = match_fanout_group;
dev_add_pack(&match->prot_hook);
list_add(&match->list, &fanout_list);
}

View File

@ -0,0 +1,47 @@
From: "danborkmann@iogearbox.net" <danborkmann@iogearbox.net>
Date: Fri, 10 Aug 2012 22:48:54 +0000
Subject: af_packet: remove BUG statement in tpacket_destruct_skb
[ Upstream commit 7f5c3e3a80e6654cf48dfba7cf94f88c6b505467 ]
Here's a quote of the comment about the BUG macro from asm-generic/bug.h:
Don't use BUG() or BUG_ON() unless there's really no way out; one
example might be detecting data structure corruption in the middle
of an operation that can't be backed out of. If the (sub)system
can somehow continue operating, perhaps with reduced functionality,
it's probably not BUG-worthy.
If you're tempted to BUG(), think again: is completely giving up
really the *only* solution? There are usually better options, where
users don't need to reboot ASAP and can mostly shut down cleanly.
In our case, the status flag of a ring buffer slot is managed from both sides,
the kernel space and the user space. This means that even though the kernel
side might work as expected, the user space screws up and changes this flag
right between the send(2) is triggered when the flag is changed to
TP_STATUS_SENDING and a given skb is destructed after some time. Then, this
will hit the BUG macro. As David suggested, the best solution is to simply
remove this statement since it cannot be used for kernel side internal
consistency checks. I've tested it and the system still behaves /stable/ in
this case, so in accordance with the above comment, we should rather remove it.
Signed-off-by: Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/packet/af_packet.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index d9d4970..13b14dc 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1931,7 +1931,6 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
if (likely(po->tx_ring.pg_vec)) {
ph = skb_shinfo(skb)->destructor_arg;
- BUG_ON(__packet_get_status(po, ph) != TP_STATUS_SENDING);
BUG_ON(atomic_read(&po->tx_ring.pending) == 0);
atomic_dec(&po->tx_ring.pending);
__packet_set_status(po, ph, TP_STATUS_AVAILABLE);

View File

@ -0,0 +1,29 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:44 +0000
Subject: atm: fix info leak in getsockopt(SO_ATMPVC)
[ Upstream commit e862f1a9b7df4e8196ebec45ac62295138aa3fc2 ]
The ATM code fails to initialize the two padding bytes of struct
sockaddr_atmpvc inserted for alignment. Add an explicit memset(0)
before filling the structure to avoid the info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/atm/common.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/atm/common.c b/net/atm/common.c
index 14ff9fe..0ca06e8 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -784,6 +784,7 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags))
return -ENOTCONN;
+ memset(&pvc, 0, sizeof(pvc));
pvc.sap_family = AF_ATMPVC;
pvc.sap_addr.itf = vcc->dev->number;
pvc.sap_addr.vpi = vcc->vpi;

View File

@ -0,0 +1,29 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:45 +0000
Subject: atm: fix info leak via getsockname()
[ Upstream commit 3c0c5cfdcd4d69ffc4b9c0907cec99039f30a50a ]
The ATM code fails to initialize the two padding bytes of struct
sockaddr_atmpvc inserted for alignment. Add an explicit memset(0)
before filling the structure to avoid the info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/atm/pvc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index 3a73491..ae03240 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -95,6 +95,7 @@ static int pvc_getname(struct socket *sock, struct sockaddr *sockaddr,
return -ENOTCONN;
*sockaddr_len = sizeof(struct sockaddr_atmpvc);
addr = (struct sockaddr_atmpvc *)sockaddr;
+ memset(addr, 0, sizeof(*addr));
addr->sap_family = AF_ATMPVC;
addr->sap_addr.itf = vcc->dev->number;
addr->sap_addr.vpi = vcc->vpi;

View File

@ -0,0 +1,33 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:46 +0000
Subject: Bluetooth: HCI - Fix info leak in getsockopt(HCI_FILTER)
[ Upstream commit e15ca9a0ef9a86f0477530b0f44a725d67f889ee ]
The HCI code fails to initialize the two padding bytes of struct
hci_ufilter before copying it to userland -- that for leaking two
bytes kernel stack. Add an explicit memset(0) before filling the
structure to avoid the info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/bluetooth/hci_sock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index f6afe3d..e4c8bc0 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -671,6 +671,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
{
struct hci_filter *f = &hci_pi(sk)->filter;
+ memset(&uf, 0, sizeof(uf));
uf.type_mask = f->type_mask;
uf.opcode = f->opcode;
uf.event_mask[0] = *((u32 *) f->event_mask + 0);

View File

@ -0,0 +1,33 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:47 +0000
Subject: Bluetooth: HCI - Fix info leak via getsockname()
[ Upstream commit 3f68ba07b1da811bf383b4b701b129bfcb2e4988 ]
The HCI code fails to initialize the hci_channel member of struct
sockaddr_hci and that for leaks two bytes kernel stack via the
getsockname() syscall. Initialize hci_channel with 0 to avoid the
info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/bluetooth/hci_sock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index e4c8bc0..8361ee4 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -388,6 +388,7 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *add
*addr_len = sizeof(*haddr);
haddr->hci_family = AF_BLUETOOTH;
haddr->hci_dev = hdev->id;
+ haddr->hci_channel= 0;
release_sock(sk);
return 0;

View File

@ -0,0 +1,33 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:51 +0000
Subject: Bluetooth: L2CAP - Fix info leak via getsockname()
[ Upstream commit 792039c73cf176c8e39a6e8beef2c94ff46522ed ]
The L2CAP code fails to initialize the l2_bdaddr_type member of struct
sockaddr_l2 and the padding byte added for alignment. It that for leaks
two bytes kernel stack via the getsockname() syscall. Add an explicit
memset(0) before filling the structure to avoid the info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/bluetooth/l2cap_sock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 5c406d3..6dedd6f 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -293,6 +293,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
BT_DBG("sock %p, sk %p", sock, sk);
+ memset(la, 0, sizeof(struct sockaddr_l2));
addr->sa_family = AF_BLUETOOTH;
*len = sizeof(struct sockaddr_l2);

View File

@ -0,0 +1,33 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:48 +0000
Subject: Bluetooth: RFCOMM - Fix info leak in getsockopt(BT_SECURITY)
[ Upstream commit 9ad2de43f1aee7e7274a4e0d41465489299e344b ]
The RFCOMM code fails to initialize the key_size member of struct
bt_security before copying it to userland -- that for leaking one
byte kernel stack. Initialize key_size with 0 to avoid the info
leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/bluetooth/rfcomm/sock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 5417f61..03584bc 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -835,6 +835,7 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
}
sec.level = rfcomm_pi(sk)->sec_level;
+ sec.key_size = 0;
len = min_t(unsigned int, len, sizeof(sec));
if (copy_to_user(optval, (char *) &sec, len))

View File

@ -0,0 +1,37 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:49 +0000
Subject: Bluetooth: RFCOMM - Fix info leak in ioctl(RFCOMMGETDEVLIST)
[ Upstream commit f9432c5ec8b1e9a09b9b0e5569e3c73db8de432a ]
The RFCOMM code fails to initialize the two padding bytes of struct
rfcomm_dev_list_req inserted for alignment before copying it to
userland. Additionally there are two padding bytes in each instance of
struct rfcomm_dev_info. The ioctl() that for disclosures two bytes plus
dev_num times two bytes uninitialized kernel heap memory.
Allocate the memory using kzalloc() to fix this issue.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/bluetooth/rfcomm/tty.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index c258796..bc1eb56 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -471,7 +471,7 @@ static int rfcomm_get_dev_list(void __user *arg)
size = sizeof(*dl) + dev_num * sizeof(*di);
- dl = kmalloc(size, GFP_KERNEL);
+ dl = kzalloc(size, GFP_KERNEL);
if (!dl)
return -ENOMEM;

View File

@ -0,0 +1,33 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:50 +0000
Subject: Bluetooth: RFCOMM - Fix info leak via getsockname()
[ Upstream commit 9344a972961d1a6d2c04d9008b13617bcb6ec2ef ]
The RFCOMM code fails to initialize the trailing padding byte of struct
sockaddr_rc added for alignment. It that for leaks one byte kernel stack
via the getsockname() syscall. Add an explicit memset(0) before filling
the structure to avoid the info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/bluetooth/rfcomm/sock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 03584bc..7ee4ead 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -547,6 +547,7 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
BT_DBG("sock %p, sk %p", sock, sk);
+ memset(sa, 0, sizeof(*sa));
sa->rc_family = AF_BLUETOOTH;
sa->rc_channel = rfcomm_pi(sk)->channel;
if (peer)

View File

@ -0,0 +1,32 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:55 +0000
Subject: dccp: fix info leak via getsockopt(DCCP_SOCKOPT_CCID_TX_INFO)
[ Upstream commit 7b07f8eb75aa3097cdfd4f6eac3da49db787381d ]
The CCID3 code fails to initialize the trailing padding bytes of struct
tfrc_tx_info added for alignment on 64 bit architectures. It that for
potentially leaks four bytes kernel stack via the getsockopt() syscall.
Add an explicit memset(0) before filling the structure to avoid the
info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/dccp/ccids/ccid3.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 3d604e1..4caf63f 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -532,6 +532,7 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
case DCCP_SOCKOPT_CCID_TX_INFO:
if (len < sizeof(tfrc))
return -EINVAL;
+ memset(&tfrc, 0, sizeof(tfrc));
tfrc.tfrctx_x = hc->tx_x;
tfrc.tfrctx_x_recv = hc->tx_x_recv;
tfrc.tfrctx_x_calc = hc->tx_x_calc;

View File

@ -0,0 +1,34 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:56 +0000
Subject: ipvs: fix info leak in getsockopt(IP_VS_SO_GET_TIMEOUT)
[ Upstream commit 2d8a041b7bfe1097af21441cb77d6af95f4f4680 ]
If at least one of CONFIG_IP_VS_PROTO_TCP or CONFIG_IP_VS_PROTO_UDP is
not set, __ip_vs_get_timeouts() does not fully initialize the structure
that gets copied to userland and that for leaks up to 12 bytes of kernel
stack. Add an explicit memset(0) before passing the structure to
__ip_vs_get_timeouts() to avoid the info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Wensong Zhang <wensong@linux-vs.org>
Cc: Simon Horman <horms@verge.net.au>
Cc: Julian Anastasov <ja@ssi.bg>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/netfilter/ipvs/ip_vs_ctl.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index e1a66cf..72f4253 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2713,6 +2713,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
{
struct ip_vs_timeout_user t;
+ memset(&t, 0, sizeof(t));
__ip_vs_get_timeouts(net, &t);
if (copy_to_user(user, &t, sizeof(t)) != 0)
ret = -EFAULT;

View File

@ -0,0 +1,44 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:53 +0000
Subject: llc: fix info leak via getsockname()
[ Upstream commit 3592aaeb80290bda0f2cf0b5456c97bfc638b192 ]
The LLC code wrongly returns 0, i.e. "success", when the socket is
zapped. Together with the uninitialized uaddrlen pointer argument from
sys_getsockname this leads to an arbitrary memory leak of up to 128
bytes kernel stack via the getsockname() syscall.
Return an error instead when the socket is zapped to prevent the info
leak. Also remove the unnecessary memset(0). We don't directly write to
the memory pointed by uaddr but memcpy() a local structure at the end of
the function that is properly initialized.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/llc/af_llc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index a18e6c3..99a60d5 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -966,14 +966,13 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
struct sockaddr_llc sllc;
struct sock *sk = sock->sk;
struct llc_sock *llc = llc_sk(sk);
- int rc = 0;
+ int rc = -EBADF;
memset(&sllc, 0, sizeof(sllc));
lock_sock(sk);
if (sock_flag(sk, SOCK_ZAPPED))
goto out;
*uaddrlen = sizeof(sllc);
- memset(uaddr, 0, *uaddrlen);
if (peer) {
rc = -ENOTCONN;
if (sk->sk_state != TCP_ESTABLISHED)

View File

@ -0,0 +1,34 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Sun, 12 Aug 2012 22:47:41 +0100
Subject: [media] rc: ite-cir: Initialise ite_dev::rdev earlier
Bug-Debian: http://bugs.debian.org/684441
ite_dev::rdev is currently initialised in ite_probe() after
rc_register_device() returns. If a newly registered device is opened
quickly enough, we may enable interrupts and try to use ite_dev::rdev
before it has been initialised. Move it up to the earliest point we
can, right after calling rc_allocate_device().
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/media/rc/ite-cir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1473,6 +1473,7 @@ static int ite_probe(struct pnp_dev *pde
rdev = rc_allocate_device();
if (!rdev)
goto failure;
+ itdev->rdev = rdev;
ret = -ENODEV;
@@ -1604,7 +1605,6 @@ static int ite_probe(struct pnp_dev *pde
if (ret)
goto failure3;
- itdev->rdev = rdev;
ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");
return 0;

View File

@ -0,0 +1,68 @@
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 30 Jul 2012 15:57:00 +0000
Subject: net: Allow driver to limit number of GSO segments per skb
commit 30b678d844af3305cda5953467005cebb5d7b687 upstream.
A peer (or local user) may cause TCP to use a nominal MSS of as little
as 88 (actual MSS of 76 with timestamps). Given that we have a
sufficiently prodigious local sender and the peer ACKs quickly enough,
it is nevertheless possible to grow the window for such a connection
to the point that we will try to send just under 64K at once. This
results in a single skb that expands to 861 segments.
In some drivers with TSO support, such an skb will require hundreds of
DMA descriptors; a substantial fraction of a TX ring or even more than
a full ring. The TX queue selected for the skb may stall and trigger
the TX watchdog repeatedly (since the problem skb will be retried
after the TX reset). This particularly affects sfc, for which the
issue is designated as CVE-2012-3412.
Therefore:
1. Add the field net_device::gso_max_segs holding the device-specific
limit.
2. In netif_skb_features(), if the number of segments is too high then
mask out GSO features to force fall back to software GSO.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/linux/netdevice.h | 2 ++
net/core/dev.c | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index eb06e58..a9db4f3 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1300,6 +1300,8 @@ struct net_device {
/* for setting kernel sock attribute on TCP connection setup */
#define GSO_MAX_SIZE 65536
unsigned int gso_max_size;
+#define GSO_MAX_SEGS 65535
+ u16 gso_max_segs;
#ifdef CONFIG_DCB
/* Data Center Bridging netlink ops */
diff --git a/net/core/dev.c b/net/core/dev.c
index 0cb3fe8..f91abf8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2134,6 +2134,9 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
__be16 protocol = skb->protocol;
netdev_features_t features = skb->dev->features;
+ if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs)
+ features &= ~NETIF_F_GSO_MASK;
+
if (protocol == htons(ETH_P_8021Q)) {
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
protocol = veh->h_vlan_encapsulated_proto;
@@ -5986,6 +5989,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
dev_net_set(dev, &init_net);
dev->gso_max_size = GSO_MAX_SIZE;
+ dev->gso_max_segs = GSO_MAX_SEGS;
INIT_LIST_HEAD(&dev->napi_list);
INIT_LIST_HEAD(&dev->unreg_list);

View File

@ -0,0 +1,31 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Wed, 15 Aug 2012 11:31:57 +0000
Subject: net: fix info leak in compat dev_ifconf()
[ Upstream commit 43da5f2e0d0c69ded3d51907d9552310a6b545e8 ]
The implementation of dev_ifconf() for the compat ioctl interface uses
an intermediate ifc structure allocated in userland for the duration of
the syscall. Though, it fails to initialize the padding bytes inserted
for alignment and that for leaks four bytes of kernel stack. Add an
explicit memset(0) before filling the structure to avoid the info leak.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/socket.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/socket.c b/net/socket.c
index 273cbce..68879db 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2645,6 +2645,7 @@ static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
return -EFAULT;
+ memset(&ifc, 0, sizeof(ifc));
if (ifc32.ifcbuf == 0) {
ifc32.ifc_len = 0;
ifc.ifc_len = 0;

View File

@ -0,0 +1,82 @@
From: Francesco Ruggeri <fruggeri@aristanetworks.com>
Date: Fri, 24 Aug 2012 07:38:35 +0000
Subject: net: ipv4: ipmr_expire_timer causes crash when removing net namespace
[ Upstream commit acbb219d5f53821b2d0080d047800410c0420ea1 ]
When tearing down a net namespace, ipv4 mr_table structures are freed
without first deactivating their timers. This can result in a crash in
run_timer_softirq.
This patch mimics the corresponding behaviour in ipv6.
Locking and synchronization seem to be adequate.
We are about to kfree mrt, so existing code should already make sure that
no other references to mrt are pending or can be created by incoming traffic.
The functions invoked here do not cause new references to mrt or other
race conditions to be created.
Invoking del_timer_sync guarantees that ipmr_expire_timer is inactive.
Both ipmr_expire_process (whose completion we may have to wait in
del_timer_sync) and mroute_clean_tables internally use mfc_unres_lock
or other synchronizations when needed, and they both only modify mrt.
Tested in Linux 3.4.8.
Signed-off-by: Francesco Ruggeri <fruggeri@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/ipv4/ipmr.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index d2aae27..0064394 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -125,6 +125,8 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
static struct kmem_cache *mrt_cachep __read_mostly;
static struct mr_table *ipmr_new_table(struct net *net, u32 id);
+static void ipmr_free_table(struct mr_table *mrt);
+
static int ip_mr_forward(struct net *net, struct mr_table *mrt,
struct sk_buff *skb, struct mfc_cache *cache,
int local);
@@ -132,6 +134,7 @@ static int ipmr_cache_report(struct mr_table *mrt,
struct sk_buff *pkt, vifi_t vifi, int assert);
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
struct mfc_cache *c, struct rtmsg *rtm);
+static void mroute_clean_tables(struct mr_table *mrt);
static void ipmr_expire_process(unsigned long arg);
#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
@@ -272,7 +275,7 @@ static void __net_exit ipmr_rules_exit(struct net *net)
list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) {
list_del(&mrt->list);
- kfree(mrt);
+ ipmr_free_table(mrt);
}
fib_rules_unregister(net->ipv4.mr_rules_ops);
}
@@ -300,7 +303,7 @@ static int __net_init ipmr_rules_init(struct net *net)
static void __net_exit ipmr_rules_exit(struct net *net)
{
- kfree(net->ipv4.mrt);
+ ipmr_free_table(net->ipv4.mrt);
}
#endif
@@ -337,6 +340,13 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
return mrt;
}
+static void ipmr_free_table(struct mr_table *mrt)
+{
+ del_timer_sync(&mrt->ipmr_expire_timer);
+ mroute_clean_tables(mrt);
+ kfree(mrt);
+}
+
/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v)

View File

@ -0,0 +1,66 @@
From: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
Date: Fri, 3 Aug 2012 19:57:52 +0900
Subject: net_sched: gact: Fix potential panic in tcf_gact().
[ Upstream commit 696ecdc10622d86541f2e35cc16e15b6b3b1b67e ]
gact_rand array is accessed by gact->tcfg_ptype whose value
is assumed to less than MAX_RAND, but any range checks are
not performed.
So add a check in tcf_gact_init(). And in tcf_gact(), we can
reduce a branch.
Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/sched/act_gact.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index b77f5a0..bdacd8d 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -67,6 +67,9 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
struct tcf_common *pc;
int ret = 0;
int err;
+#ifdef CONFIG_GACT_PROB
+ struct tc_gact_p *p_parm = NULL;
+#endif
if (nla == NULL)
return -EINVAL;
@@ -82,6 +85,12 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
#ifndef CONFIG_GACT_PROB
if (tb[TCA_GACT_PROB] != NULL)
return -EOPNOTSUPP;
+#else
+ if (tb[TCA_GACT_PROB]) {
+ p_parm = nla_data(tb[TCA_GACT_PROB]);
+ if (p_parm->ptype >= MAX_RAND)
+ return -EINVAL;
+ }
#endif
pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info);
@@ -103,8 +112,7 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
spin_lock_bh(&gact->tcf_lock);
gact->tcf_action = parm->action;
#ifdef CONFIG_GACT_PROB
- if (tb[TCA_GACT_PROB] != NULL) {
- struct tc_gact_p *p_parm = nla_data(tb[TCA_GACT_PROB]);
+ if (p_parm) {
gact->tcfg_paction = p_parm->paction;
gact->tcfg_pval = p_parm->pval;
gact->tcfg_ptype = p_parm->ptype;
@@ -133,7 +141,7 @@ static int tcf_gact(struct sk_buff *skb, const struct tc_action *a,
spin_lock(&gact->tcf_lock);
#ifdef CONFIG_GACT_PROB
- if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL)
+ if (gact->tcfg_ptype)
action = gact_rand[gact->tcfg_ptype](gact);
else
action = gact->tcf_action;

View File

@ -0,0 +1,72 @@
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 23 Aug 2012 02:09:11 +0000
Subject: netlink: fix possible spoofing from non-root processes
[ Upstream commit 20e1db19db5d6b9e4e83021595eab0dc8f107bef ]
Non-root user-space processes can send Netlink messages to other
processes that are well-known for being subscribed to Netlink
asynchronous notifications. This allows ilegitimate non-root
process to send forged messages to Netlink subscribers.
The userspace process usually verifies the legitimate origin in
two ways:
a) Socket credentials. If UID != 0, then the message comes from
some ilegitimate process and the message needs to be dropped.
b) Netlink portID. In general, portID == 0 means that the origin
of the messages comes from the kernel. Thus, discarding any
message not coming from the kernel.
However, ctnetlink sets the portID in event messages that has
been triggered by some user-space process, eg. conntrack utility.
So other processes subscribed to ctnetlink events, eg. conntrackd,
know that the event was triggered by some user-space action.
Neither of the two ways to discard ilegitimate messages coming
from non-root processes can help for ctnetlink.
This patch adds capability validation in case that dst_pid is set
in netlink_sendmsg(). This approach is aggressive since existing
applications using any Netlink bus to deliver messages between
two user-space processes will break. Note that the exception is
NETLINK_USERSOCK, since it is reserved for netlink-to-netlink
userspace communication.
Still, if anyone wants that his Netlink bus allows netlink-to-netlink
userspace, then they can set NL_NONROOT_SEND. However, by default,
I don't think it makes sense to allow to use NETLINK_ROUTE to
communicate two processes that are sending no matter what information
that is not related to link/neighbouring/routing. They should be using
NETLINK_USERSOCK instead for that.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/netlink/af_netlink.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1af8542..38b78b9 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1344,7 +1344,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
dst_pid = addr->nl_pid;
dst_group = ffs(addr->nl_groups);
err = -EPERM;
- if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND))
+ if ((dst_group || dst_pid) &&
+ !netlink_capable(sock, NL_NONROOT_SEND))
goto out;
} else {
dst_pid = nlk->dst_pid;
@@ -2103,6 +2104,7 @@ static void __init netlink_add_usersock_entry(void)
rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);
nl_table[NETLINK_USERSOCK].module = THIS_MODULE;
nl_table[NETLINK_USERSOCK].registered = 1;
+ nl_table[NETLINK_USERSOCK].nl_nonroot = NL_NONROOT_SEND;
netlink_table_ungrab();
}

View File

@ -0,0 +1,217 @@
From: Weiping Pan <wpan@redhat.com>
Date: Mon, 23 Jul 2012 10:37:48 +0800
Subject: rds: set correct msg_namelen
commit 06b6a1cf6e776426766298d055bb3991957d90a7 upstream.
Jay Fenlason (fenlason@redhat.com) found a bug,
that recvfrom() on an RDS socket can return the contents of random kernel
memory to userspace if it was called with a address length larger than
sizeof(struct sockaddr_in).
rds_recvmsg() also fails to set the addr_len paramater properly before
returning, but that's just a bug.
There are also a number of cases wher recvfrom() can return an entirely bogus
address. Anything in rds_recvmsg() that returns a non-negative value but does
not go through the "sin = (struct sockaddr_in *)msg->msg_name;" code path
at the end of the while(1) loop will return up to 128 bytes of kernel memory
to userspace.
And I write two test programs to reproduce this bug, you will see that in
rds_server, fromAddr will be overwritten and the following sock_fd will be
destroyed.
Yes, it is the programmer's fault to set msg_namelen incorrectly, but it is
better to make the kernel copy the real length of address to user space in
such case.
How to run the test programs ?
I test them on 32bit x86 system, 3.5.0-rc7.
1 compile
gcc -o rds_client rds_client.c
gcc -o rds_server rds_server.c
2 run ./rds_server on one console
3 run ./rds_client on another console
4 you will see something like:
server is waiting to receive data...
old socket fd=3
server received data from client:data from client
msg.msg_namelen=32
new socket fd=-1067277685
sendmsg()
: Bad file descriptor
/***************** rds_client.c ********************/
int main(void)
{
int sock_fd;
struct sockaddr_in serverAddr;
struct sockaddr_in toAddr;
char recvBuffer[128] = "data from client";
struct msghdr msg;
struct iovec iov;
sock_fd = socket(AF_RDS, SOCK_SEQPACKET, 0);
if (sock_fd < 0) {
perror("create socket error\n");
exit(1);
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(4001);
if (bind(sock_fd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
perror("bind() error\n");
close(sock_fd);
exit(1);
}
memset(&toAddr, 0, sizeof(toAddr));
toAddr.sin_family = AF_INET;
toAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
toAddr.sin_port = htons(4000);
msg.msg_name = &toAddr;
msg.msg_namelen = sizeof(toAddr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base = recvBuffer;
msg.msg_iov->iov_len = strlen(recvBuffer) + 1;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
if (sendmsg(sock_fd, &msg, 0) == -1) {
perror("sendto() error\n");
close(sock_fd);
exit(1);
}
printf("client send data:%s\n", recvBuffer);
memset(recvBuffer, '\0', 128);
msg.msg_name = &toAddr;
msg.msg_namelen = sizeof(toAddr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base = recvBuffer;
msg.msg_iov->iov_len = 128;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
if (recvmsg(sock_fd, &msg, 0) == -1) {
perror("recvmsg() error\n");
close(sock_fd);
exit(1);
}
printf("receive data from server:%s\n", recvBuffer);
close(sock_fd);
return 0;
}
/***************** rds_server.c ********************/
int main(void)
{
struct sockaddr_in fromAddr;
int sock_fd;
struct sockaddr_in serverAddr;
unsigned int addrLen;
char recvBuffer[128];
struct msghdr msg;
struct iovec iov;
sock_fd = socket(AF_RDS, SOCK_SEQPACKET, 0);
if(sock_fd < 0) {
perror("create socket error\n");
exit(0);
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(4000);
if (bind(sock_fd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
perror("bind error\n");
close(sock_fd);
exit(1);
}
printf("server is waiting to receive data...\n");
msg.msg_name = &fromAddr;
/*
* I add 16 to sizeof(fromAddr), ie 32,
* and pay attention to the definition of fromAddr,
* recvmsg() will overwrite sock_fd,
* since kernel will copy 32 bytes to userspace.
*
* If you just use sizeof(fromAddr), it works fine.
* */
msg.msg_namelen = sizeof(fromAddr) + 16;
/* msg.msg_namelen = sizeof(fromAddr); */
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base = recvBuffer;
msg.msg_iov->iov_len = 128;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
while (1) {
printf("old socket fd=%d\n", sock_fd);
if (recvmsg(sock_fd, &msg, 0) == -1) {
perror("recvmsg() error\n");
close(sock_fd);
exit(1);
}
printf("server received data from client:%s\n", recvBuffer);
printf("msg.msg_namelen=%d\n", msg.msg_namelen);
printf("new socket fd=%d\n", sock_fd);
strcat(recvBuffer, "--data from server");
if (sendmsg(sock_fd, &msg, 0) == -1) {
perror("sendmsg()\n");
close(sock_fd);
exit(1);
}
}
close(sock_fd);
return 0;
}
Signed-off-by: Weiping Pan <wpan@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/rds/recv.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/rds/recv.c b/net/rds/recv.c
index 5c6e9f1..9f0f17c 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -410,6 +410,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
+ msg->msg_namelen = 0;
+
if (msg_flags & MSG_OOB)
goto out;
@@ -485,6 +487,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
sin->sin_port = inc->i_hdr.h_sport;
sin->sin_addr.s_addr = inc->i_saddr;
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+ msg->msg_namelen = sizeof(*sin);
}
break;
}

View File

@ -0,0 +1,153 @@
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 30 Jul 2012 15:57:44 +0000
Subject: sfc: Fix maximum number of TSO segments and minimum TX queue size
commit 7e6d06f0de3f74ca929441add094518ae332257c upstream.
Currently an skb requiring TSO may not fit within a minimum-size TX
queue. The TX queue selected for the skb may stall and trigger the TX
watchdog repeatedly (since the problem skb will be retried after the
TX reset). This issue is designated as CVE-2012-3412.
Set the maximum number of TSO segments for our devices to 100. This
should make no difference to behaviour unless the actual MSS is less
than about 700. Increase the minimum TX queue size accordingly to
allow for 2 worst-case skbs, so that there will definitely be space
to add an skb after we wake a queue.
To avoid invalidating existing configurations, change
efx_ethtool_set_ringparam() to fix up values that are too small rather
than returning -EINVAL.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/sfc/efx.c | 6 ++++++
drivers/net/ethernet/sfc/efx.h | 14 ++++++++++----
drivers/net/ethernet/sfc/ethtool.c | 16 +++++++++++-----
drivers/net/ethernet/sfc/tx.c | 19 +++++++++++++++++++
4 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 70554a1..65a8d49 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1503,6 +1503,11 @@ static int efx_probe_all(struct efx_nic *efx)
goto fail2;
}
+ BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT);
+ if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) {
+ rc = -EINVAL;
+ goto fail3;
+ }
efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
rc = efx_probe_filters(efx);
@@ -2070,6 +2075,7 @@ static int efx_register_netdev(struct efx_nic *efx)
net_dev->irq = efx->pci_dev->irq;
net_dev->netdev_ops = &efx_netdev_ops;
SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
+ net_dev->gso_max_segs = EFX_TSO_MAX_SEGS;
rtnl_lock();
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index be8f915..70755c9 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -30,6 +30,7 @@ extern netdev_tx_t
efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc);
+extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
/* RX */
extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
@@ -52,10 +53,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
#define EFX_MAX_EVQ_SIZE 16384UL
#define EFX_MIN_EVQ_SIZE 512UL
-/* The smallest [rt]xq_entries that the driver supports. Callers of
- * efx_wake_queue() assume that they can subsequently send at least one
- * skb. Falcon/A1 may require up to three descriptors per skb_frag. */
-#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
+/* Maximum number of TCP segments we support for soft-TSO */
+#define EFX_TSO_MAX_SEGS 100
+
+/* The smallest [rt]xq_entries that the driver supports. RX minimum
+ * is a bit arbitrary. For TX, we must have space for at least 2
+ * TSO skbs.
+ */
+#define EFX_RXQ_MIN_ENT 128U
+#define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx))
/* Filters */
extern int efx_probe_filters(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 10536f9..8cba2df 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -680,21 +680,27 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev,
struct ethtool_ringparam *ring)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ u32 txq_entries;
if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
ring->tx_pending > EFX_MAX_DMAQ_SIZE)
return -EINVAL;
- if (ring->rx_pending < EFX_MIN_RING_SIZE ||
- ring->tx_pending < EFX_MIN_RING_SIZE) {
+ if (ring->rx_pending < EFX_RXQ_MIN_ENT) {
netif_err(efx, drv, efx->net_dev,
- "TX and RX queues cannot be smaller than %ld\n",
- EFX_MIN_RING_SIZE);
+ "RX queues cannot be smaller than %u\n",
+ EFX_RXQ_MIN_ENT);
return -EINVAL;
}
- return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
+ txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx));
+ if (txq_entries != ring->tx_pending)
+ netif_warn(efx, drv, efx->net_dev,
+ "increasing TX queue size to minimum of %u\n",
+ txq_entries);
+
+ return efx_realloc_channels(efx, ring->rx_pending, txq_entries);
}
static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index 9b225a7..1871343 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -119,6 +119,25 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr)
return len;
}
+unsigned int efx_tx_max_skb_descs(struct efx_nic *efx)
+{
+ /* Header and payload descriptor for each output segment, plus
+ * one for every input fragment boundary within a segment
+ */
+ unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS;
+
+ /* Possibly one more per segment for the alignment workaround */
+ if (EFX_WORKAROUND_5391(efx))
+ max_descs += EFX_TSO_MAX_SEGS;
+
+ /* Possibly more for PCIe page boundaries within input fragments */
+ if (PAGE_SIZE > EFX_PAGE_SIZE)
+ max_descs += max_t(unsigned int, MAX_SKB_FRAGS,
+ DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE));
+
+ return max_descs;
+}
+
/*
* Add a socket buffer to a TX queue
*

View File

@ -0,0 +1,33 @@
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Sun, 26 Aug 2012 23:35:17 +0200
Subject: speakup: lower default software speech rate
commit cfd757010691eae4e17acc246f74e7622c3a2f05 upstream.
Speech synthesis beginners need a low speech rate, and trained people
want a high speech rate. A medium speech rate is thus actually not a
good default for neither. Since trained people will typically know how
to change the rate, better default for a low speech rate, which
beginners can grasp and learn how to increase it afterwards
This was agreed with users on the speakup mailing list.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/staging/speakup/speakup_soft.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c
index 42cdafe..2a67610 100644
--- a/drivers/staging/speakup/speakup_soft.c
+++ b/drivers/staging/speakup/speakup_soft.c
@@ -46,7 +46,7 @@ static int misc_registered;
static struct var_t vars[] = {
{ CAPS_START, .u.s = {"\x01+3p" } },
{ CAPS_STOP, .u.s = {"\x01-3p" } },
- { RATE, .u.n = {"\x01%ds", 5, 0, 9, 0, 0, NULL } },
+ { RATE, .u.n = {"\x01%ds", 2, 0, 9, 0, 0, NULL } },
{ PITCH, .u.n = {"\x01%dp", 5, 0, 9, 0, 0, NULL } },
{ VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } },
{ TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } },

View File

@ -0,0 +1,135 @@
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 30 Jul 2012 16:11:42 +0000
Subject: tcp: Apply device TSO segment limit earlier
commit 1485348d2424e1131ea42efc033cbd9366462b01 upstream.
Cache the device gso_max_segs in sock::sk_gso_max_segs and use it to
limit the size of TSO skbs. This avoids the need to fall back to
software GSO for local TCP senders.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/sock.h | 2 ++
net/core/sock.c | 1 +
net/ipv4/tcp.c | 4 +++-
net/ipv4/tcp_cong.c | 3 ++-
net/ipv4/tcp_output.c | 21 ++++++++++++---------
5 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index b373023..72132ae 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -218,6 +218,7 @@ struct cg_proto;
* @sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK)
* @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
* @sk_gso_max_size: Maximum GSO segment size to build
+ * @sk_gso_max_segs: Maximum number of GSO segments
* @sk_lingertime: %SO_LINGER l_linger setting
* @sk_backlog: always used with the per-socket spinlock held
* @sk_callback_lock: used with the callbacks in the end of this struct
@@ -338,6 +339,7 @@ struct sock {
netdev_features_t sk_route_nocaps;
int sk_gso_type;
unsigned int sk_gso_max_size;
+ u16 sk_gso_max_segs;
int sk_rcvlowat;
unsigned long sk_lingertime;
struct sk_buff_head sk_error_queue;
diff --git a/net/core/sock.c b/net/core/sock.c
index 6b654b3..8f67ced 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1458,6 +1458,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
} else {
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
sk->sk_gso_max_size = dst->dev->gso_max_size;
+ sk->sk_gso_max_segs = dst->dev->gso_max_segs;
}
}
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index e7e6eea..2109ff4 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -811,7 +811,9 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
old_size_goal + mss_now > xmit_size_goal)) {
xmit_size_goal = old_size_goal;
} else {
- tp->xmit_size_goal_segs = xmit_size_goal / mss_now;
+ tp->xmit_size_goal_segs =
+ min_t(u16, xmit_size_goal / mss_now,
+ sk->sk_gso_max_segs);
xmit_size_goal = tp->xmit_size_goal_segs * mss_now;
}
}
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 4d4db16..1432cdb 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -291,7 +291,8 @@ bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
left = tp->snd_cwnd - in_flight;
if (sk_can_gso(sk) &&
left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&
- left * tp->mss_cache < sk->sk_gso_max_size)
+ left * tp->mss_cache < sk->sk_gso_max_size &&
+ left < sk->sk_gso_max_segs)
return true;
return left <= tcp_max_tso_deferred_mss(tp);
}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3f1bcff..a7b3ec9 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1522,21 +1522,21 @@ static void tcp_cwnd_validate(struct sock *sk)
* when we would be allowed to send the split-due-to-Nagle skb fully.
*/
static unsigned int tcp_mss_split_point(const struct sock *sk, const struct sk_buff *skb,
- unsigned int mss_now, unsigned int cwnd)
+ unsigned int mss_now, unsigned int max_segs)
{
const struct tcp_sock *tp = tcp_sk(sk);
- u32 needed, window, cwnd_len;
+ u32 needed, window, max_len;
window = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
- cwnd_len = mss_now * cwnd;
+ max_len = mss_now * max_segs;
- if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk)))
- return cwnd_len;
+ if (likely(max_len <= window && skb != tcp_write_queue_tail(sk)))
+ return max_len;
needed = min(skb->len, window);
- if (cwnd_len <= needed)
- return cwnd_len;
+ if (max_len <= needed)
+ return max_len;
return needed - needed % mss_now;
}
@@ -1765,7 +1765,8 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
limit = min(send_win, cong_win);
/* If a full-sized TSO skb can be sent, do it. */
- if (limit >= sk->sk_gso_max_size)
+ if (limit >= min_t(unsigned int, sk->sk_gso_max_size,
+ sk->sk_gso_max_segs * tp->mss_cache))
goto send_now;
/* Middle in queue won't get any more data, full sendable already? */
@@ -1999,7 +2000,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
limit = mss_now;
if (tso_segs > 1 && !tcp_urg_mode(tp))
limit = tcp_mss_split_point(sk, skb, mss_now,
- cwnd_quota);
+ min_t(unsigned int,
+ cwnd_quota,
+ sk->sk_gso_max_segs));
if (skb->len > limit &&
unlikely(tso_fragment(sk, skb, limit, mss_now, gfp)))

View File

@ -0,0 +1,99 @@
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Date: Thu, 19 Jul 2012 12:39:14 +0200
Subject: usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams
commit e387ef5c47ddeaeaa3cbdc54424cdb7a28dae2c0 upstream.
Most Logitech UVC webcams (both early models that don't advertise UVC
compatibility and newer UVC-advertised devices) require the RESET_RESUME
quirk. Instead of listing each and every model, match the devices based
on the UVC interface information.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/core/quirks.c | 58 +++++++++++++--------------------------------
1 file changed, 16 insertions(+), 42 deletions(-)
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index cbd15d1..f15501f4c 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -43,53 +43,23 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Creative SB Audigy 2 NX */
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech Webcam C200 */
- { USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Logitech Quickcam Fusion */
+ { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech Webcam C250 */
- { USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Logitech Quickcam Orbit MP */
+ { USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech Webcam C300 */
- { USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Logitech Quickcam Pro for Notebook */
+ { USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech Webcam B/C500 */
- { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Logitech Quickcam Pro 5000 */
+ { USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech Webcam C600 */
- { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Logitech Quickcam OEM Dell Notebook */
+ { USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech Webcam Pro 9000 */
- { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Webcam C905 */
- { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Webcam C210 */
- { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Webcam C260 */
- { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Webcam C310 */
- { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Webcam C910 */
- { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Webcam C160 */
- { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Webcam C270 */
- { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Quickcam Pro 9000 */
- { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Quickcam E3500 */
- { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
-
- /* Logitech Quickcam Vision Pro */
- { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Logitech Quickcam OEM Cisco VT Camera II */
+ { USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME },
/* Logitech Harmony 700-series */
{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
@@ -162,6 +132,10 @@ static const struct usb_device_id usb_quirk_list[] = {
};
static const struct usb_device_id usb_interface_quirk_list[] = {
+ /* Logitech UVC Cameras */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0),
+ .driver_info = USB_QUIRK_RESET_RESUME },
+
{ } /* terminating entry must be last */
};

View File

@ -0,0 +1,250 @@
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Date: Thu, 19 Jul 2012 12:39:13 +0200
Subject: usb: Add quirk detection based on interface information
commit 80da2e0df5af700518611b7d1cc4fc9945bcaf95 upstream.
When a whole class of devices (possibly from a specific vendor, or
across multiple vendors) require a quirk, explictly listing all devices
in the class make the quirks table unnecessarily large. Fix this by
allowing matching devices based on interface information.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/core/driver.c | 38 ++++++++++--------
drivers/usb/core/hub.c | 10 +++--
drivers/usb/core/quirks.c | 93 +++++++++++++++++++++++++++++++++++----------
drivers/usb/core/usb.h | 4 ++
4 files changed, 106 insertions(+), 39 deletions(-)
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -606,22 +606,10 @@ int usb_match_device(struct usb_device *
}
/* returns 0 if no match, 1 if match */
-int usb_match_one_id(struct usb_interface *interface,
- const struct usb_device_id *id)
+int usb_match_one_id_intf(struct usb_device *dev,
+ struct usb_host_interface *intf,
+ const struct usb_device_id *id)
{
- struct usb_host_interface *intf;
- struct usb_device *dev;
-
- /* proc_connectinfo in devio.c may call us with id == NULL. */
- if (id == NULL)
- return 0;
-
- intf = interface->cur_altsetting;
- dev = interface_to_usbdev(interface);
-
- if (!usb_match_device(dev, id))
- return 0;
-
/* The interface class, subclass, and protocol should never be
* checked for a match if the device class is Vendor Specific,
* unless the match record specifies the Vendor ID. */
@@ -646,6 +634,26 @@ int usb_match_one_id(struct usb_interfac
return 1;
}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_host_interface *intf;
+ struct usb_device *dev;
+
+ /* proc_connectinfo in devio.c may call us with id == NULL. */
+ if (id == NULL)
+ return 0;
+
+ intf = interface->cur_altsetting;
+ dev = interface_to_usbdev(interface);
+
+ if (!usb_match_device(dev, id))
+ return 0;
+
+ return usb_match_one_id_intf(dev, intf, id);
+}
EXPORT_SYMBOL_GPL(usb_match_one_id);
/**
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2066,7 +2066,7 @@ static int usb_enumerate_device(struct u
if (err < 0) {
dev_err(&udev->dev, "can't read configurations, error %d\n",
err);
- goto fail;
+ return err;
}
}
if (udev->wusb == 1 && udev->authorized == 0) {
@@ -2082,8 +2082,12 @@ static int usb_enumerate_device(struct u
udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
}
err = usb_enumerate_device_otg(udev);
-fail:
- return err;
+ if (err < 0)
+ return err;
+
+ usb_detect_interface_quirks(udev);
+
+ return 0;
}
static void set_usb_port_removable(struct usb_device *udev)
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -15,17 +15,22 @@
#include <linux/usb/quirks.h>
#include "usb.h"
-/* List of quirky USB devices. Please keep this list ordered by:
+/* Lists of quirky USB devices, split in device quirks and interface quirks.
+ * Device quirks are applied at the very beginning of the enumeration process,
+ * right after reading the device descriptor. They can thus only match on device
+ * information.
+ *
+ * Interface quirks are applied after reading all the configuration descriptors.
+ * They can match on both device and interface information.
+ *
+ * Note that the DELAY_INIT and HONOR_BNUMINTERFACES quirks do not make sense as
+ * interface quirks, as they only influence the enumeration process which is run
+ * before processing the interface quirks.
+ *
+ * Please keep the lists ordered by:
* 1) Vendor ID
* 2) Product ID
* 3) Class ID
- *
- * as we want specific devices to be overridden first, and only after that, any
- * class specific quirks.
- *
- * Right now the logic aborts if it finds a valid device in the table, we might
- * want to change that in the future if it turns out that a whole class of
- * devices is broken...
*/
static const struct usb_device_id usb_quirk_list[] = {
/* CBM - Flash disk */
@@ -156,16 +161,53 @@ static const struct usb_device_id usb_qu
{ } /* terminating entry must be last */
};
-static const struct usb_device_id *find_id(struct usb_device *udev)
+static const struct usb_device_id usb_interface_quirk_list[] = {
+ { } /* terminating entry must be last */
+};
+
+static bool usb_match_any_interface(struct usb_device *udev,
+ const struct usb_device_id *id)
+{
+ unsigned int i;
+
+ for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) {
+ struct usb_host_config *cfg = &udev->config[i];
+ unsigned int j;
+
+ for (j = 0; j < cfg->desc.bNumInterfaces; ++j) {
+ struct usb_interface_cache *cache;
+ struct usb_host_interface *intf;
+
+ cache = cfg->intf_cache[j];
+ if (cache->num_altsetting == 0)
+ continue;
+
+ intf = &cache->altsetting[0];
+ if (usb_match_one_id_intf(udev, intf, id))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static u32 __usb_detect_quirks(struct usb_device *udev,
+ const struct usb_device_id *id)
{
- const struct usb_device_id *id = usb_quirk_list;
+ u32 quirks = 0;
- for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
- id->driver_info; id++) {
- if (usb_match_device(udev, id))
- return id;
+ for (; id->match_flags; id++) {
+ if (!usb_match_device(udev, id))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) &&
+ !usb_match_any_interface(udev, id))
+ continue;
+
+ quirks |= (u32)(id->driver_info);
}
- return NULL;
+
+ return quirks;
}
/*
@@ -173,14 +215,10 @@ static const struct usb_device_id *find_
*/
void usb_detect_quirks(struct usb_device *udev)
{
- const struct usb_device_id *id = usb_quirk_list;
-
- id = find_id(udev);
- if (id)
- udev->quirks = (u32)(id->driver_info);
+ udev->quirks = __usb_detect_quirks(udev, usb_quirk_list);
if (udev->quirks)
dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
- udev->quirks);
+ udev->quirks);
/* For the present, all devices default to USB-PERSIST enabled */
#if 0 /* was: #ifdef CONFIG_PM */
@@ -197,3 +235,16 @@ void usb_detect_quirks(struct usb_device
udev->persist_enabled = 1;
#endif /* CONFIG_PM */
}
+
+void usb_detect_interface_quirks(struct usb_device *udev)
+{
+ u32 quirks;
+
+ quirks = __usb_detect_quirks(udev, usb_interface_quirk_list);
+ if (quirks == 0)
+ return;
+
+ dev_dbg(&udev->dev, "USB interface quirks for this device: %x\n",
+ quirks);
+ udev->quirks |= quirks;
+}
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -24,6 +24,7 @@ extern void usb_disable_device(struct us
extern int usb_deauthorize_device(struct usb_device *);
extern int usb_authorize_device(struct usb_device *);
extern void usb_detect_quirks(struct usb_device *udev);
+extern void usb_detect_interface_quirks(struct usb_device *udev);
extern int usb_remove_device(struct usb_device *udev);
extern int usb_get_device_descriptor(struct usb_device *dev,
@@ -35,6 +36,9 @@ extern int usb_set_configuration(struct
extern int usb_choose_configuration(struct usb_device *udev);
extern void usb_kick_khubd(struct usb_device *dev);
+extern int usb_match_one_id_intf(struct usb_device *dev,
+ struct usb_host_interface *intf,
+ const struct usb_device_id *id);
extern int usb_match_device(struct usb_device *dev,
const struct usb_device_id *id);
extern void usb_forced_unbind_intf(struct usb_interface *intf);

View File

@ -0,0 +1,13 @@
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 4759fe7..b5d44bd 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -12,7 +12,7 @@ NM := $(NM) -B
LDFLAGS_vmlinux := -static -N #-relax
CHECKFLAGS += -D__alpha__ -m64
-cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
+cflags-y := -pipe -mno-fp-regs -ffixed-8 -mlarge-data
cflags-y += $(call cc-option, -fno-jump-tables)
cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4

View File

@ -0,0 +1,27 @@
From: Ben Hutchings <ben@decadent.org.uk>
Subject: debugfs: Set default mode to 700
Bug-Debian: http://bugs.debian.org/681418
As discussed here
<http://lists.linux-foundation.org/pipermail/ksummit-2012-discuss/2012-July/000891.html>.
Mounting of debugfs is a significant security liability, but there are
applications that depend on some interfaces based on debugfs and they
(or their packages) will mount it automatically anyway.
Setting the default mode for the debugfs root to 700 (accessible
to root only) should leave it functional, since most such applications
will require root anyway, and users can override it to relax
permissions if they really don't care about the security problems.
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -28,7 +28,7 @@
#include <linux/magic.h>
#include <linux/slab.h>
-#define DEBUGFS_DEFAULT_MODE 0755
+#define DEBUGFS_DEFAULT_MODE 0700
static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;

View File

@ -1,90 +1,250 @@
From: Bastian Blank <waldi@debian.org>
Subject: Add debian version information to kernel version string
Date: Sun, 20 May 2007 11:46:51 +0200
Include the package version in /proc/version and the initial log
banner.
Determine the target distribution ($DISTRIBUTION) with lsb_release,
defaulting to Debian.
From: Ben Hutchings <ben@decadent.org.uk>
Subject: Include package version along with kernel release in stack traces
Date: Tue, 24 Jul 2012 03:13:10 +0100
For distribution binary packages we assume
$DISTRIBUTION_OFFICIAL_BUILD is set. Add $DISTRIBUTION and
$DISTRIBUTION_VERSION after the kernel version (UTS_RELEASE), and
replace the account name used to build the package with
$DISTRIBUTION_UPLOADER.
$DISTRIBUTION_OFFICIAL_BUILD, $DISTRIBUTOR and $DISTRIBUTION_VERSION
are set.
[bwh: Changed $DISTRIBUTION_UPLOADER to $DISTRIBUTION_MAINTAINER.]
For custom packages built from a linux-source package, read the
package version from version.$DISTRIBUTION and add that after
the kernel version string.
--- a/init/version.c
+++ b/init/version.c
@@ -37,12 +37,31 @@
};
EXPORT_SYMBOL_GPL(init_uts_ns);
--- a/Makefile
+++ b/Makefile
@@ -806,7 +806,7 @@ endif
prepare2: prepare3 outputmakefile asm-generic
-/* FIXED STRINGS! Don't touch! */
const char linux_banner[] =
- "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
- LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
+ "Linux version " UTS_RELEASE
+#ifdef LINUX_COMPILE_DISTRIBUTION_OFFICIAL_BUILD
+ " (" LINUX_COMPILE_DISTRIBUTION " "
+ LINUX_COMPILE_DISTRIBUTION_VERSION ")"
+ " (" LINUX_COMPILE_DISTRIBUTION_MAINTAINER ")"
+#else
+# ifdef LINUX_COMPILE_DISTRIBUTION_VERSION
+ " (" LINUX_COMPILE_DISTRIBUTION_VERSION ")"
+# endif
+ " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
+#endif
+ " (" LINUX_COMPILER ")"
+ " " UTS_VERSION "\n";
prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \
- include/config/auto.conf
+ include/config/auto.conf include/generated/package.h
$(cmd_crmodverdir)
const char linux_proc_banner[] =
"%s version %s"
+#ifdef LINUX_COMPILE_DISTRIBUTION_OFFICIAL_BUILD
+ " (" LINUX_COMPILE_DISTRIBUTION " "
+ LINUX_COMPILE_DISTRIBUTION_VERSION ")"
+ " (" LINUX_COMPILE_DISTRIBUTION_MAINTAINER ")"
+#else
+# ifdef LINUX_COMPILE_DISTRIBUTION_VERSION
+ " (" LINUX_COMPILE_DISTRIBUTION_VERSION ")"
+# endif
" (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
+#endif
" (" LINUX_COMPILER ") %s\n";
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -73,8 +73,26 @@
archprepare: archheaders archscripts prepare1 scripts_basic
@@ -838,12 +838,25 @@ define filechk_version.h
echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
endef
echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"
- echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\"
- echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\"
+ DISTRIBUTION=$(lsb_release -is 2>/dev/null)
+ DISTRIBUTION=${DISTRIBUTION:-Debian}
+ echo \#define LINUX_COMPILE_DISTRIBUTION \"$DISTRIBUTION\"
+ifneq ($(DISTRIBUTION_OFFICIAL_BUILD),)
+define filechk_package.h
+ echo \#define LINUX_PACKAGE_ID \" $(DISTRIBUTOR) $(DISTRIBUTION_VERSION)\"
+endef
+else
+define filechk_package.h
+ echo \#define LINUX_PACKAGE_ID \"\"
+endef
+endif
+
+ if [ "$DISTRIBUTION_OFFICIAL_BUILD" ]; then
+ echo \#define LINUX_COMPILE_DISTRIBUTION_OFFICIAL_BUILD
+ echo \#define LINUX_COMPILE_DISTRIBUTION_MAINTAINER \"$DISTRIBUTION_MAINTAINER\"
+ echo \#define LINUX_COMPILE_DISTRIBUTION_VERSION \"$DISTRIBUTION_VERSION\"
+ echo \#define LINUX_COMPILE_BY \"unknown\"
+ echo \#define LINUX_COMPILE_HOST \"$DISTRIBUTION\"
+ else
+ if [ -e version.$DISTRIBUTION ]; then
+ echo \#define LINUX_COMPILE_DISTRIBUTION_VERSION \"$(cut -d" " -f1 version.$DISTRIBUTION)\"
+ else
+ echo \#define LINUX_COMPILE_DISTRIBUTION_VERSION \"unknown\"
+ fi
+
+ echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\"
+ echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\"
+ fi
include/linux/version.h: $(srctree)/Makefile FORCE
$(call filechk,version.h)
echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\"
) > .tmpcompile
include/generated/utsrelease.h: include/config/kernel.release FORCE
$(call filechk,utsrelease.h)
+include/generated/package.h: $(srctree)/Makefile FORCE
+ $(call filechk,package.h)
+
PHONY += headerdep
headerdep:
$(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -33,6 +33,7 @@
#include <linux/kprobes.h>
#include <linux/bug.h>
#include <linux/utsname.h>
+#include <generated/package.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/atomic.h>
@@ -166,11 +167,12 @@ static void show_last_breaking_event(str
*/
void dump_stack(void)
{
- printk("CPU: %d %s %s %.*s\n",
+ printk("CPU: %d %s %s %.*s%s\n",
task_thread_info(current)->cpu, print_tainted(),
init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
+ init_utsname()->version,
+ LINUX_PACKAGE_ID);
printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
current->comm, current->pid, current,
(void *) current->thread.ksp);
@@ -217,11 +219,12 @@ void show_registers(struct pt_regs *regs
void show_regs(struct pt_regs *regs)
{
print_modules();
- printk("CPU: %d %s %s %.*s\n",
+ printk("CPU: %d %s %s %.*s%s\n",
task_thread_info(current)->cpu, print_tainted(),
init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
+ init_utsname()->version,
+ LINUX_PACKAGE_ID);
printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
current->comm, current->pid, current,
(void *) current->thread.ksp);
--- a/arch/x86/um/sysrq_64.c
+++ b/arch/x86/um/sysrq_64.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/utsname.h>
+#include <generated/package.h>
#include <asm/current.h>
#include <asm/ptrace.h>
#include "sysrq.h"
@@ -16,8 +17,9 @@ void __show_regs(struct pt_regs *regs)
{
printk("\n");
print_modules();
- printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
- current->comm, print_tainted(), init_utsname()->release);
+ printk(KERN_INFO "Pid: %d, comm: %.20s %s %s%s\n", task_pid_nr(current),
+ current->comm, print_tainted(), init_utsname()->release,
+ LINUX_PACKAGE_ID);
printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff,
PT_REGS_IP(regs));
printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs),
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -17,6 +17,7 @@
#include <linux/cpuidle.h>
#include <trace/events/power.h>
#include <linux/hw_breakpoint.h>
+#include <generated/package.h>
#include <asm/cpu.h>
#include <asm/apic.h>
#include <asm/syscalls.h>
@@ -146,11 +147,12 @@ void show_regs_common(void)
board = dmi_get_system_info(DMI_BOARD_NAME);
printk(KERN_CONT "\n");
- printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s",
+ printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s%s",
current->pid, current->comm, print_tainted(),
init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
+ init_utsname()->version,
+ LINUX_PACKAGE_ID);
printk(KERN_CONT " %s %s", vendor, product);
if (board)
printk(KERN_CONT "/%s", board);
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -15,6 +15,7 @@
#include <linux/bug.h>
#include <linux/nmi.h>
#include <linux/sysfs.h>
+#include <generated/package.h>
#include <asm/stacktrace.h>
@@ -188,11 +189,12 @@ void dump_stack(void)
unsigned long stack;
bp = stack_frame(current, NULL);
- printk("Pid: %d, comm: %.20s %s %s %.*s\n",
+ printk("Pid: %d, comm: %.20s %s %s %.*s%s\n",
current->pid, current->comm, print_tainted(),
init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
+ init_utsname()->version,
+ LINUX_PACKAGE_ID);
show_trace(NULL, NULL, &stack, bp);
}
EXPORT_SYMBOL(dump_stack);
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -29,6 +29,7 @@
#include <linux/kdebug.h>
#include <linux/utsname.h>
#include <linux/tracehook.h>
+#include <generated/package.h>
#include <asm/cpu.h>
#include <asm/delay.h>
@@ -112,9 +113,9 @@ show_regs (struct pt_regs *regs)
print_modules();
printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current),
smp_processor_id(), current->comm);
- printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n",
+ printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s%s)\n",
regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
- init_utsname()->release);
+ init_utsname()->release, LINUX_PACKAGE_ID);
print_symbol("ip is at %s\n", ip);
printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -31,6 +31,7 @@
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
#include <linux/cpuidle.h>
+#include <generated/package.h>
#include <asm/cacheflush.h>
#include <asm/leds.h>
@@ -278,11 +279,12 @@ void __show_regs(struct pt_regs *regs)
unsigned long flags;
char buf[64];
- printk("CPU: %d %s (%s %.*s)\n",
+ printk("CPU: %d %s (%s %.*s%s)\n",
raw_smp_processor_id(), print_tainted(),
init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
+ init_utsname()->version,
+ LINUX_PACKAGE_ID);
print_symbol("PC is at %s\n", instruction_pointer(regs));
print_symbol("LR is at %s\n", regs->ARM_lr);
printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n"
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -38,6 +38,7 @@
#include <linux/personality.h>
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
+#include <generated/package.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -644,8 +645,9 @@ void show_regs(struct pt_regs * regs)
printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
regs->nip, regs->link, regs->ctr);
- printk("REGS: %p TRAP: %04lx %s (%s)\n",
- regs, regs->trap, print_tainted(), init_utsname()->release);
+ printk("REGS: %p TRAP: %04lx %s (%s%s)\n",
+ regs, regs->trap, print_tainted(), init_utsname()->release,
+ LINUX_PACKAGE_ID);
printk("MSR: "REG" ", regs->msr);
printbits(regs->msr, msr_bits);
printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -23,6 +23,7 @@
#include <linux/hw_breakpoint.h>
#include <linux/prefetch.h>
#include <linux/stackprotector.h>
+#include <generated/package.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/fpu.h>
@@ -33,10 +34,11 @@ void show_regs(struct pt_regs * regs)
{
printk("\n");
printk("Pid : %d, Comm: \t\t%s\n", task_pid_nr(current), current->comm);
- printk("CPU : %d \t\t%s (%s %.*s)\n\n",
+ printk("CPU : %d \t\t%s (%s %.*s%s)\n\n",
smp_processor_id(), print_tainted(), init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
+ init_utsname()->version,
+ LINUX_PACKAGE_ID);
print_symbol("PC is at %s\n", instruction_pointer(regs));
print_symbol("PR is at %s\n", regs->pr);

View File

@ -0,0 +1,56 @@
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Date: Tue, 10 Jul 2012 19:10:06 -0300
Subject: USB: add USB_VENDOR_AND_INTERFACE_INFO() macro
commit d81a5d1956731c453b85c141458d4ff5d6cc5366 upstream.
A lot of Broadcom Bluetooth devices provides vendor specific interface
class and we are getting flooded by patches adding new device support.
This change will help us enable support for any other Broadcom with vendor
specific device that arrives in the future.
Only the product id changes for those devices, so this macro would be
perfect for us:
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Acked-by: Henrik Rydberg <rydberg@bitmath.se>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/usb.h | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 873956b..30d1ae3 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -861,6 +861,27 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
.bInterfaceSubClass = (sc), \
.bInterfaceProtocol = (pr)
+/**
+ * USB_VENDOR_AND_INTERFACE_INFO - describe a specific usb vendor with a class of usb interfaces
+ * @vend: the 16 bit USB Vendor ID
+ * @cl: bInterfaceClass value
+ * @sc: bInterfaceSubClass value
+ * @pr: bInterfaceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific vendor with a specific class of interfaces.
+ *
+ * This is especially useful when explicitly matching devices that have
+ * vendor specific bDeviceClass values, but standards-compliant interfaces.
+ */
+#define USB_VENDOR_AND_INTERFACE_INFO(vend, cl, sc, pr) \
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
+ | USB_DEVICE_ID_MATCH_VENDOR, \
+ .idVendor = (vend), \
+ .bInterfaceClass = (cl), \
+ .bInterfaceSubClass = (sc), \
+ .bInterfaceProtocol = (pr)
+
/* ----------------------------------------------------------------------- */
/* Stuff for dynamic usb ids */

View File

@ -0,0 +1,93 @@
From: Kees Cook <keescook@chromium.org>
Date: Wed, 25 Jul 2012 17:29:08 -0700
Subject: [2/2] fs: add link restriction audit reporting
commit a51d9eaa41866ab6b4b6ecad7b621f8b66ece0dc upstream.
Adds audit messages for unexpected link restriction violations so that
system owners will have some sort of potentially actionable information
about misbehaving processes.
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/namei.c | 2 ++
include/linux/audit.h | 4 ++++
kernel/audit.c | 21 +++++++++++++++++++++
3 files changed, 27 insertions(+)
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -652,6 +652,7 @@ static inline int may_follow_link(struct
path_put_conditional(link, nd);
path_put(&nd->path);
+ audit_log_link_denied("follow_link", link);
return -EACCES;
}
@@ -720,6 +721,7 @@ static int may_linkat(struct path *link)
capable(CAP_FOWNER))
return 0;
+ audit_log_link_denied("linkat", link);
return -EPERM;
}
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -130,6 +130,7 @@
#define AUDIT_LAST_KERN_ANOM_MSG 1799
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
#define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */
+#define AUDIT_ANOM_LINK 1702 /* Suspicious use of file links */
#define AUDIT_INTEGRITY_DATA 1800 /* Data integrity verification */
#define AUDIT_INTEGRITY_METADATA 1801 /* Metadata integrity verification */
#define AUDIT_INTEGRITY_STATUS 1802 /* Integrity enable status */
@@ -687,6 +688,8 @@ extern void audit_log_d_path(struct
const struct path *path);
extern void audit_log_key(struct audit_buffer *ab,
char *key);
+extern void audit_log_link_denied(const char *operation,
+ struct path *link);
extern void audit_log_lost(const char *message);
#ifdef CONFIG_SECURITY
extern void audit_log_secctx(struct audit_buffer *ab, u32 secid);
@@ -716,6 +719,7 @@ extern int audit_enabled;
#define audit_log_untrustedstring(a,s) do { ; } while (0)
#define audit_log_d_path(b, p, d) do { ; } while (0)
#define audit_log_key(b, k) do { ; } while (0)
+#define audit_log_link_denied(o, l) do { ; } while (0)
#define audit_log_secctx(b,s) do { ; } while (0)
#define audit_enabled 0
#endif
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1450,6 +1450,27 @@ void audit_log_key(struct audit_buffer *
}
/**
+ * audit_log_link_denied - report a link restriction denial
+ * @operation: specific link opreation
+ * @link: the path that triggered the restriction
+ */
+void audit_log_link_denied(const char *operation, struct path *link)
+{
+ struct audit_buffer *ab;
+
+ ab = audit_log_start(current->audit_context, GFP_KERNEL,
+ AUDIT_ANOM_LINK);
+ audit_log_format(ab, "op=%s action=denied", operation);
+ audit_log_format(ab, " pid=%d comm=", current->pid);
+ audit_log_untrustedstring(ab, current->comm);
+ audit_log_d_path(ab, " path=", link);
+ audit_log_format(ab, " dev=");
+ audit_log_untrustedstring(ab, link->dentry->d_inode->i_sb->s_id);
+ audit_log_format(ab, " ino=%lu", link->dentry->d_inode->i_ino);
+ audit_log_end(ab);
+}
+
+/**
* audit_log_end - end one audit record
* @ab: the audit_buffer
*

View File

@ -0,0 +1,356 @@
From: Kees Cook <keescook@chromium.org>
Date: Wed, 25 Jul 2012 17:29:07 -0700
Subject: [1/2] fs: add link restrictions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit 800179c9b8a1e796e441674776d11cd4c05d61d7 upstream.
This adds symlink and hardlink restrictions to the Linux VFS.
Symlinks:
A long-standing class of security issues is the symlink-based
time-of-check-time-of-use race, most commonly seen in world-writable
directories like /tmp. The common method of exploitation of this flaw
is to cross privilege boundaries when following a given symlink (i.e. a
root process follows a symlink belonging to another user). For a likely
incomplete list of hundreds of examples across the years, please see:
http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
The solution is to permit symlinks to only be followed when outside
a sticky world-writable directory, or when the uid of the symlink and
follower match, or when the directory owner matches the symlink's owner.
Some pointers to the history of earlier discussion that I could find:
1996 Aug, Zygo Blaxell
http://marc.info/?l=bugtraq&m=87602167419830&w=2
1996 Oct, Andrew Tridgell
http://lkml.indiana.edu/hypermail/linux/kernel/9610.2/0086.html
1997 Dec, Albert D Cahalan
http://lkml.org/lkml/1997/12/16/4
2005 Feb, Lorenzo Hernández García-Hierro
http://lkml.indiana.edu/hypermail/linux/kernel/0502.0/1896.html
2010 May, Kees Cook
https://lkml.org/lkml/2010/5/30/144
Past objections and rebuttals could be summarized as:
- Violates POSIX.
- POSIX didn't consider this situation and it's not useful to follow
a broken specification at the cost of security.
- Might break unknown applications that use this feature.
- Applications that break because of the change are easy to spot and
fix. Applications that are vulnerable to symlink ToCToU by not having
the change aren't. Additionally, no applications have yet been found
that rely on this behavior.
- Applications should just use mkstemp() or O_CREATE|O_EXCL.
- True, but applications are not perfect, and new software is written
all the time that makes these mistakes; blocking this flaw at the
kernel is a single solution to the entire class of vulnerability.
- This should live in the core VFS.
- This should live in an LSM. (https://lkml.org/lkml/2010/5/31/135)
- This should live in an LSM.
- This should live in the core VFS. (https://lkml.org/lkml/2010/8/2/188)
Hardlinks:
On systems that have user-writable directories on the same partition
as system files, a long-standing class of security issues is the
hardlink-based time-of-check-time-of-use race, most commonly seen in
world-writable directories like /tmp. The common method of exploitation
of this flaw is to cross privilege boundaries when following a given
hardlink (i.e. a root process follows a hardlink created by another
user). Additionally, an issue exists where users can "pin" a potentially
vulnerable setuid/setgid file so that an administrator will not actually
upgrade a system fully.
The solution is to permit hardlinks to only be created when the user is
already the existing file's owner, or if they already have read/write
access to the existing file.
Many Linux users are surprised when they learn they can link to files
they have no access to, so this change appears to follow the doctrine
of "least surprise". Additionally, this change does not violate POSIX,
which states "the implementation may require that the calling process
has permission to access the existing file"[1].
This change is known to break some implementations of the "at" daemon,
though the version used by Fedora and Ubuntu has been fixed[2] for
a while. Otherwise, the change has been undisruptive while in use in
Ubuntu for the last 1.5 years.
[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html
[2] http://anonscm.debian.org/gitweb/?p=collab-maint/at.git;a=commitdiff;h=f4114656c3a6c6f6070e315ffdf940a49eda3279
This patch is based on the patches in Openwall and grsecurity, along with
suggestions from Al Viro. I have added a sysctl to enable the protected
behavior, and documentation.
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[bwh: Backported to 3.2:
- Adjust context
- In path_openat(), convert error from may_follow_link() to filp as it
won't be converted outside the loop]
---
Documentation/sysctl/fs.txt | 42 +++++++++++++++
fs/namei.c | 122 +++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 2 +
kernel/sysctl.c | 18 +++++++
4 files changed, 184 insertions(+)
--- a/Documentation/sysctl/fs.txt
+++ b/Documentation/sysctl/fs.txt
@@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/
- nr_open
- overflowuid
- overflowgid
+- protected_hardlinks
+- protected_symlinks
- suid_dumpable
- super-max
- super-nr
@@ -157,6 +159,46 @@ The default is 65534.
==============================================================
+protected_hardlinks:
+
+A long-standing class of security issues is the hardlink-based
+time-of-check-time-of-use race, most commonly seen in world-writable
+directories like /tmp. The common method of exploitation of this flaw
+is to cross privilege boundaries when following a given hardlink (i.e. a
+root process follows a hardlink created by another user). Additionally,
+on systems without separated partitions, this stops unauthorized users
+from "pinning" vulnerable setuid/setgid files against being upgraded by
+the administrator, or linking to special files.
+
+When set to "0", hardlink creation behavior is unrestricted.
+
+When set to "1" hardlinks cannot be created by users if they do not
+already own the source file, or do not have read/write access to it.
+
+This protection is based on the restrictions in Openwall and grsecurity.
+
+==============================================================
+
+protected_symlinks:
+
+A long-standing class of security issues is the symlink-based
+time-of-check-time-of-use race, most commonly seen in world-writable
+directories like /tmp. The common method of exploitation of this flaw
+is to cross privilege boundaries when following a given symlink (i.e. a
+root process follows a symlink belonging to another user). For a likely
+incomplete list of hundreds of examples across the years, please see:
+http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
+
+When set to "0", symlink following behavior is unrestricted.
+
+When set to "1" symlinks are permitted to be followed only when outside
+a sticky world-writable directory, or when the uid of the symlink and
+follower match, or when the directory owner matches the symlink's owner.
+
+This protection is based on the restrictions in Openwall and grsecurity.
+
+==============================================================
+
suid_dumpable:
This value can be used to query and set the core dump mode for setuid
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -624,6 +624,119 @@ static inline void put_link(struct namei
path_put(link);
}
+int sysctl_protected_symlinks __read_mostly = 1;
+int sysctl_protected_hardlinks __read_mostly = 1;
+
+/**
+ * may_follow_link - Check symlink following for unsafe situations
+ * @link: The path of the symlink
+ *
+ * In the case of the sysctl_protected_symlinks sysctl being enabled,
+ * CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is
+ * in a sticky world-writable directory. This is to protect privileged
+ * processes from failing races against path names that may change out
+ * from under them by way of other users creating malicious symlinks.
+ * It will permit symlinks to be followed only when outside a sticky
+ * world-writable directory, or when the uid of the symlink and follower
+ * match, or when the directory owner matches the symlink's owner.
+ *
+ * Returns 0 if following the symlink is allowed, -ve on error.
+ */
+static inline int may_follow_link(struct path *link, struct nameidata *nd)
+{
+ const struct inode *inode;
+ const struct inode *parent;
+
+ if (!sysctl_protected_symlinks)
+ return 0;
+
+ /* Allowed if owner and follower match. */
+ inode = link->dentry->d_inode;
+ if (current_cred()->fsuid == inode->i_uid)
+ return 0;
+
+ /* Allowed if parent directory not sticky and world-writable. */
+ parent = nd->path.dentry->d_inode;
+ if ((parent->i_mode & (S_ISVTX|S_IWOTH)) != (S_ISVTX|S_IWOTH))
+ return 0;
+
+ /* Allowed if parent directory and link owner match. */
+ if (parent->i_uid == inode->i_uid)
+ return 0;
+
+ path_put_conditional(link, nd);
+ path_put(&nd->path);
+ return -EACCES;
+}
+
+/**
+ * safe_hardlink_source - Check for safe hardlink conditions
+ * @inode: the source inode to hardlink from
+ *
+ * Return false if at least one of the following conditions:
+ * - inode is not a regular file
+ * - inode is setuid
+ * - inode is setgid and group-exec
+ * - access failure for read and write
+ *
+ * Otherwise returns true.
+ */
+static bool safe_hardlink_source(struct inode *inode)
+{
+ umode_t mode = inode->i_mode;
+
+ /* Special files should not get pinned to the filesystem. */
+ if (!S_ISREG(mode))
+ return false;
+
+ /* Setuid files should not get pinned to the filesystem. */
+ if (mode & S_ISUID)
+ return false;
+
+ /* Executable setgid files should not get pinned to the filesystem. */
+ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
+ return false;
+
+ /* Hardlinking to unreadable or unwritable sources is dangerous. */
+ if (inode_permission(inode, MAY_READ | MAY_WRITE))
+ return false;
+
+ return true;
+}
+
+/**
+ * may_linkat - Check permissions for creating a hardlink
+ * @link: the source to hardlink from
+ *
+ * Block hardlink when all of:
+ * - sysctl_protected_hardlinks enabled
+ * - fsuid does not match inode
+ * - hardlink source is unsafe (see safe_hardlink_source() above)
+ * - not CAP_FOWNER
+ *
+ * Returns 0 if successful, -ve on error.
+ */
+static int may_linkat(struct path *link)
+{
+ const struct cred *cred;
+ struct inode *inode;
+
+ if (!sysctl_protected_hardlinks)
+ return 0;
+
+ cred = current_cred();
+ inode = link->dentry->d_inode;
+
+ /* Source inode owner (or CAP_FOWNER) can hardlink all they like,
+ * otherwise, it must be a safe source.
+ */
+ if (cred->fsuid == inode->i_uid || safe_hardlink_source(inode) ||
+ capable(CAP_FOWNER))
+ return 0;
+
+ return -EPERM;
+}
+
static __always_inline int
follow_link(struct path *link, struct nameidata *nd, void **p)
{
@@ -1613,6 +1726,9 @@ static int path_lookupat(int dfd, const
while (err > 0) {
void *cookie;
struct path link = path;
+ err = may_follow_link(&link, nd);
+ if (unlikely(err))
+ break;
nd->flags |= LOOKUP_PARENT;
err = follow_link(&link, nd, &cookie);
if (!err)
@@ -2325,6 +2441,11 @@ static struct file *path_openat(int dfd,
filp = ERR_PTR(-ELOOP);
break;
}
+ error = may_follow_link(&link, nd);
+ if (unlikely(error)) {
+ filp = ERR_PTR(error);
+ break;
+ }
nd->flags |= LOOKUP_PARENT;
nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
error = follow_link(&link, nd, &cookie);
@@ -2972,6 +3093,9 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
error = -EXDEV;
if (old_path.mnt != new_path.mnt)
goto out_dput;
+ error = may_linkat(&old_path);
+ if (unlikely(error))
+ goto out_dput;
error = mnt_want_write(new_path.mnt);
if (error)
goto out_dput;
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -420,6 +420,8 @@ extern unsigned long get_max_files(void)
extern int sysctl_nr_open;
extern struct inodes_stat_t inodes_stat;
extern int leases_enable, lease_break_time;
+extern int sysctl_protected_symlinks;
+extern int sysctl_protected_hardlinks;
struct buffer_head;
typedef int (get_block_t)(struct inode *inode, sector_t iblock,
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1495,6 +1495,24 @@ static struct ctl_table fs_table[] = {
#endif
#endif
{
+ .procname = "protected_symlinks",
+ .data = &sysctl_protected_symlinks,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+ {
+ .procname = "protected_hardlinks",
+ .data = &sysctl_protected_hardlinks,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+ {
.procname = "suid_dumpable",
.data = &suid_dumpable,
.maxlen = sizeof(int),

View File

@ -1,112 +0,0 @@
From 52db90d0fa770e2277645eb34956820cec26b2cb Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Sat, 25 Feb 2012 12:28:44 +1100
Subject: [PATCH 5/5] fs: hardlink creation restriction cleanup
Clean-up of hardlink restriction logic, as suggested by Andrew Morton.
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/namei.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index fe13533..1436fae 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -693,46 +693,72 @@ static inline int may_follow_link(struct path *link)
}
/**
+ * safe_hardlink_source - Check for safe hardlink conditions
+ * @inode: the source inode to hardlink from
+ *
+ * Return false if at least one of the following conditions:
+ * - inode is not a regular file
+ * - inode is setuid
+ * - inode is setgid and group-exec
+ * - access failure for read and write
+ *
+ * Otherwise returns true.
+ */
+static bool safe_hardlink_source(struct inode *inode)
+{
+ mode_t mode = inode->i_mode;
+
+ /* Special files should not get pinned to the filesystem. */
+ if (!S_ISREG(mode))
+ return false;
+
+ /* Setuid files should not get pinned to the filesystem. */
+ if (mode & S_ISUID)
+ return false;
+
+ /* Executable setgid files should not get pinned to the filesystem. */
+ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
+ return false;
+
+ /* Hardlinking to unreadable or unwritable sources is dangerous. */
+ if (inode_permission(inode, MAY_READ | MAY_WRITE))
+ return false;
+
+ return true;
+}
+
+/**
* may_linkat - Check permissions for creating a hardlink
* @link: the source to hardlink from
*
* Block hardlink when all of:
* - sysctl_protected_hardlinks enabled
* - fsuid does not match inode
- * - at least one of:
- * - inode is not a regular file
- * - inode is setuid
- * - inode is setgid and group-exec
- * - access failure for read and write
+ * - hardlink source is unsafe (see safe_hardlink_source() above)
* - not CAP_FOWNER
*
* Returns 0 if successful, -ve on error.
*/
static int may_linkat(struct path *link)
{
- int error = 0;
const struct cred *cred;
struct inode *inode;
- int mode;
if (!sysctl_protected_hardlinks)
return 0;
cred = current_cred();
inode = link->dentry->d_inode;
- mode = inode->i_mode;
-
- if (cred->fsuid != inode->i_uid &&
- (!S_ISREG(mode) || (mode & S_ISUID) ||
- ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
- (inode_permission(inode, MAY_READ | MAY_WRITE))) &&
- !capable(CAP_FOWNER))
- error = -EPERM;
- if (error)
- audit_log_link_denied("linkat", link);
+ /* Source inode owner (or CAP_FOWNER) can hardlink all they like,
+ * otherwise, it must be a safe source.
+ */
+ if (cred->fsuid == inode->i_uid || safe_hardlink_source(inode) ||
+ capable(CAP_FOWNER))
+ return 0;
- return error;
+ audit_log_link_denied("linkat", link);
+ return -EPERM;
}
#else
static inline int may_follow_link(struct path *link)
--
1.7.9.1

View File

@ -1,39 +0,0 @@
From 19f621ccbef745dedad641f44f535e3bcb00f30d Mon Sep 17 00:00:00 2001
From: Andrew Morton <akpm@linux-foundation.org>
Date: Sat, 25 Feb 2012 12:28:43 +1100
Subject: [PATCH 4/5] fs-hardlink-creation-restrictions-fix
uninline may_linkat() and audit_log_link_denied().
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/namei.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 7be190c..fe13533 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -629,8 +629,7 @@ int sysctl_protected_symlinks __read_mostly =
int sysctl_protected_hardlinks __read_mostly =
CONFIG_PROTECTED_HARDLINKS_SYSCTL;
-static inline void
-audit_log_link_denied(const char *operation, struct path *link)
+static void audit_log_link_denied(const char *operation, struct path *link)
{
struct audit_buffer *ab;
@@ -709,7 +708,7 @@ static inline int may_follow_link(struct path *link)
*
* Returns 0 if successful, -ve on error.
*/
-static inline int may_linkat(struct path *link)
+static int may_linkat(struct path *link)
{
int error = 0;
const struct cred *cred;
--
1.7.9.1

View File

@ -1,390 +0,0 @@
From fa3abdeee4e792ed794eef7ea71e7e0073cec32d Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Sat, 25 Feb 2012 12:28:43 +1100
Subject: [PATCH 3/5] fs: hardlink creation restrictions
On systems that have user-writable directories on the same partition as
system files, a long-standing class of security issues is the
hardlink-based time-of-check-time-of-use race, most commonly seen in
world-writable directories like /tmp. The common method of exploitation
of this flaw is to cross privilege boundaries when following a given
hardlink (i.e. a root process follows a hardlink created by another
user). Additionally, an issue exists where users can "pin" a potentially
vulnerable setuid/setgid file so that an administrator will not actually
upgrade a system fully.
The solution is to permit hardlinks to only be created when the user is
already the existing file's owner, or if they already have read/write
access to the existing file.
Many Linux users are surprised when they learn they can link to files they
have no access to, so this change appears to follow the doctrine of "least
surprise". Additionally, this change does not violate POSIX, which states
"the implementation may require that the calling process has permission to
access the existing file"[1].
This change is known to break some implementations of the "at" daemon,
though the version used by Fedora and Ubuntu has been fixed[2] for a
while. Otherwise, the change has been undisruptive while in use in Ubuntu
for the last 1.5 years.
This patch is based on the patch in Openwall and grsecurity. I have added
a sysctl to enable the protected behavior, documentation, and an audit
notification.
[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html
[2] http://anonscm.debian.org/gitweb/?p=collab-maint/at.git;a=commitdiff;h=f4114656c3a6c6f6070e315ffdf940a49eda3279
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Rik van Riel <riel@redhat.com>
Cc: Federica Teodori <federica.teodori@googlemail.com>
Cc: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Eric Paris <eparis@redhat.com>
Cc: Randy Dunlap <rdunlap@xenotime.net>
Cc: Dan Rosenberg <drosenberg@vsecurity.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Documentation/sysctl/fs.txt | 21 ++++++++
fs/Kconfig | 54 ++++++++++++++++------
fs/namei.c | 109 ++++++++++++++++++++++++++++++++-----------
include/linux/fs.h | 1 +
kernel/sysctl.c | 11 ++++-
5 files changed, 153 insertions(+), 43 deletions(-)
diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
index 01daa80..9d29414 100644
--- a/Documentation/sysctl/fs.txt
+++ b/Documentation/sysctl/fs.txt
@@ -32,6 +32,7 @@ Currently, these files are in /proc/sys/fs:
- nr_open
- overflowuid
- overflowgid
+- protected_hardlinks
- protected_symlinks
- suid_dumpable
- super-max
@@ -158,6 +159,26 @@ The default is 65534.
==============================================================
+protected_hardlinks:
+
+A long-standing class of security issues is the hardlink-based
+time-of-check-time-of-use race, most commonly seen in world-writable
+directories like /tmp. The common method of exploitation of this flaw
+is to cross privilege boundaries when following a given hardlink (i.e. a
+root process follows a hardlink created by another user). Additionally,
+on systems without separated partitions, this stops unauthorized users
+from "pinning" vulnerable setuid/setgid files against being upgraded by
+the administrator, or linking to special files.
+
+When set to "0", hardlink creation behavior is unrestricted.
+
+When set to "1" hardlinks cannot be created by users if they do not
+already own the source file, or do not have read/write access to it.
+
+This protection is based on the restrictions in Openwall and grsecurity.
+
+==============================================================
+
protected_symlinks:
A long-standing class of security issues is the symlink-based
diff --git a/fs/Kconfig b/fs/Kconfig
index f2c46f3..d2a422e 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -272,27 +272,29 @@ endif # NETWORK_FILESYSTEMS
source "fs/nls/Kconfig"
source "fs/dlm/Kconfig"
-config PROTECTED_SYMLINKS
- bool "Evaluate vulnerable symlink conditions"
+config PROTECTED_LINKS
+ bool "Evaluate vulnerable link conditions"
default y
help
- A long-standing class of security issues is the symlink-based
+ A long-standing class of security issues is the link-based
time-of-check-time-of-use race, most commonly seen in
world-writable directories like /tmp. The common method of
exploitation of this flaw is to cross privilege boundaries
- when following a given symlink (i.e. a root process follows
- a malicious symlink belonging to another user).
+ when following a given link (i.e. a root process follows
+ a malicious symlink belonging to another user, or a hardlink
+ created to a root-owned file).
- Enabling this adds the logic to examine these dangerous symlink
- conditions. Whether or not the dangerous symlink situations are
- allowed is controlled by PROTECTED_SYMLINKS_ENABLED.
+ Enabling this adds the logic to examine these dangerous link
+ conditions. Whether or not the dangerous link situations are
+ allowed is controlled by PROTECTED_HARDLINKS_ENABLED and
+ PROTECTED_SYMLINKS_ENABLED.
-config PROTECTED_SYMLINKS_ENABLED
- depends on PROTECTED_SYMLINKS
+config PROTECTED_SYMLINKS
+ depends on PROTECTED_LINKS
bool "Disallow symlink following in sticky world-writable dirs"
default y
help
- Solve ToCToU symlink race vulnerablities by permitting symlinks
+ Solve ToCToU symlink race vulnerabilities by permitting symlinks
to be followed only when outside a sticky world-writable directory,
or when the uid of the symlink and follower match, or when the
directory and symlink owners match.
@@ -300,10 +302,34 @@ config PROTECTED_SYMLINKS_ENABLED
When PROC_SYSCTL is enabled, this setting can also be controlled
via /proc/sys/kernel/protected_symlinks.
-config PROTECTED_SYMLINKS_ENABLED_SYSCTL
- depends on PROTECTED_SYMLINKS
+ See Documentation/sysctl/fs.txt for details.
+
+config PROTECTED_SYMLINKS_SYSCTL
+ depends on PROTECTED_LINKS
+ int
+ default "1" if PROTECTED_SYMLINKS
+ default "0"
+
+config PROTECTED_HARDLINKS
+ depends on PROTECTED_LINKS
+ bool "Disallow hardlink creation to non-accessible files"
+ default y
+ help
+ Solve ToCToU hardlink race vulnerabilities by permitting hardlinks
+ to be created only when to a regular file that is owned by the user,
+ or is readable and writable by the user. Also blocks users from
+ "pinning" vulnerable setuid/setgid programs from being upgraded by
+ the administrator.
+
+ When PROC_SYSCTL is enabled, this setting can also be controlled
+ via /proc/sys/kernel/protected_hardlinks.
+
+ See Documentation/sysctl/fs.txt for details.
+
+config PROTECTED_HARDLINKS_SYSCTL
+ depends on PROTECTED_LINKS
int
- default "1" if PROTECTED_SYMLINKS_ENABLED
+ default "1" if PROTECTED_HARDLINKS
default "0"
endmenu
diff --git a/fs/namei.c b/fs/namei.c
index 39edcf7..7be190c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -623,16 +623,33 @@ static inline void put_link(struct nameidata *nd, struct path *link, void *cooki
path_put(link);
}
-#ifdef CONFIG_PROTECTED_SYMLINKS
+#ifdef CONFIG_PROTECTED_LINKS
int sysctl_protected_symlinks __read_mostly =
- CONFIG_PROTECTED_SYMLINKS_ENABLED_SYSCTL;
+ CONFIG_PROTECTED_SYMLINKS_SYSCTL;
+int sysctl_protected_hardlinks __read_mostly =
+ CONFIG_PROTECTED_HARDLINKS_SYSCTL;
+
+static inline void
+audit_log_link_denied(const char *operation, struct path *link)
+{
+ struct audit_buffer *ab;
+
+ ab = audit_log_start(current->audit_context, GFP_KERNEL, AUDIT_AVC);
+ audit_log_format(ab, "op=%s action=denied", operation);
+ audit_log_format(ab, " pid=%d comm=", current->pid);
+ audit_log_untrustedstring(ab, current->comm);
+ audit_log_d_path(ab, " path=", link);
+ audit_log_format(ab, " dev=");
+ audit_log_untrustedstring(ab, link->dentry->d_inode->i_sb->s_id);
+ audit_log_format(ab, " ino=%lu", link->dentry->d_inode->i_ino);
+ audit_log_end(ab);
+}
/**
* may_follow_link - Check symlink following for unsafe situations
- * @dentry: The inode/dentry of the symlink
- * @nameidata: The path data of the symlink
+ * @link: The path of the symlink
*
- * In the case of the protected_symlinks sysctl being enabled,
+ * In the case of the sysctl_protected_symlinks sysctl being enabled,
* CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is
* in a sticky world-writable directory. This is to protect privileged
* processes from failing races against path names that may change out
@@ -643,19 +660,20 @@ int sysctl_protected_symlinks __read_mostly =
*
* Returns 0 if following the symlink is allowed, -ve on error.
*/
-static inline int
-may_follow_link(struct dentry *dentry, struct nameidata *nameidata)
+static inline int may_follow_link(struct path *link)
{
int error = 0;
const struct inode *parent;
const struct inode *inode;
const struct cred *cred;
+ struct dentry *dentry;
if (!sysctl_protected_symlinks)
return 0;
/* Allowed if owner and follower match. */
cred = current_cred();
+ dentry = link->dentry;
inode = dentry->d_inode;
if (cred->fsuid == inode->i_uid)
return 0;
@@ -669,29 +687,61 @@ may_follow_link(struct dentry *dentry, struct nameidata *nameidata)
}
spin_unlock(&dentry->d_lock);
-#ifdef CONFIG_AUDIT
- if (error) {
- struct audit_buffer *ab;
-
- ab = audit_log_start(current->audit_context,
- GFP_KERNEL, AUDIT_AVC);
- audit_log_format(ab, "op=follow_link action=denied");
- audit_log_format(ab, " pid=%d comm=", current->pid);
- audit_log_untrustedstring(ab, current->comm);
- audit_log_d_path(ab, " path=", &nameidata->path);
- audit_log_format(ab, " name=");
- audit_log_untrustedstring(ab, dentry->d_name.name);
- audit_log_format(ab, " dev=");
- audit_log_untrustedstring(ab, inode->i_sb->s_id);
- audit_log_format(ab, " ino=%lu", inode->i_ino);
- audit_log_end(ab);
- }
-#endif
+ if (error)
+ audit_log_link_denied("follow_link", link);
+
+ return error;
+}
+
+/**
+ * may_linkat - Check permissions for creating a hardlink
+ * @link: the source to hardlink from
+ *
+ * Block hardlink when all of:
+ * - sysctl_protected_hardlinks enabled
+ * - fsuid does not match inode
+ * - at least one of:
+ * - inode is not a regular file
+ * - inode is setuid
+ * - inode is setgid and group-exec
+ * - access failure for read and write
+ * - not CAP_FOWNER
+ *
+ * Returns 0 if successful, -ve on error.
+ */
+static inline int may_linkat(struct path *link)
+{
+ int error = 0;
+ const struct cred *cred;
+ struct inode *inode;
+ int mode;
+
+ if (!sysctl_protected_hardlinks)
+ return 0;
+
+ cred = current_cred();
+ inode = link->dentry->d_inode;
+ mode = inode->i_mode;
+
+ if (cred->fsuid != inode->i_uid &&
+ (!S_ISREG(mode) || (mode & S_ISUID) ||
+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
+ (inode_permission(inode, MAY_READ | MAY_WRITE))) &&
+ !capable(CAP_FOWNER))
+ error = -EPERM;
+
+ if (error)
+ audit_log_link_denied("linkat", link);
+
return error;
}
#else
-static inline int
-may_follow_link(struct dentry *dentry, struct nameidata *nameidata)
+static inline int may_follow_link(struct path *link)
+{
+ return 0;
+}
+
+static inline int may_linkat(struct path *link)
{
return 0;
}
@@ -720,7 +770,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p, bool sensitive)
nd_set_link(nd, NULL);
if (sensitive)
- error = may_follow_link(link->dentry, nd);
+ error = may_follow_link(link);
if (!error)
error = security_inode_follow_link(link->dentry, nd);
if (error) {
@@ -3058,6 +3108,9 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
error = -EXDEV;
if (old_path.mnt != new_path.mnt)
goto out_dput;
+ error = may_linkat(&old_path);
+ if (error)
+ goto out_dput;
error = mnt_want_write(new_path.mnt);
if (error)
goto out_dput;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 404cc89..f42a557 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -424,6 +424,7 @@ extern int sysctl_nr_open;
extern struct inodes_stat_t inodes_stat;
extern int leases_enable, lease_break_time;
extern int sysctl_protected_symlinks;
+extern int sysctl_protected_hardlinks;
struct buffer_head;
typedef int (get_block_t)(struct inode *inode, sector_t iblock,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 0624e7c..0b29d58 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1497,7 +1497,7 @@ static struct ctl_table fs_table[] = {
},
#endif
#endif
-#ifdef CONFIG_PROTECTED_SYMLINKS
+#ifdef CONFIG_PROTECTED_LINKS
{
.procname = "protected_symlinks",
.data = &sysctl_protected_symlinks,
@@ -1507,6 +1507,15 @@ static struct ctl_table fs_table[] = {
.extra1 = &zero,
.extra2 = &one,
},
+ {
+ .procname = "protected_hardlinks",
+ .data = &sysctl_protected_hardlinks,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
#endif
{
.procname = "suid_dumpable",
--
1.7.9.1

View File

@ -1,151 +0,0 @@
From d48f814bd83a3cbd95dedaf5e4dd91c05cffddc6 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Sat, 25 Feb 2012 12:28:43 +1100
Subject: [PATCH 2/5] fs-symlink-restrictions-on-sticky-directories-fix-2
s/sticky_//
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Documentation/sysctl/fs.txt | 4 ++--
fs/Kconfig | 16 ++++++++--------
fs/namei.c | 10 +++++-----
include/linux/fs.h | 2 +-
kernel/sysctl.c | 6 +++---
5 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
index 4b47cd5..01daa80 100644
--- a/Documentation/sysctl/fs.txt
+++ b/Documentation/sysctl/fs.txt
@@ -32,7 +32,7 @@ Currently, these files are in /proc/sys/fs:
- nr_open
- overflowuid
- overflowgid
-- protected_sticky_symlinks
+- protected_symlinks
- suid_dumpable
- super-max
- super-nr
@@ -158,7 +158,7 @@ The default is 65534.
==============================================================
-protected_sticky_symlinks:
+protected_symlinks:
A long-standing class of security issues is the symlink-based
time-of-check-time-of-use race, most commonly seen in world-writable
diff --git a/fs/Kconfig b/fs/Kconfig
index d0fdbdd..f2c46f3 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -272,7 +272,7 @@ endif # NETWORK_FILESYSTEMS
source "fs/nls/Kconfig"
source "fs/dlm/Kconfig"
-config PROTECTED_STICKY_SYMLINKS
+config PROTECTED_SYMLINKS
bool "Evaluate vulnerable symlink conditions"
default y
help
@@ -285,10 +285,10 @@ config PROTECTED_STICKY_SYMLINKS
Enabling this adds the logic to examine these dangerous symlink
conditions. Whether or not the dangerous symlink situations are
- allowed is controlled by PROTECTED_STICKY_SYMLINKS_ENABLED.
+ allowed is controlled by PROTECTED_SYMLINKS_ENABLED.
-config PROTECTED_STICKY_SYMLINKS_ENABLED
- depends on PROTECTED_STICKY_SYMLINKS
+config PROTECTED_SYMLINKS_ENABLED
+ depends on PROTECTED_SYMLINKS
bool "Disallow symlink following in sticky world-writable dirs"
default y
help
@@ -298,12 +298,12 @@ config PROTECTED_STICKY_SYMLINKS_ENABLED
directory and symlink owners match.
When PROC_SYSCTL is enabled, this setting can also be controlled
- via /proc/sys/kernel/protected_sticky_symlinks.
+ via /proc/sys/kernel/protected_symlinks.
-config PROTECTED_STICKY_SYMLINKS_ENABLED_SYSCTL
- depends on PROTECTED_STICKY_SYMLINKS
+config PROTECTED_SYMLINKS_ENABLED_SYSCTL
+ depends on PROTECTED_SYMLINKS
int
- default "1" if PROTECTED_STICKY_SYMLINKS_ENABLED
+ default "1" if PROTECTED_SYMLINKS_ENABLED
default "0"
endmenu
diff --git a/fs/namei.c b/fs/namei.c
index 5b4c05b..39edcf7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -623,16 +623,16 @@ static inline void put_link(struct nameidata *nd, struct path *link, void *cooki
path_put(link);
}
-#ifdef CONFIG_PROTECTED_STICKY_SYMLINKS
-int sysctl_protected_sticky_symlinks __read_mostly =
- CONFIG_PROTECTED_STICKY_SYMLINKS_ENABLED_SYSCTL;
+#ifdef CONFIG_PROTECTED_SYMLINKS
+int sysctl_protected_symlinks __read_mostly =
+ CONFIG_PROTECTED_SYMLINKS_ENABLED_SYSCTL;
/**
* may_follow_link - Check symlink following for unsafe situations
* @dentry: The inode/dentry of the symlink
* @nameidata: The path data of the symlink
*
- * In the case of the protected_sticky_symlinks sysctl being enabled,
+ * In the case of the protected_symlinks sysctl being enabled,
* CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is
* in a sticky world-writable directory. This is to protect privileged
* processes from failing races against path names that may change out
@@ -651,7 +651,7 @@ may_follow_link(struct dentry *dentry, struct nameidata *nameidata)
const struct inode *inode;
const struct cred *cred;
- if (!sysctl_protected_sticky_symlinks)
+ if (!sysctl_protected_symlinks)
return 0;
/* Allowed if owner and follower match. */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index aba8db0..404cc89 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -423,7 +423,7 @@ extern unsigned long get_max_files(void);
extern int sysctl_nr_open;
extern struct inodes_stat_t inodes_stat;
extern int leases_enable, lease_break_time;
-extern int sysctl_protected_sticky_symlinks;
+extern int sysctl_protected_symlinks;
struct buffer_head;
typedef int (get_block_t)(struct inode *inode, sector_t iblock,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c469b88..0624e7c 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1497,10 +1497,10 @@ static struct ctl_table fs_table[] = {
},
#endif
#endif
-#ifdef CONFIG_PROTECTED_STICKY_SYMLINKS
+#ifdef CONFIG_PROTECTED_SYMLINKS
{
- .procname = "protected_sticky_symlinks",
- .data = &sysctl_protected_sticky_symlinks,
+ .procname = "protected_symlinks",
+ .data = &sysctl_protected_symlinks,
.maxlen = sizeof(int),
.mode = 0600,
.proc_handler = proc_dointvec_minmax,
--
1.7.9.1

View File

@ -1,316 +0,0 @@
From af16d0017a7de1f00af3966b5013bebfce8a81b4 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Sat, 25 Feb 2012 12:28:42 +1100
Subject: [PATCH 1/5] fs: symlink restrictions on sticky directories
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
A longstanding class of security issues is the symlink-based
time-of-check-time-of-use race, most commonly seen in world-writable
directories like /tmp. The common method of exploitation of this flaw is
to cross privilege boundaries when following a given symlink (i.e. a root
process follows a symlink belonging to another user). For a likely
incomplete list of hundreds of examples across the years, please see:
http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
The solution is to permit symlinks to only be followed when outside a
sticky world-writable directory, or when the uid of the symlink and
follower match, or when the directory owner matches the symlink's owner.
Some pointers to the history of earlier discussion that I could find:
1996 Aug, Zygo Blaxell
http://marc.info/?l=bugtraq&m=87602167419830&w=2
1996 Oct, Andrew Tridgell
http://lkml.indiana.edu/hypermail/linux/kernel/9610.2/0086.html
1997 Dec, Albert D Cahalan
http://lkml.org/lkml/1997/12/16/4
2005 Feb, Lorenzo Hernández García-Hierro
http://lkml.indiana.edu/hypermail/linux/kernel/0502.0/1896.html
2010 May, Kees Cook
https://lkml.org/lkml/2010/5/30/144
Past objections and rebuttals could be summarized as:
- Violates POSIX.
- POSIX didn't consider this situation and it's not useful to follow
a broken specification at the cost of security.
- Might break unknown applications that use this feature.
- Applications that break because of the change are easy to spot and
fix. Applications that are vulnerable to symlink ToCToU by not having
the change aren't. Additionally, no applications have yet been found
that rely on this behavior.
- Applications should just use mkstemp() or O_CREATE|O_EXCL.
- True, but applications are not perfect, and new software is written
all the time that makes these mistakes; blocking this flaw at the
kernel is a single solution to the entire class of vulnerability.
- This should live in the core VFS.
- This should live in an LSM. (https://lkml.org/lkml/2010/5/31/135)
- This should live in an LSM.
- This should live in the core VFS. (https://lkml.org/lkml/2010/8/2/188)
This patch is based on the patch in Openwall and grsecurity, along with
suggestions from Al Viro. I have added a sysctl to enable the protected
behavior, documentation, and an audit notification.
[akpm@linux-foundation.org: move sysctl_protected_sticky_symlinks declaration into .h]
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Rik van Riel <riel@redhat.com>
Cc: Federica Teodori <federica.teodori@googlemail.com>
Cc: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Eric Paris <eparis@redhat.com>
Cc: Randy Dunlap <rdunlap@xenotime.net>
Cc: Dan Rosenberg <drosenberg@vsecurity.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Documentation/sysctl/fs.txt | 21 ++++++++++
fs/Kconfig | 34 ++++++++++++++++
fs/namei.c | 91 ++++++++++++++++++++++++++++++++++++++++---
include/linux/fs.h | 1 +
kernel/sysctl.c | 11 +++++
5 files changed, 152 insertions(+), 6 deletions(-)
--- a/Documentation/sysctl/fs.txt
+++ b/Documentation/sysctl/fs.txt
@@ -32,6 +32,7 @@
- nr_open
- overflowuid
- overflowgid
+- protected_sticky_symlinks
- suid_dumpable
- super-max
- super-nr
@@ -157,6 +158,26 @@
==============================================================
+protected_sticky_symlinks:
+
+A long-standing class of security issues is the symlink-based
+time-of-check-time-of-use race, most commonly seen in world-writable
+directories like /tmp. The common method of exploitation of this flaw
+is to cross privilege boundaries when following a given symlink (i.e. a
+root process follows a symlink belonging to another user). For a likely
+incomplete list of hundreds of examples across the years, please see:
+http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
+
+When set to "0", symlink following behavior is unrestricted.
+
+When set to "1" symlinks are permitted to be followed only when outside
+a sticky world-writable directory, or when the uid of the symlink and
+follower match, or when the directory owner matches the symlink's owner.
+
+This protection is based on the restrictions in Openwall and grsecurity.
+
+==============================================================
+
suid_dumpable:
This value can be used to query and set the core dump mode for setuid
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -277,4 +277,38 @@
source "fs/nls/Kconfig"
source "fs/dlm/Kconfig"
+config PROTECTED_STICKY_SYMLINKS
+ bool "Evaluate vulnerable symlink conditions"
+ default y
+ help
+ A long-standing class of security issues is the symlink-based
+ time-of-check-time-of-use race, most commonly seen in
+ world-writable directories like /tmp. The common method of
+ exploitation of this flaw is to cross privilege boundaries
+ when following a given symlink (i.e. a root process follows
+ a malicious symlink belonging to another user).
+
+ Enabling this adds the logic to examine these dangerous symlink
+ conditions. Whether or not the dangerous symlink situations are
+ allowed is controlled by PROTECTED_STICKY_SYMLINKS_ENABLED.
+
+config PROTECTED_STICKY_SYMLINKS_ENABLED
+ depends on PROTECTED_STICKY_SYMLINKS
+ bool "Disallow symlink following in sticky world-writable dirs"
+ default y
+ help
+ Solve ToCToU symlink race vulnerablities by permitting symlinks
+ to be followed only when outside a sticky world-writable directory,
+ or when the uid of the symlink and follower match, or when the
+ directory and symlink owners match.
+
+ When PROC_SYSCTL is enabled, this setting can also be controlled
+ via /proc/sys/kernel/protected_sticky_symlinks.
+
+config PROTECTED_STICKY_SYMLINKS_ENABLED_SYSCTL
+ depends on PROTECTED_STICKY_SYMLINKS
+ int
+ default "1" if PROTECTED_STICKY_SYMLINKS_ENABLED
+ default "0"
+
endmenu
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -623,10 +623,84 @@
path_put(link);
}
+#ifdef CONFIG_PROTECTED_STICKY_SYMLINKS
+int sysctl_protected_sticky_symlinks __read_mostly =
+ CONFIG_PROTECTED_STICKY_SYMLINKS_ENABLED_SYSCTL;
+
+/**
+ * may_follow_link - Check symlink following for unsafe situations
+ * @dentry: The inode/dentry of the symlink
+ * @nameidata: The path data of the symlink
+ *
+ * In the case of the protected_sticky_symlinks sysctl being enabled,
+ * CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is
+ * in a sticky world-writable directory. This is to protect privileged
+ * processes from failing races against path names that may change out
+ * from under them by way of other users creating malicious symlinks.
+ * It will permit symlinks to be followed only when outside a sticky
+ * world-writable directory, or when the uid of the symlink and follower
+ * match, or when the directory owner matches the symlink's owner.
+ *
+ * Returns 0 if following the symlink is allowed, -ve on error.
+ */
+static inline int
+may_follow_link(struct dentry *dentry, struct nameidata *nameidata)
+{
+ int error = 0;
+ const struct inode *parent;
+ const struct inode *inode;
+ const struct cred *cred;
+
+ if (!sysctl_protected_sticky_symlinks)
+ return 0;
+
+ /* Allowed if owner and follower match. */
+ cred = current_cred();
+ inode = dentry->d_inode;
+ if (cred->fsuid == inode->i_uid)
+ return 0;
+
+ /* Check parent directory mode and owner. */
+ spin_lock(&dentry->d_lock);
+ parent = dentry->d_parent->d_inode;
+ if ((parent->i_mode & (S_ISVTX|S_IWOTH)) == (S_ISVTX|S_IWOTH) &&
+ parent->i_uid != inode->i_uid) {
+ error = -EACCES;
+ }
+ spin_unlock(&dentry->d_lock);
+
+#ifdef CONFIG_AUDIT
+ if (error) {
+ struct audit_buffer *ab;
+
+ ab = audit_log_start(current->audit_context,
+ GFP_KERNEL, AUDIT_AVC);
+ audit_log_format(ab, "op=follow_link action=denied");
+ audit_log_format(ab, " pid=%d comm=", current->pid);
+ audit_log_untrustedstring(ab, current->comm);
+ audit_log_d_path(ab, " path=", &nameidata->path);
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab, dentry->d_name.name);
+ audit_log_format(ab, " dev=");
+ audit_log_untrustedstring(ab, inode->i_sb->s_id);
+ audit_log_format(ab, " ino=%lu", inode->i_ino);
+ audit_log_end(ab);
+ }
+#endif
+ return error;
+}
+#else
+static inline int
+may_follow_link(struct dentry *dentry, struct nameidata *nameidata)
+{
+ return 0;
+}
+#endif
+
static __always_inline int
-follow_link(struct path *link, struct nameidata *nd, void **p)
+follow_link(struct path *link, struct nameidata *nd, void **p, bool sensitive)
{
- int error;
+ int error = 0;
struct dentry *dentry = link->dentry;
BUG_ON(nd->flags & LOOKUP_RCU);
@@ -645,7 +719,10 @@
touch_atime(link);
nd_set_link(nd, NULL);
- error = security_inode_follow_link(link->dentry, nd);
+ if (sensitive)
+ error = may_follow_link(link->dentry, nd);
+ if (!error)
+ error = security_inode_follow_link(link->dentry, nd);
if (error) {
*p = ERR_PTR(error); /* no ->put_link(), please */
path_put(&nd->path);
@@ -1351,7 +1428,7 @@
struct path link = *path;
void *cookie;
- res = follow_link(&link, nd, &cookie);
+ res = follow_link(&link, nd, &cookie, false);
if (!res)
res = walk_component(nd, path, &nd->last,
nd->last_type, LOOKUP_FOLLOW);
@@ -1743,7 +1820,8 @@
void *cookie;
struct path link = path;
nd->flags |= LOOKUP_PARENT;
- err = follow_link(&link, nd, &cookie);
+
+ err = follow_link(&link, nd, &cookie, true);
if (!err)
err = lookup_last(nd, &path);
put_link(nd, &link, cookie);
@@ -2405,7 +2483,8 @@
}
nd->flags |= LOOKUP_PARENT;
nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
- error = follow_link(&link, nd, &cookie);
+
+ error = follow_link(&link, nd, &cookie, true);
if (unlikely(error))
filp = ERR_PTR(error);
else
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -427,6 +427,7 @@
extern int sysctl_nr_open;
extern struct inodes_stat_t inodes_stat;
extern int leases_enable, lease_break_time;
+extern int sysctl_protected_sticky_symlinks;
struct buffer_head;
typedef int (get_block_t)(struct inode *inode, sector_t iblock,
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1493,6 +1493,17 @@
},
#endif
#endif
+#ifdef CONFIG_PROTECTED_STICKY_SYMLINKS
+ {
+ .procname = "protected_sticky_symlinks",
+ .data = &sysctl_protected_sticky_symlinks,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+#endif
{
.procname = "suid_dumpable",
.data = &suid_dumpable,

View File

@ -0,0 +1,27 @@
Subject: ahci: Add JMicron 362 device IDs
From: Ben Hutchings <ben@decadent.org.uk>
Date: Fri, 22 Jul 2011 01:43:22 +0200
The JMicron JMB362 controller supports AHCI only, but some revisions
use the IDE class code. These need to be matched by device ID.
These additions have apparently been included by QNAP in their NAS
devices using these controllers.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/ata/ahci.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -264,6 +264,9 @@ static const struct pci_device_id ahci_p
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
+ /* JMicron 362B and 362C have an AHCI function with IDE class code */
+ { PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
+ { PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
/* ATI */
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */

42
debian/patches/series vendored
View File

@ -41,11 +41,9 @@ bugfix/ia64/nouveau-ACPI-support-is-dependent-on-X86.patch
bugfix/arm/ixp4xx_iobe.patch
debian/x86-memtest-WARN-if-bad-RAM-found.patch
features/all/fs-symlink-restrictions-on-sticky-directories.patch
features/all/fs-symlink-restrictions-on-sticky-directories-fix-2.patch
features/all/fs-hardlink-creation-restrictions.patch
features/all/fs-hardlink-creation-restrictions-fix.patch
features/all/fs-hardlink-creation-restriction-cleanup.patch
# Add link security restrictions from 3.6
features/all/fs-add-link-restrictions.patch
features/all/fs-add-link-restriction-audit-reporting.patch
features/all/wacom/0029-wacom-do-not-request-tablet-data-on-MT-Tablet-PC-pen.patch
features/all/wacom/0030-wacom-ignore-new-style-Wacom-multi-touch-packets-on-.patch
@ -58,3 +56,37 @@ bugfix/all/hwmon-applesmc-Allow-negative-temperature-values.patch
bugfix/all/hwmon-applesmc-Ignore-some-temperature-registers.patch
bugfix/all/hwmon-applesmc-Decode-and-act-on-read-write-status-c.patch
bugfix/x86/mfd-lpc_ich-Fix-a-3.5-kernel-regression-for-iTCO_wdt.patch
debian/debugfs-set-default-mode-to-700.patch
bugfix/all/rds-set-correct-msg_namelen.patch
bugfix/all/media-rc-ite-cir-Initialise-ite_dev-rdev-earlier.patch
features/all/USB-add-USB_VENDOR_AND_INTERFACE_INFO-macro.patch
bugfix/all/usb-Add-quirk-detection-based-on-interface-informati.patch
bugfix/all/usb-Add-USB_QUIRK_RESET_RESUME-for-all-Logitech-UVC-.patch
bugfix/alpha/alpha-use-large-data-model.diff
features/arm/ahci-Add-JMicron-362-device-IDs.patch
bugfix/all/speakup-lower-default-software-speech-rate.patch
# These were all picked from the 3.5.5 patch queue
bugfix/all/net-allow-driver-to-limit-number-of-gso-segments-per-skb.patch
bugfix/all/sfc-fix-maximum-number-of-tso-segments-and-minimum-tx-queue-size.patch
bugfix/all/tcp-apply-device-tso-segment-limit-earlier.patch
bugfix/all/net_sched-gact-fix-potential-panic-in-tcf_gact.patch
bugfix/all/af_packet-remove-bug-statement-in-tpacket_destruct_skb.patch
bugfix/all/atm-fix-info-leak-in-getsockopt-so_atmpvc.patch
bugfix/all/atm-fix-info-leak-via-getsockname.patch
bugfix/all/bluetooth-hci-fix-info-leak-in-getsockopt-hci_filter.patch
bugfix/all/bluetooth-hci-fix-info-leak-via-getsockname.patch
bugfix/all/bluetooth-rfcomm-fix-info-leak-in-getsockopt-bt_security.patch
bugfix/all/bluetooth-rfcomm-fix-info-leak-in-ioctl-rfcommgetdevlist.patch
bugfix/all/bluetooth-rfcomm-fix-info-leak-via-getsockname.patch
bugfix/all/bluetooth-l2cap-fix-info-leak-via-getsockname.patch
bugfix/all/llc-fix-info-leak-via-getsockname.patch
bugfix/all/dccp-fix-info-leak-via-getsockopt-dccp_sockopt_ccid_tx_info.patch
bugfix/all/ipvs-fix-info-leak-in-getsockopt-ip_vs_so_get_timeout.patch
bugfix/all/net-fix-info-leak-in-compat-dev_ifconf.patch
bugfix/all/af_packet-don-t-emit-packet-on-orig-fanout-group.patch
bugfix/all/af_netlink-force-credentials-passing.patch
bugfix/all/netlink-fix-possible-spoofing-from-non-root-processes.patch
bugfix/all/net-ipv4-ipmr_expire_timer-causes-crash-when-removing-net-namespace.patch

7
debian/rules.real vendored
View File

@ -13,6 +13,11 @@ DEB_BUILD_ARCH := $(shell dpkg-architecture -a'$(ARCH)' -qDEB_BUILD_ARCH)
MAINTAINER := $(shell sed -ne 's,^Maintainer: .[^<]*<\([^>]*\)>,\1,p' debian/control)
DISTRIBUTION := $(shell dpkg-parsechangelog | sed -ne 's,^Distribution: ,,p')
DISTRIBUTOR := $(shell lsb_release -is 2>/dev/null)
ifeq ($(DISTRIBUTOR),)
DISTRIBUTOR := Debian
endif
export PYTHONPATH = $(CURDIR)/debian/lib/python
export DH_OPTIONS
export DEB_HOST_ARCH DEB_HOST_GNU_TYPE DEB_BUILD_ARCH
@ -33,7 +38,7 @@ include debian/rules.defs
stamp = [ -d $(dir $@) ] || mkdir $(dir $@); touch $@
setup_env := env -u ABINAME -u ABINAME_PART -u ARCH -u FEATURESET -u FLAVOUR -u VERSION -u LOCALVERSION
setup_env += DISTRIBUTION_OFFICIAL_BUILD=1 DISTRIBUTION_MAINTAINER=$(MAINTAINER) DISTRIBUTION_VERSION="$(SOURCEVERSION)"
setup_env += DISTRIBUTION_OFFICIAL_BUILD=1 DISTRIBUTOR="$(DISTRIBUTOR)" DISTRIBUTION_VERSION="$(SOURCEVERSION)" KBUILD_BUILD_TIMESTAMP="$(DISTRIBUTOR) $(SOURCEVERSION)" KBUILD_BUILD_USER="$(word 1,$(subst @, ,$(MAINTAINER)))" KBUILD_BUILD_HOST="$(word 2,$(subst @, ,$(MAINTAINER)))"
MAKE_CLEAN = $(setup_env) $(MAKE)
MAKE_SELF := $(MAKE) -f debian/rules.real $(MAKEOVERRIDES)

View File

@ -4,7 +4,7 @@ Section: kernel
Provides: linux-source
Depends: binutils, bzip2, ${misc:Depends}
Recommends: libc6-dev | libc-dev, gcc, make
Suggests: libncurses-dev | ncurses-dev, libqt4-dev
Suggests: libncurses-dev | ncurses-dev, libqt4-dev, pkg-config
Multi-Arch: ${linux:Multi-Arch}
Description: Linux kernel source for version @version@ with Debian patches
This package provides source code for the Linux kernel version @version@.