Ted Unangst wrote [2011-11-14 22:35+0100]:
> On Mon, Nov 14, 2011, Steffen Daode Nurpmeso wrote:
> > Is there a reason not to use CTASSERT (and some kind of
> > member_sizeof())?  I couldn't find just any discussion on that in
> > marc and gmane.
> 
> Seems like a good idea, but your patch is wrong.
> Off by one because strlen != sizeof.

The patch adds a fantastic member_sizeof() which is unique in the
world!  Even though needed so often, neither was it invented by
IBM (TM,REG), nor has Coca-Cola (TM,REG) a trademark on it!
It was me, many years ago! (AFAIK)
Hah!! (AFAIK)
Feel free to use it!!!

--steffen

Index: sys/sys/cdefs.h
===================================================================
RCS file: /cvs/src/sys/sys/cdefs.h,v
retrieving revision 1.31
diff -a -p -u -r1.31 cdefs.h
--- sys/sys/cdefs.h     1 Oct 2010 04:51:49 -0000       1.31
+++ sys/sys/cdefs.h     15 Nov 2011 19:50:34 -0000
@@ -86,6 +86,18 @@
 #define        __CONCAT(x,y)   x/**/y
 #define        __STRING(x)     "x"
 
+/*
+ * Compile time assertion
+ */
+#define __CTASSERT(X)          __CTASSERT1((X), __LINE__)
+#define __CTASSERT1(X,L)       __CTASSERT2((X), L)
+#define __CTASSERT2(X,L)       typedef char __CTASSERT_bail_ ## L[(X) ? 1 : -1]
+
+/*
+ * __member_sizeof(T,M) - uses 0x8 to avoid cc warnings and aggr. optimization
+ */
+#define __member_sizeof(T,M)   sizeof(((T *)0x8)->M)
+
 #if !defined(__GNUC__) && !defined(lint)
 #define        __const                         /* delete pseudo-ANSI C 
keywords */
 #define        __inline
Index: sbin/dhclient/dhclient.c
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
retrieving revision 1.141
diff -a -p -u -r1.141 dhclient.c
--- sbin/dhclient/dhclient.c    11 May 2011 14:38:36 -0000      1.141
+++ sbin/dhclient/dhclient.c    15 Nov 2011 19:50:34 -0000
@@ -2077,6 +2077,9 @@ get_ifname(char *ifname, char *arg)
        struct ifg_req *ifg;
        int s, len;
 
+       __CTASSERT(__member_sizeof(struct interface_info, name) >=
+                  __member_sizeof(struct ifg_req, ifgrq_member));
+
        if (!strcmp(arg, "egress")) {
                s = socket(AF_INET, SOCK_DGRAM, 0);
                if (s == -1)
@@ -2103,8 +2106,8 @@ get_ifname(char *ifname, char *arg)
                        arg = ifg->ifgrq_member;
                }
 
-               if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ)
-                       error("Interface name too long: %m");
+               (void)strlcpy(ifi->name, arg,
+                             __member_sizeof(struct ifg_req, ifgrq_member));
 
                free(ifgr.ifgr_groups);
                close(s);

Reply via email to