aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-01-25 10:06:12 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2024-01-25 10:06:12 -0500
commit6426d466779fa889bca170e3ff80dbfc6ea8c2e8 (patch)
tree8485d8299a610e4982e91507701e574718f48a28
parent4ffcceef8137b7151ad1e779e38e4b6a3bdcaea8 (diff)
downloadgcc-6426d466779fa889bca170e3ff80dbfc6ea8c2e8.zip
gcc-6426d466779fa889bca170e3ff80dbfc6ea8c2e8.tar.gz
gcc-6426d466779fa889bca170e3ff80dbfc6ea8c2e8.tar.bz2
analyzer: fix defaults in compound assignments from non-zero offsets [PR112969]
Confusion in binding_cluster::maybe_get_compound_binding about whether offsets are relative to the start of the region or to the start of the cluster was leading to incorrect handling of default values, leading to false positives from -Wanalyzer-use-of-uninitialized-value, from -Wanalyzer-exposure-through-uninit-copy, and other logic errors. Fixed thusly. gcc/analyzer/ChangeLog: PR analyzer/112969 * store.cc (binding_cluster::maybe_get_compound_binding): When populating default_map, express the bit-range of the default key for REG relative to REG, rather than to the base region. gcc/testsuite/ChangeLog: PR analyzer/112969 * c-c++-common/analyzer/compound-assignment-5.c (test_3): Remove xfails, reorder tests. * c-c++-common/analyzer/compound-assignment-pr112969.c: New test. * gcc.dg/plugin/infoleak-pr112969.c: New test. * gcc.dg/plugin/plugin.exp: Add infoleak-pr112969.c to analyzer_kernel_plugin.c tests. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r--gcc/analyzer/store.cc11
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c3
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/compound-assignment-pr112969.c35
-rw-r--r--gcc/testsuite/gcc.dg/plugin/infoleak-pr112969.c52
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp1
5 files changed, 99 insertions, 3 deletions
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 67c90b7..e85a196 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -1759,7 +1759,16 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr,
else
default_sval = sval_mgr->get_or_create_initial_value (reg);
const binding_key *default_key = binding_key::make (mgr, reg);
- default_map.put (default_key, default_sval);
+
+ /* Express the bit-range of the default key for REG relative to REG,
+ rather than to the base region. */
+ const concrete_binding *concrete_default_key
+ = default_key->dyn_cast_concrete_binding ();
+ if (!concrete_default_key)
+ return nullptr;
+ const concrete_binding *default_key_relative_to_reg
+ = mgr->get_concrete_binding (0, concrete_default_key->get_size_in_bits ());
+ default_map.put (default_key_relative_to_reg, default_sval);
for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter)
{
diff --git a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c
index 3ce2b72..08f1060 100644
--- a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c
+++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c
@@ -48,9 +48,8 @@ void test_3 (void)
glob_arr3[7] = arr[3]; // or should the uninit warning be here?
- __analyzer_eval (glob_arr3[7].x); /* { dg-warning "uninitialized" "uninit" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
__analyzer_eval (glob_arr3[7].y == 6); /* { dg-warning "TRUE" } */
+ __analyzer_eval (glob_arr3[7].x); /* { dg-warning "uninitialized" "uninit" } */
}
/* Symbolic bindings: copying from one array to another. */
diff --git a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-pr112969.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-pr112969.c
new file mode 100644
index 0000000..4bc037c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-pr112969.c
@@ -0,0 +1,35 @@
+/* Reduced from -Wanalyzer-exposure-through-uninit-copy false positives
+ seen in Linux kernel in drivers/net/ethernet/intel/ice/ice_ptp.c */
+
+#include "analyzer-decls.h"
+
+/* { dg-do compile } */
+
+struct hwtstamp_config
+{
+ int flags;
+ int tx_type;
+ int rx_filter;
+};
+
+struct ice_ptp
+{
+ long placeholder;
+ struct hwtstamp_config tstamp_config;
+};
+
+struct ice_pf
+{
+ struct ice_ptp ptp;
+};
+
+void
+ice_ptp_set_ts_config(struct ice_pf* pf)
+{
+ struct hwtstamp_config config;
+ pf->ptp.tstamp_config.tx_type = 1;
+ pf->ptp.tstamp_config.rx_filter = 2;
+ config = pf->ptp.tstamp_config;
+ __analyzer_eval (config.flags == pf->ptp.tstamp_config.flags); /* { dg-warning "TRUE" } */
+ /* { dg-bogus "use of uninitialized value 'config.flags'" "PR analyzer/112969" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/infoleak-pr112969.c b/gcc/testsuite/gcc.dg/plugin/infoleak-pr112969.c
new file mode 100644
index 0000000..e78fe36
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/infoleak-pr112969.c
@@ -0,0 +1,52 @@
+/* Reduced from -Wanalyzer-exposure-through-uninit-copy false positives
+ seen in Linux kernel in drivers/net/ethernet/intel/ice/ice_ptp.c */
+
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer" } */
+/* { dg-require-effective-target analyzer } */
+
+extern unsigned long
+copy_from_user(void* to, const void* from, unsigned long n);
+
+extern unsigned long
+copy_to_user(void* to, const void* from, unsigned long n);
+
+struct ifreq
+{
+ union
+ {
+ void* ifru_data;
+ } ifr_ifru;
+};
+
+struct hwtstamp_config
+{
+ int flags;
+ int tx_type;
+ int rx_filter;
+};
+
+struct ice_ptp
+{
+ long placeholder;
+ struct hwtstamp_config tstamp_config;
+};
+
+struct ice_pf
+{
+ struct ice_ptp ptp;
+};
+int
+ice_ptp_set_ts_config(struct ice_pf* pf, struct ifreq* ifr)
+{
+ struct hwtstamp_config config;
+ int err;
+ if (copy_from_user(&config, ifr->ifr_ifru.ifru_data, sizeof(config)))
+ return -14;
+ pf->ptp.tstamp_config.tx_type = 0;
+ pf->ptp.tstamp_config.rx_filter = 0;
+ config = pf->ptp.tstamp_config;
+ if (copy_to_user(ifr->ifr_ifru.ifru_data, &config, sizeof(config))) /* { dg-bogus "-Wanalyzer-exposure-through-uninit-copy" "PR analyzer/112969" } */
+ return -14;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 8141cc2..c26dda1 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -150,6 +150,7 @@ set plugin_test_list [list \
infoleak-CVE-2017-18550-1.c \
infoleak-antipatterns-1.c \
infoleak-fixit-1.c \
+ infoleak-pr112969.c \
infoleak-uninit-size-1.c \
infoleak-uninit-size-2.c \
infoleak-net-ethtool-ioctl.c \