summaryrefslogtreecommitdiffstats
path: root/include/list.h
diff options
context:
space:
mode:
authorSami Liedes2012-12-17 16:22:35 +0100
committerKarel Zak2012-12-17 16:23:35 +0100
commitbecd09500f4abe1c11edb42289f4f6b453b01c65 (patch)
tree677a06c6fb0380d563bd11225670a49e985f883c /include/list.h
parentdocs: fix typo (diff)
downloadkernel-qcow2-util-linux-becd09500f4abe1c11edb42289f4f6b453b01c65.tar.gz
kernel-qcow2-util-linux-becd09500f4abe1c11edb42289f4f6b453b01c65.tar.xz
kernel-qcow2-util-linux-becd09500f4abe1c11edb42289f4f6b453b01c65.zip
include/list: fix undefined behavior in list_entry() macro
Update list_entry() macro, which is basically the same as the container_of() macro in the kernel, to use offsetof() to fix undefined behavior. Caught using clang -fsanitize=undefined. [kzak@redhat.com: port from e2fsprogs] Signed-off-by: Sami Liedes <sami.liedes@iki.fi> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'include/list.h')
-rw-r--r--include/list.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/include/list.h b/include/list.h
index 1824af05d..414d356ba 100644
--- a/include/list.h
+++ b/include/list.h
@@ -163,8 +163,9 @@ _INLINE_ void list_splice(struct list_head *list, struct list_head *head)
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
-#define list_entry(ptr, type, member) \
- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+#define list_entry(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
#define list_first_entry(head, type, member) \