Hi, I'm working on a j1939 socket type (not sure our managament will allow us to open source it, we're working on that too). During that development, we added an extra entry in struct sockaddr_can.can_addr. ----
Our extension does increase the size of struct sockaddr_can This patch solves a problem that 'regular' socket types do require the full struct sockaddr_can be present, while using only the first few fields. It does so by not testing on sizeof() but using a newly introduced macro 'partial_struct_size', which returns the size of the struct up to the requested struct member. When socketcan is compiled with bigger struct sockaddr_can, It will not pose any problems with userspace binaries that got compiled with older revisions of struct sockaddr_can. Please not that the 'partial_struct_size' macro can only work when the struct in only added to, not modified, which is the case here. Signed-off-by: Kurt Van Dijck <[email protected]> --- Index: include/socketcan/can/core.h =================================================================== --- include/socketcan/can/core.h (revision 1123) +++ include/socketcan/can/core.h (working copy) @@ -52,6 +52,15 @@ #endif }; + +/* + * partial_struct_size + * macro to find the size of a struct up to a requested member (inclusive) + */ +#define partial_struct_size(member, type) \ + (offsetof(typeof(type), member) + \ + sizeof(((typeof(type) *)(0))->member)) + /* function prototypes for the CAN networklayer core (af_can.c) */ extern int can_proto_register(struct can_proto *cp); Index: net/can/isotp.c =================================================================== --- net/can/isotp.c (revision 1123) +++ net/can/isotp.c (working copy) @@ -826,7 +826,7 @@ int err = 0; int notify_enetdown = 0; - if (len < sizeof(*addr)) + if (len < partial_struct_size(can_addr.tp, *addr)) return -EINVAL; if (addr->can_addr.tp.rx_id == addr->can_addr.tp.tx_id) Index: net/can/bcm.c =================================================================== --- net/can/bcm.c (revision 1123) +++ net/can/bcm.c (working copy) @@ -1610,6 +1610,9 @@ if (bo->bound) return -EISCONN; + if (len < partial_struct_size(can_ifindex, *addr)) + return -EINVAL; + /* bind a device to this socket */ if (addr->can_ifindex) { struct net_device *dev; Index: net/can/raw.c =================================================================== --- net/can/raw.c (revision 1123) +++ net/can/raw.c (working copy) @@ -354,7 +354,7 @@ int err = 0; int notify_enetdown = 0; - if (len < sizeof(*addr)) + if (len < partial_struct_size(can_ifindex, *addr)) return -EINVAL; lock_sock(sk); Index: net/can/bcm-prior-2-6-22.c =================================================================== --- net/can/bcm-prior-2-6-22.c (revision 1123) +++ net/can/bcm-prior-2-6-22.c (working copy) @@ -1475,6 +1475,9 @@ if (bo->bound) return -EISCONN; + if (len < partial_struct_size(can_ifindex, *addr)) + return -EINVAL; + /* bind a device to this socket */ if (addr->can_ifindex) { struct net_device *dev; _______________________________________________ Socketcan-core mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-core
