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:
commit
af9147122a
|
@ -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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
[base]
|
||||
flavours: alpha-generic alpha-smp alpha-legacy
|
||||
kernel-arch: alpha
|
||||
compiler: gcc-4.5
|
||||
|
||||
[image]
|
||||
suggests: aboot, fdutils
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
##
|
||||
|
|
|
@ -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
|
||||
##
|
||||
|
|
|
@ -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
|
||||
##
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
fuse
|
|
@ -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 ?
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "../powerpc/fuse-modules"
|
|
@ -0,0 +1 @@
|
|||
#include "../powerpc/fuse-modules"
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -0,0 +1 @@
|
|||
#include <fuse-modules>
|
|
@ -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;
|
||||
|
102
debian/patches/bugfix/all/af_packet-don-t-emit-packet-on-orig-fanout-group.patch
vendored
Normal file
102
debian/patches/bugfix/all/af_packet-don-t-emit-packet-on-orig-fanout-group.patch
vendored
Normal 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);
|
||||
}
|
47
debian/patches/bugfix/all/af_packet-remove-bug-statement-in-tpacket_destruct_skb.patch
vendored
Normal file
47
debian/patches/bugfix/all/af_packet-remove-bug-statement-in-tpacket_destruct_skb.patch
vendored
Normal 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);
|
|
@ -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;
|
|
@ -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;
|
33
debian/patches/bugfix/all/bluetooth-hci-fix-info-leak-in-getsockopt-hci_filter.patch
vendored
Normal file
33
debian/patches/bugfix/all/bluetooth-hci-fix-info-leak-in-getsockopt-hci_filter.patch
vendored
Normal 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);
|
|
@ -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;
|
33
debian/patches/bugfix/all/bluetooth-l2cap-fix-info-leak-via-getsockname.patch
vendored
Normal file
33
debian/patches/bugfix/all/bluetooth-l2cap-fix-info-leak-via-getsockname.patch
vendored
Normal 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);
|
||||
|
33
debian/patches/bugfix/all/bluetooth-rfcomm-fix-info-leak-in-getsockopt-bt_security.patch
vendored
Normal file
33
debian/patches/bugfix/all/bluetooth-rfcomm-fix-info-leak-in-getsockopt-bt_security.patch
vendored
Normal 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))
|
37
debian/patches/bugfix/all/bluetooth-rfcomm-fix-info-leak-in-ioctl-rfcommgetdevlist.patch
vendored
Normal file
37
debian/patches/bugfix/all/bluetooth-rfcomm-fix-info-leak-in-ioctl-rfcommgetdevlist.patch
vendored
Normal 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;
|
||||
|
33
debian/patches/bugfix/all/bluetooth-rfcomm-fix-info-leak-via-getsockname.patch
vendored
Normal file
33
debian/patches/bugfix/all/bluetooth-rfcomm-fix-info-leak-via-getsockname.patch
vendored
Normal 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)
|
32
debian/patches/bugfix/all/dccp-fix-info-leak-via-getsockopt-dccp_sockopt_ccid_tx_info.patch
vendored
Normal file
32
debian/patches/bugfix/all/dccp-fix-info-leak-via-getsockopt-dccp_sockopt_ccid_tx_info.patch
vendored
Normal 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;
|
34
debian/patches/bugfix/all/ipvs-fix-info-leak-in-getsockopt-ip_vs_so_get_timeout.patch
vendored
Normal file
34
debian/patches/bugfix/all/ipvs-fix-info-leak-in-getsockopt-ip_vs_so_get_timeout.patch
vendored
Normal 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;
|
|
@ -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)
|
34
debian/patches/bugfix/all/media-rc-ite-cir-Initialise-ite_dev-rdev-earlier.patch
vendored
Normal file
34
debian/patches/bugfix/all/media-rc-ite-cir-Initialise-ite_dev-rdev-earlier.patch
vendored
Normal 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;
|
68
debian/patches/bugfix/all/net-allow-driver-to-limit-number-of-gso-segments-per-skb.patch
vendored
Normal file
68
debian/patches/bugfix/all/net-allow-driver-to-limit-number-of-gso-segments-per-skb.patch
vendored
Normal 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);
|
|
@ -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;
|
|
@ -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)
|
66
debian/patches/bugfix/all/net_sched-gact-fix-potential-panic-in-tcf_gact.patch
vendored
Normal file
66
debian/patches/bugfix/all/net_sched-gact-fix-potential-panic-in-tcf_gact.patch
vendored
Normal 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;
|
72
debian/patches/bugfix/all/netlink-fix-possible-spoofing-from-non-root-processes.patch
vendored
Normal file
72
debian/patches/bugfix/all/netlink-fix-possible-spoofing-from-non-root-processes.patch
vendored
Normal 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();
|
||||
}
|
|
@ -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;
|
||||
}
|
153
debian/patches/bugfix/all/sfc-fix-maximum-number-of-tso-segments-and-minimum-tx-queue-size.patch
vendored
Normal file
153
debian/patches/bugfix/all/sfc-fix-maximum-number-of-tso-segments-and-minimum-tx-queue-size.patch
vendored
Normal 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
|
||||
*
|
|
@ -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 } },
|
|
@ -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)))
|
99
debian/patches/bugfix/all/usb-Add-USB_QUIRK_RESET_RESUME-for-all-Logitech-UVC-.patch
vendored
Normal file
99
debian/patches/bugfix/all/usb-Add-USB_QUIRK_RESET_RESUME-for-all-Logitech-UVC-.patch
vendored
Normal 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 */
|
||||
};
|
||||
|
250
debian/patches/bugfix/all/usb-Add-quirk-detection-based-on-interface-informati.patch
vendored
Normal file
250
debian/patches/bugfix/all/usb-Add-quirk-detection-based-on-interface-informati.patch
vendored
Normal 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);
|
|
@ -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
|
|
@ -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;
|
|
@ -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);
|
||||
|
|
56
debian/patches/features/all/USB-add-USB_VENDOR_AND_INTERFACE_INFO-macro.patch
vendored
Normal file
56
debian/patches/features/all/USB-add-USB_VENDOR_AND_INTERFACE_INFO-macro.patch
vendored
Normal 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 */
|
|
@ -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
|
||||
*
|
|
@ -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),
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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@.
|
||||
|
|
Loading…
Reference in New Issue