patch-2.4.23 linux-2.4.23/net/atm/addr.c

Next file: linux-2.4.23/net/atm/atm_misc.c
Previous file: linux-2.4.23/net/Makefile
Back to the patch index
Back to the overall index

diff -urN linux-2.4.22/net/atm/addr.c linux-2.4.23/net/atm/addr.c
@@ -118,23 +118,24 @@
 {
 	unsigned long flags;
 	struct atm_dev_addr *walk;
-	int total;
+	int total = 0, error;
+	struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
+
 
 	spin_lock_irqsave(&dev->lock, flags);
-	total = 0;
-	for (walk = dev->local; walk; walk = walk->next) {
+	for (walk = dev->local; walk; walk = walk->next)
 		total += sizeof(struct sockaddr_atmsvc);
-		if (total > size) {
-			spin_unlock_irqrestore(&dev->lock, flags);
-			return -E2BIG;
-		}
-		if (copy_to_user(u_buf,&walk->addr,
-		    sizeof(struct sockaddr_atmsvc))) {
-			spin_unlock_irqrestore(&dev->lock, flags);
-			return -EFAULT;
-		}
-		u_buf++;
+	tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
+	if (!tmp_buf) {
+		spin_unlock_irqrestore(&dev->lock, flags);
+		return -ENOMEM;
 	}
+	for (walk = dev->local; walk; walk = walk->next)
+		memcpy(tmp_bufp++, &walk->addr, sizeof(struct sockaddr_atmsvc));
 	spin_unlock_irqrestore(&dev->lock, flags);
-	return total;
+	error = total > size ? -E2BIG : total;
+	if (copy_to_user(u_buf, tmp_buf, total < size ? total : size))
+		error = -EFAULT;
+	kfree(tmp_buf);
+	return error;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)