0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /// If list_for_each_entry, etc complete a traversal of the list, the iterator
0003 /// variable ends up pointing to an address at an offset from the list head,
0004 /// and not a meaningful structure. Thus this value should not be used after
0005 /// the end of the iterator.
0006 //#False positives arise when there is a goto in the iterator and the
0007 //#reported reference is at the label of this goto. Some flag tests
0008 //#may also cause a report to be a false positive.
0009 ///
0010 // Confidence: Moderate
0011 // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
0012 // Copyright: (C) 2012 Gilles Muller, INRIA/LIP6.
0013 // URL: https://coccinelle.gitlabpages.inria.fr/website
0014 // Comments:
0015 // Options: --no-includes --include-headers
0016
0017 virtual context
0018 virtual org
0019 virtual report
0020
0021 @r exists@
0022 identifier c,member;
0023 expression E,x;
0024 iterator name list_for_each_entry;
0025 iterator name list_for_each_entry_reverse;
0026 iterator name list_for_each_entry_continue;
0027 iterator name list_for_each_entry_continue_reverse;
0028 iterator name list_for_each_entry_from;
0029 iterator name list_for_each_entry_safe;
0030 iterator name list_for_each_entry_safe_continue;
0031 iterator name list_for_each_entry_safe_from;
0032 iterator name list_for_each_entry_safe_reverse;
0033 iterator name hlist_for_each_entry;
0034 iterator name hlist_for_each_entry_continue;
0035 iterator name hlist_for_each_entry_from;
0036 iterator name hlist_for_each_entry_safe;
0037 statement S;
0038 position p1,p2;
0039 type T;
0040 @@
0041
0042 (
0043 list_for_each_entry@p1(c,...,member) { ... when != break;
0044 when forall
0045 when strict
0046 }
0047 |
0048 list_for_each_entry_reverse@p1(c,...,member) { ... when != break;
0049 when forall
0050 when strict
0051 }
0052 |
0053 list_for_each_entry_continue@p1(c,...,member) { ... when != break;
0054 when forall
0055 when strict
0056 }
0057 |
0058 list_for_each_entry_continue_reverse@p1(c,...,member) { ... when != break;
0059 when forall
0060 when strict
0061 }
0062 |
0063 list_for_each_entry_from@p1(c,...,member) { ... when != break;
0064 when forall
0065 when strict
0066 }
0067 |
0068 list_for_each_entry_safe@p1(c,...,member) { ... when != break;
0069 when forall
0070 when strict
0071 }
0072 |
0073 list_for_each_entry_safe_continue@p1(c,...,member) { ... when != break;
0074 when forall
0075 when strict
0076 }
0077 |
0078 list_for_each_entry_safe_from@p1(c,...,member) { ... when != break;
0079 when forall
0080 when strict
0081 }
0082 |
0083 list_for_each_entry_safe_reverse@p1(c,...,member) { ... when != break;
0084 when forall
0085 when strict
0086 }
0087 )
0088 ...
0089 (
0090 list_for_each_entry(c,...) S
0091 |
0092 list_for_each_entry_reverse(c,...) S
0093 |
0094 list_for_each_entry_continue(c,...) S
0095 |
0096 list_for_each_entry_continue_reverse(c,...) S
0097 |
0098 list_for_each_entry_from(c,...) S
0099 |
0100 list_for_each_entry_safe(c,...) S
0101 |
0102 list_for_each_entry_safe(x,c,...) S
0103 |
0104 list_for_each_entry_safe_continue(c,...) S
0105 |
0106 list_for_each_entry_safe_continue(x,c,...) S
0107 |
0108 list_for_each_entry_safe_from(c,...) S
0109 |
0110 list_for_each_entry_safe_from(x,c,...) S
0111 |
0112 list_for_each_entry_safe_reverse(c,...) S
0113 |
0114 list_for_each_entry_safe_reverse(x,c,...) S
0115 |
0116 hlist_for_each_entry(c,...) S
0117 |
0118 hlist_for_each_entry_continue(c,...) S
0119 |
0120 hlist_for_each_entry_from(c,...) S
0121 |
0122 hlist_for_each_entry_safe(c,...) S
0123 |
0124 list_remove_head(x,c,...)
0125 |
0126 list_entry_is_head(c,...)
0127 |
0128 sizeof(<+...c...+>)
0129 |
0130 &c->member
0131 |
0132 T c;
0133 |
0134 c = E
0135 |
0136 *c@p2
0137 )
0138
0139 @script:python depends on org@
0140 p1 << r.p1;
0141 p2 << r.p2;
0142 @@
0143
0144 cocci.print_main("invalid iterator index reference",p2)
0145 cocci.print_secs("iterator",p1)
0146
0147 @script:python depends on report@
0148 p1 << r.p1;
0149 p2 << r.p2;
0150 @@
0151
0152 msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line)
0153 coccilib.report.print_report(p2[0], msg)