[klibc] PATCH: Bug in function bootp_parse in file bootp_proto.c

Άλκης Άλκης
Sat Oct 11 03:03:08 PDT 2008


Στις 09-10-2008, ημέρα Πεμ, και ώρα 19:37 +0300, ο/η Άλκης Γεωργόπουλος έγραψε:
> I propose to fix it by introducing a 
>   void *memcpy_null_terminate(dest, src, dest_len, src_len);
> function.

I've implemented this and I'm sending the git diff as an attachment.
It's a diff from my previous patch, not from the klibc current git head.

Peter, could you please have a look at the last 2 patches for possible
inclusion before I start with the next (big one) patch?

Because, being a git newbie, if you tell me later to revert to a
previous point and reapply a patch, I don't think I'll be easy for me to
do it! :)
And this particular bug *could* be responsible for some of the lost
packets, so debugging will be easier without it.

Kind regards,
Alkis Georgopoulos
-------------- next part --------------
commit 2f3a74f94edda260ba5b069458efad5943d1e828
Author: Άλκης Γεωργόπουλος <alkisg at gmail.com>
Date:   Sat Oct 11 12:38:29 2008 +0300

    Signed-off-by: Alkis Georgopoulos <alkisg at gmail.com>
    
    Fixed an error in dhcp option parsing

diff --git a/usr/kinit/ipconfig/bootp_proto.c b/usr/kinit/ipconfig/bootp_proto.c
index b138e0f..01cff1b 100644
--- a/usr/kinit/ipconfig/bootp_proto.c
+++ b/usr/kinit/ipconfig/bootp_proto.c
@@ -29,6 +29,25 @@ static uint8_t bootp_options[312] = {
 };
 
 /*
+ * Copy min(dest_n, src_n) bytes from src to dest and return dest.
+ * Ensure that dest is null terminated.
+ */
+static void *memncpy(void *dest, const void *src, size_t dest_n, size_t src_n)
+{
+	size_t min = dest_n < src_n ? dest_n : src_n;
+	
+	memcpy(dest, src, min);
+	if (dest_n > 0 && src_n > 0) {
+		if (min < dest_n)
+			((char *)dest)[min - 1] = '\0';
+		else
+			((char *)dest)[dest_n - 1] = '\0';
+	}
+	
+	return dest;
+}
+
+/*
  * Send a plain bootp request packet with options
  */
 int bootp_send_request(struct netdev *dev)
@@ -110,22 +129,13 @@ int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,
 					       len >= 8 ? 8 : 4);
 				break;
 			case 12:	/* host name */
-				if (len > sizeof(dev->hostname) - 1)
-					len = sizeof(dev->hostname) - 1;
-				memcpy(&dev->hostname, ext, len);
-				dev->hostname[len] = '\0';
+				memncpy(&dev->hostname, ext, sizeof(dev->hostname), len);
 				break;
 			case 15:	/* domain name */
-				if (len > sizeof(dev->dnsdomainname) - 1)
-					len = sizeof(dev->dnsdomainname) - 1;
-				memcpy(&dev->dnsdomainname, ext, len);
-				dev->dnsdomainname[len] = '\0';
+				memncpy(&dev->dnsdomainname, ext, sizeof(dev->dnsdomainname), len);
 				break;
 			case 17:	/* root path */
-				if (len > sizeof(dev->bootpath) - 1)
-					len = sizeof(dev->bootpath) - 1;
-				memcpy(&dev->bootpath, ext, len);
-				dev->bootpath[len] = '\0';
+				memncpy(&dev->bootpath, ext, sizeof(dev->bootpath), len);
 				break;
 			case 26:	/* interface MTU */
 				if (len == 2)
@@ -136,10 +146,7 @@ int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,
 					memcpy(&dev->ip_broadcast, ext, 4);
 				break;
 			case 40:	/* NIS domain name */
-				if (len > sizeof(dev->nisdomainname) - 1)
-					len = sizeof(dev->nisdomainname) - 1;
-				memcpy(&dev->nisdomainname, ext, len);
-				dev->nisdomainname[len] = '\0';
+				memncpy(&dev->nisdomainname, ext, sizeof(dev->nisdomainname), len);
 				break;
 			case 53:	/* DHCP message type */
 				type = *ext;
@@ -149,10 +156,7 @@ int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,
 					memcpy(&dev->ip_server, ext, 4);
 				break;
 			case 67:	/* bootfile name, when option overload is set */
-				if (len > sizeof(dev->filename) - 1)
-					len = sizeof(dev->filename) - 1;
-				memcpy(&dev->filename, ext, len);
-				dev->filename[len] = '\0';
+				memncpy(&dev->filename, ext, sizeof(dev->filename), len);
 				break;
 			}
 


More information about the klibc mailing list