lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20060717141022.GC11675@kroah.com>
Date:	Mon, 17 Jul 2006 07:10:22 -0700
From:	Greg KH <gregkh@...e.de>
To:	linux-kernel@...r.kernel.org, Andrew Morton <akpm@...l.org>,
	torvalds@...l.org, stable@...nel.org
Subject: Re: Linux 2.6.16.27

diff --git a/Makefile b/Makefile
index bea535b..4c2e2bd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 16
-EXTRAVERSION = .26
+EXTRAVERSION = .27
 NAME=Sliding Snow Leopard
 
 # *DOCUMENTATION*
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c145e1e..b64b9d3 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/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 @@ #define WDR_SHORT_TIMEOUT 1000	/* shorte
 #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 */
 
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 19727d9..99e960c 100644
--- a/net/ipv6/addrconf.c
+++ b/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;
 }
 
@@ -1059,6 +1065,9 @@ #ifdef CONFIG_IPV6_PRIVACY
 				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) {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ