@@ -39,7 +39,33 @@ private Type getElementType(Type containerType) {
3939 result = containerType .( SliceType ) .getElementType ( ) or
4040 result = containerType .( ChanType ) .getElementType ( ) or
4141 result = containerType .( MapType ) .getValueType ( ) or
42- result = containerType .( PointerType ) .getPointerType ( )
42+ result = containerType .( PointerType ) .getPointerType ( ) or
43+ result = containerType .( NamedType ) .getUnderlyingType ( )
44+ }
45+
46+ private Type getElementTypeIncludingFields ( Type containerType ) {
47+ result = getElementType ( containerType ) or
48+ result = containerType .( StructType ) .getField ( _) .getType ( )
49+ }
50+
51+ private DataFlow:: ContentSet getContentForType ( Type containerType ) {
52+ containerType instanceof ArrayType and
53+ result instanceof DataFlow:: ArrayContent
54+ or
55+ containerType instanceof SliceType and
56+ result instanceof DataFlow:: ArrayContent
57+ or
58+ containerType instanceof ChanType and
59+ result instanceof DataFlow:: CollectionContent
60+ or
61+ containerType instanceof MapType and
62+ result instanceof DataFlow:: MapValueContent
63+ or
64+ result .( DataFlow:: PointerContent ) .getPointerType ( ) = containerType
65+ or
66+ exists ( Field f | f = containerType .( StructType ) .getField ( _) |
67+ result .( DataFlow:: FieldContent ) .getField ( ) = f
68+ )
4369}
4470
4571/**
@@ -51,23 +77,41 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c)
5177 exists ( Type containerType |
5278 node instanceof DataFlow:: ArgumentNode and
5379 getElementType * ( node .getType ( ) ) = containerType
54- |
55- containerType instanceof ArrayType and
56- c instanceof DataFlow:: ArrayContent
57- or
58- containerType instanceof SliceType and
59- c instanceof DataFlow:: ArrayContent
6080 or
61- containerType instanceof ChanType and
62- c instanceof DataFlow:: CollectionContent
63- or
64- containerType instanceof MapType and
65- c instanceof DataFlow:: MapValueContent
66- or
67- c .( DataFlow:: PointerContent ) .getPointerType ( ) = containerType
81+ any ( ImplicitFieldReadNode ifrn ) .shouldImplicitlyReadAllFields ( node ) and
82+ getElementTypeIncludingFields * ( node .getType ( ) ) = containerType
83+ |
84+ c = getContentForType ( containerType )
6885 )
6986}
7087
88+ /**
89+ * Holds if default `TaintTracking::Configuration`s should allow implicit reads
90+ * of `c` at `node` in any context.
91+ */
92+ bindingset [ node]
93+ predicate defaultImplicitTaintReadGlobal ( DataFlow:: Node node , DataFlow:: ContentSet c ) {
94+ exists ( Type containerType |
95+ any ( ImplicitFieldReadNode ifrn ) .shouldImplicitlyReadAllFields ( node ) and
96+ getElementTypeIncludingFields * ( node .getType ( ) ) = containerType
97+ |
98+ c = getContentForType ( containerType )
99+ )
100+ }
101+
102+ /**
103+ * A unit class for adding nodes that should implicitly read from all nested content
104+ * in a taint-tracking context.
105+ *
106+ * For example, this might be appopriate for the argument to a method that serializes a struct.
107+ */
108+ class ImplicitFieldReadNode extends Unit {
109+ /**
110+ * Holds if the node `n` should implicitly read from all nested content in a taint-tracking context.
111+ */
112+ abstract predicate shouldImplicitlyReadAllFields ( DataFlow:: Node n ) ;
113+ }
114+
71115/**
72116 * A unit class for adding additional taint steps.
73117 *
0 commit comments