* [patch 1/3] IPV6: Fix source address selection.
2006-07-13 22:10 ` [patch 0/3] 2.6.16-stable review Greg KH
@ 2006-07-13 22:10 ` Greg KH
2006-07-13 22:10 ` [patch 2/3] IPV6 ADDRCONF: Fix default source address selection without CONFIG_IPV6_PRIVACY Greg KH
2006-07-13 22:10 ` [patch 3/3] USB serial ftdi_sio: Prevent userspace DoS (CVE-2006-2936) Greg KH
2 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2006-07-13 22:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Justin Forbes, Zwane Mwaikambo, Theodore Ts'o, Randy Dunlap,
Dave Jones, Chuck Wolber, Chris Wedgwood, torvalds, akpm, alan,
aukasz Stelmach, YOSHIFUJI Hideaki, David S. Miller, Chris Wright,
Greg Kroah-Hartman
[-- Attachment #1: ipv6-fix-source-address-selection.patch --]
[-- Type: text/plain, Size: 1455 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
From: aukasz Stelmach <stlman@poczta.fm>
Two additional labels (RFC 3484, sec. 10.3) for IPv6 addreses
are defined to make a distinction between global unicast
addresses and Unique Local Addresses (fc00::/7, RFC 4193) and
Teredo (2001::/32, RFC 4380). It is necessary to avoid attempts
of connection that would either fail (eg. fec0:: to 2001:feed::)
or be sub-optimal (2001:0:: to 2001:feed::).
Signed-off-by: aukasz Stelmach <stlman@poczta.fm>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
net/ipv6/addrconf.c | 6 ++++++
1 file changed, 6 insertions(+)
--- linux-2.6.16.22.orig/net/ipv6/addrconf.c
+++ linux-2.6.16.22/net/ipv6/addrconf.c
@@ -852,6 +852,8 @@ static int inline ipv6_saddr_label(const
* 2002::/16 2
* ::/96 3
* ::ffff:0:0/96 4
+ * fc00::/7 5
+ * 2001::/32 6
*/
if (type & IPV6_ADDR_LOOPBACK)
return 0;
@@ -859,8 +861,12 @@ static int inline ipv6_saddr_label(const
return 3;
else if (type & IPV6_ADDR_MAPPED)
return 4;
+ else if (addr->s6_addr32[0] == htonl(0x20010000))
+ return 6;
else if (addr->s6_addr16[0] == htons(0x2002))
return 2;
+ else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
+ return 5;
return 1;
}
--
^ permalink raw reply [flat|nested] 4+ messages in thread* [patch 2/3] IPV6 ADDRCONF: Fix default source address selection without CONFIG_IPV6_PRIVACY
2006-07-13 22:10 ` [patch 0/3] 2.6.16-stable review Greg KH
2006-07-13 22:10 ` [patch 1/3] IPV6: Fix source address selection Greg KH
@ 2006-07-13 22:10 ` Greg KH
2006-07-13 22:10 ` [patch 3/3] USB serial ftdi_sio: Prevent userspace DoS (CVE-2006-2936) Greg KH
2 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2006-07-13 22:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Justin Forbes, Zwane Mwaikambo, Theodore Ts'o, Randy Dunlap,
Dave Jones, Chuck Wolber, Chris Wedgwood, torvalds, akpm, alan,
YOSHIFUJI Hideaki, David S Miller, Chris Wright,
Greg Kroah-Hartman
[-- Attachment #1: ipv6-addrconf-fix-default-source-address-selection-without-config_ipv6_privacy.patch --]
[-- Type: text/plain, Size: 925 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
We need to update hiscore.rule even if we don't enable CONFIG_IPV6_PRIVACY,
because we have more less significant rule; longest match.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S Miller <davem@davemloft.net>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
net/ipv6/addrconf.c | 3 +++
1 file changed, 3 insertions(+)
--- linux-2.6.16.22.orig/net/ipv6/addrconf.c
+++ linux-2.6.16.22/net/ipv6/addrconf.c
@@ -1065,6 +1065,9 @@ int ipv6_dev_get_saddr(struct net_device
if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
continue;
}
+#else
+ if (hiscore.rule < 7)
+ hiscore.rule++;
#endif
/* Rule 8: Use longest matching prefix */
if (hiscore.rule < 8) {
--
^ permalink raw reply [flat|nested] 4+ messages in thread* [patch 3/3] USB serial ftdi_sio: Prevent userspace DoS (CVE-2006-2936)
2006-07-13 22:10 ` [patch 0/3] 2.6.16-stable review Greg KH
2006-07-13 22:10 ` [patch 1/3] IPV6: Fix source address selection Greg KH
2006-07-13 22:10 ` [patch 2/3] IPV6 ADDRCONF: Fix default source address selection without CONFIG_IPV6_PRIVACY Greg KH
@ 2006-07-13 22:10 ` Greg KH
2 siblings, 0 replies; 4+ messages in thread
From: Greg KH @ 2006-07-13 22:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Justin Forbes, Zwane Mwaikambo, Theodore Ts'o, Randy Dunlap,
Dave Jones, Chuck Wolber, Chris Wedgwood, torvalds, akpm, alan,
Ian Abbott, Greg Kroah-Hartman
[-- Attachment #1: USB-serial-ftdi_sio-Prevent-userspace-DoS.patch --]
[-- Type: text/plain, Size: 5564 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ian Abbott <abbotti@mev.co.uk>
This patch limits the amount of outstanding 'write' data that can be
queued up for the ftdi_sio driver, to prevent userspace DoS attacks (or
simple accidents) that use up all the system memory by writing lots of
data to the serial port.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/usb/serial/ftdi_sio.c | 84 +++++++++++++++++++++++++++++++++++-------
1 file changed, 71 insertions(+), 13 deletions(-)
--- linux-2.6.16.24.orig/drivers/usb/serial/ftdi_sio.c
+++ linux-2.6.16.24/drivers/usb/serial/ftdi_sio.c
@@ -545,6 +545,10 @@ struct ftdi_private {
int force_baud; /* if non-zero, force the baud rate to this value */
int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
+
+ spinlock_t tx_lock; /* spinlock for transmit state */
+ unsigned long tx_outstanding_bytes;
+ unsigned long tx_outstanding_urbs;
};
/* Used for TIOCMIWAIT */
@@ -618,6 +622,9 @@ static struct usb_serial_driver ftdi_sio
#define HIGH 1
#define LOW 0
+/* number of outstanding urbs to prevent userspace DoS from happening */
+#define URB_UPPER_LIMIT 42
+
/*
* ***************************************************************************
* Utlity functions
@@ -1149,6 +1156,7 @@ static int ftdi_sio_attach (struct usb_s
memset(priv, 0, sizeof(*priv));
spin_lock_init(&priv->rx_lock);
+ spin_lock_init(&priv->tx_lock);
init_waitqueue_head(&priv->delta_msr_wait);
/* This will push the characters through immediately rather
than queue a task to deliver them */
@@ -1365,6 +1373,7 @@ static int ftdi_write (struct usb_serial
int data_offset ; /* will be 1 for the SIO and 0 otherwise */
int status;
int transfer_size;
+ unsigned long flags;
dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);
@@ -1372,6 +1381,13 @@ static int ftdi_write (struct usb_serial
dbg("write request of 0 bytes");
return 0;
}
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) {
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ dbg("%s - write limit hit\n", __FUNCTION__);
+ return 0;
+ }
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
data_offset = priv->write_offset;
dbg("data_offset set to %d",data_offset);
@@ -1438,6 +1454,11 @@ static int ftdi_write (struct usb_serial
err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
count = status;
kfree (buffer);
+ } else {
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ ++priv->tx_outstanding_urbs;
+ priv->tx_outstanding_bytes += count;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
}
/* we are done with this urb, so let the host driver
@@ -1453,7 +1474,11 @@ static int ftdi_write (struct usb_serial
static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
{
+ unsigned long flags;
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct ftdi_private *priv;
+ int data_offset; /* will be 1 for the SIO and 0 otherwise */
+ unsigned long countback;
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
@@ -1465,34 +1490,67 @@ static void ftdi_write_bulk_callback (st
return;
}
+ priv = usb_get_serial_port_data(port);
+ if (!priv) {
+ dbg("%s - bad port private data pointer - exiting", __FUNCTION__);
+ return;
+ }
+ /* account for transferred data */
+ countback = urb->actual_length;
+ data_offset = priv->write_offset;
+ if (data_offset > 0) {
+ /* Subtract the control bytes */
+ countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ));
+ }
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ --priv->tx_outstanding_urbs;
+ priv->tx_outstanding_bytes -= countback;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
schedule_work(&port->work);
} /* ftdi_write_bulk_callback */
static int ftdi_write_room( struct usb_serial_port *port )
{
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ int room;
+ unsigned long flags;
+
dbg("%s - port %d", __FUNCTION__, port->number);
- /*
- * We really can take anything the user throws at us
- * but let's pick a nice big number to tell the tty
- * layer that we have lots of free space
- */
- return 2048;
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) {
+ /*
+ * We really can take anything the user throws at us
+ * but let's pick a nice big number to tell the tty
+ * layer that we have lots of free space
+ */
+ room = 2048;
+ } else {
+ room = 0;
+ }
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return room;
} /* ftdi_write_room */
static int ftdi_chars_in_buffer (struct usb_serial_port *port)
{ /* ftdi_chars_in_buffer */
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ int buffered;
+ unsigned long flags;
+
dbg("%s - port %d", __FUNCTION__, port->number);
- /*
- * We can't really account for how much data we
- * have sent out, but hasn't made it through to the
- * device, so just tell the tty layer that everything
- * is flushed.
- */
- return 0;
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ buffered = (int)priv->tx_outstanding_bytes;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ if (buffered < 0) {
+ err("%s outstanding tx bytes is negative!", __FUNCTION__);
+ buffered = 0;
+ }
+ return buffered;
} /* ftdi_chars_in_buffer */
--
^ permalink raw reply [flat|nested] 4+ messages in thread