かなりの多い memset バグ2007年11月20日 13時33分14秒

随分、昔に freebsd-hackers に memset bugs を修正したとの報告があった。半年、近く経ってから読んだ。


--- src/sys/netinet/sctp_output.c~	2007-08-14 15:44:11.000000000 -0400
+++ src/sys/netinet/sctp_output.c	2007-08-14 15:44:27.000000000 -0400
@@ -6331,7 +6331,7 @@ out_gu:
 		rcv_flags |= SCTP_DATA_UNORDERED;
 	}
 	/* clear out the chunk before setting up */
-	memset(chk, sizeof(*chk), 0);
+	memset(chk, 0, sizeof(*chk));
 	chk->rec.data.rcv_flags = rcv_flags;
 	if (SCTP_BUF_IS_EXTENDED(sp->data)) {
 		chk->copy_by_ref = 1;
--- src/usr.sbin/nscd/agents/services.c~	2007-08-14 15:44:33.000000000 -0400
+++ src/usr.sbin/nscd/agents/services.c	2007-08-14 15:44:41.000000000 -0400
@@ -171,7 +171,7 @@ services_lookup_func(const char *key, si
 		if (size > 0) {
 			proto = (char *)malloc(size + 1);
 			assert(proto != NULL);
-			memset(proto, size + 1, 0);
+			memset(proto, 0, size + 1);
 			memcpy(proto, key + sizeof(enum nss_lookup_type) +
 				sizeof(int), size);
 		}
--- src/usr.sbin/cached/agents/services.c~	2007-08-14 15:44:45.000000000 -0400
+++ src/usr.sbin/cached/agents/services.c	2007-08-14 15:44:52.000000000 -0400
@@ -171,7 +171,7 @@ services_lookup_func(const char *key, si
 		if (size > 0) {
 			proto = (char *)malloc(size + 1);
 			assert(proto != NULL);
-			memset(proto, size + 1, 0);
+			memset(proto, 0, size + 1);
 			memcpy(proto, key + sizeof(enum nss_lookup_type) +
 				sizeof(int), size);
 		}
--- src/contrib/gdb/gdb/std-regs.c~	2007-08-14 15:44:56.000000000 -0400
+++ src/contrib/gdb/gdb/std-regs.c	2007-08-14 15:45:22.000000000 -0400
@@ -61,7 +61,7 @@ value_of_builtin_frame_reg (struct frame
   val = allocate_value (builtin_type_frame_reg);
   VALUE_LVAL (val) = not_lval;
   buf = VALUE_CONTENTS_RAW (val);
-  memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+  memset (buf, 0, TYPE_LENGTH (VALUE_TYPE (val)));
   /* frame.base.  */
   if (frame != NULL)
     ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf,
@@ -87,7 +87,7 @@ value_of_builtin_frame_fp_reg (struct fr
       struct value *val = allocate_value (builtin_type_void_data_ptr);
       char *buf = VALUE_CONTENTS_RAW (val);
       if (frame == NULL)
-	memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+	memset (buf, 0, TYPE_LENGTH (VALUE_TYPE (val)));
       else
 	ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf,
 			    get_frame_base_address (frame));
@@ -105,7 +105,7 @@ value_of_builtin_frame_pc_reg (struct fr
       struct value *val = allocate_value (builtin_type_void_data_ptr);
       char *buf = VALUE_CONTENTS_RAW (val);
       if (frame == NULL)
-	memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+	memset (buf, 0, TYPE_LENGTH (VALUE_TYPE (val)));
       else
 	ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf,
 			    get_frame_pc (frame));
--- src/contrib/gdb/gdb/remote.c~	2007-08-14 15:45:25.000000000 -0400
+++ src/contrib/gdb/gdb/remote.c	2007-08-14 15:45:37.000000000 -0400
@@ -3463,7 +3463,7 @@ remote_store_registers (int regnum)
   {
     int i;
     regs = alloca (rs->sizeof_g_packet);
-    memset (regs, rs->sizeof_g_packet, 0);
+    memset (regs, 0, rs->sizeof_g_packet);
     for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
       {
 	struct packet_reg *r = &rs->regs[i];

-- 

これを見ると、gdb のバグも二つも入っている。結構、ありがちなのかもしれない。今一度、点検した方が良さそうだ。