public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-4424] analyzer: fix ICE on bind/connect with a constant fd [PR107928]
@ 2022-12-01 2:31 David Malcolm
0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2022-12-01 2:31 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:45a75fd3d31265e43aa3ce7a5e851083d534b00b
commit r13-4424-g45a75fd3d31265e43aa3ce7a5e851083d534b00b
Author: David Malcolm <dmalcolm@redhat.com>
Date: Wed Nov 30 21:26:41 2022 -0500
analyzer: fix ICE on bind/connect with a constant fd [PR107928]
gcc/analyzer/ChangeLog:
PR analyzer/107928
* sm-fd.cc (fd_state_machine::on_bind): Handle m_constant_fd in
the "success" outcome.
(fd_state_machine::on_connect): Likewise.
* sm-fd.dot: Add "constant_fd" state and its transitions.
gcc/testsuite/ChangeLog:
PR analyzer/107928
* gcc.dg/analyzer/fd-bind-pr107928.c: New test.
* gcc.dg/analyzer/fd-connect-pr107928.c: New test.
* gcc.dg/analyzer/fd-stream-socket-active-open.c
(test_active_open_from_connect_constant): New, adapted from
test_active_open_from_connect.
* gcc.dg/analyzer/fd-stream-socket-passive-open.c
(test_passive_open_from_bind_constant): New, adapted from
test_passive_open_from_bind.
(test_passive_open_from_listen_constant): New, adapted from
test_passive_open_from_listen.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diff:
---
gcc/analyzer/sm-fd.cc | 6 +-
gcc/analyzer/sm-fd.dot | 6 ++
gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c | 10 +++
.../gcc.dg/analyzer/fd-connect-pr107928.c | 10 +++
.../gcc.dg/analyzer/fd-stream-socket-active-open.c | 31 +++++++
.../analyzer/fd-stream-socket-passive-open.c | 98 ++++++++++++++++++++++
6 files changed, 159 insertions(+), 2 deletions(-)
diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index 794733e55ca..799847cb8e8 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -1861,7 +1861,8 @@ fd_state_machine::on_bind (const call_details &cd,
next_state = m_bound_datagram_socket;
else if (old_state == m_new_unknown_socket)
next_state = m_bound_unknown_socket;
- else if (old_state == m_start)
+ else if (old_state == m_start
+ || old_state == m_constant_fd)
next_state = m_bound_unknown_socket;
else if (old_state == m_stop)
next_state = m_stop;
@@ -2116,7 +2117,8 @@ fd_state_machine::on_connect (const call_details &cd,
next_state = m_new_datagram_socket;
else if (old_state == m_new_unknown_socket)
next_state = m_stop;
- else if (old_state == m_start)
+ else if (old_state == m_start
+ || old_state == m_constant_fd)
next_state = m_stop;
else if (old_state == m_stop)
next_state = m_stop;
diff --git a/gcc/analyzer/sm-fd.dot b/gcc/analyzer/sm-fd.dot
index da925b0989f..d7676b1f779 100644
--- a/gcc/analyzer/sm-fd.dot
+++ b/gcc/analyzer/sm-fd.dot
@@ -27,6 +27,9 @@ digraph "fd" {
/* Start state. */
start;
+ /* State for a constant file descriptor (>= 0). */
+ constant_fd;
+
/* States representing a file descriptor that hasn't yet been
checked for validity after opening, for three different
access modes. */
@@ -129,6 +132,7 @@ digraph "fd" {
/* On "bind". */
start -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
+ constant_fd -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
new_stream_socket -> bound_stream_socket [label="when 'bind(X, ...)' succeeds"];
new_datagram_socket -> bound_datagram_socket [label="when 'bind(X, ...)' succeeds"];
new_unknown_socket -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
@@ -140,12 +144,14 @@ digraph "fd" {
/* On "accept". */
start -> connected_stream_socket [label="when 'accept(OTHER, ...)' succeeds on a listening_stream_socket"];
+ constant_fd -> connected_stream_socket [label="when 'accept(OTHER, ...)' succeeds on a listening_stream_socket"];
/* On "connect". */
new_stream_socket -> connected_stream_socket [label="when 'connect(X, ...)' succeeds"];
new_datagram_socket -> new_datagram_socket [label="when 'connect(X, ...)' succeeds"];
new_unknown_socket -> stop [label="when 'connect(X, ...)' succeeds"];
start -> stop [label="when 'connect(X, ...)' succeeds"];
+ constant_fd -> stop [label="when 'connect(X, ...)' succeeds"];
/* on_condition. */
unchecked_read_write -> valid_read_write [label="on 'X >= 0'"];
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c b/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c
new file mode 100644
index 00000000000..acc1a1df8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-bind-pr107928.c
@@ -0,0 +1,10 @@
+struct sa {};
+
+int
+bind (int, struct sa *, int);
+
+int
+foo (struct sa sa)
+{
+ return bind (1, &sa, sizeof sa);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-connect-pr107928.c b/gcc/testsuite/gcc.dg/analyzer/fd-connect-pr107928.c
new file mode 100644
index 00000000000..f3bdc87c210
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-connect-pr107928.c
@@ -0,0 +1,10 @@
+struct sa {};
+
+int
+connect (int, struct sa *, int);
+
+int
+foo (struct sa sa)
+{
+ return connect (1, &sa, sizeof sa);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c
index 841894cc1bd..89ea82e59c9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-active-open.c
@@ -74,3 +74,34 @@ void test_active_open_from_connect (int fd, const char *sockname, void *buf)
close (fd);
__analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-stop'" } */
}
+
+void test_active_open_from_connect_constant (const char *sockname, void *buf)
+{
+ const int fd = 42;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+
+ struct sockaddr_un addr;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+
+ errno = 0;
+ if (connect (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-stop'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+
+ write (fd, "hello", 6);
+ read (fd, buf, 100);
+
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-stop'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c
index a61091101ed..8af52904d7e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-stream-socket-passive-open.c
@@ -129,6 +129,62 @@ void test_passive_open_from_bind (int fd, const char *sockname, void *buf)
__analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
}
+void test_passive_open_from_bind_constant (const char *sockname, void *buf)
+{
+ const int fd = 42;
+ struct sockaddr_un addr;
+ int afd;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
+ errno = 0;
+ if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-unknown-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ if (listen (fd, 5) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-bound-unknown-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
void test_passive_open_from_listen (int fd, void *buf)
{
int afd;
@@ -169,6 +225,48 @@ void test_passive_open_from_listen (int fd, void *buf)
__analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
}
+
+void test_passive_open_from_listen_constant (void *buf)
+{
+ const int fd = 42;
+ int afd;
+ errno = 0;
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ if (listen (fd, 5) == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-constant'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ afd = accept (fd, NULL, NULL);
+ if (afd == -1)
+ {
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_eval (errno > 0); /* { dg-warning "TRUE" } */
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+ return;
+ }
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-listening-stream-socket'" } */
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-connected-stream-socket'" } */
+ __analyzer_eval (errno == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fd >= 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (afd >= 0); /* { dg-warning "TRUE" } */
+
+ write (afd, "hello", 6);
+ read (afd, buf, 100);
+
+ close (afd);
+ close (fd);
+ __analyzer_dump_state ("file-descriptor", afd); /* { dg-warning "state: 'fd-closed'" } */
+ __analyzer_dump_state ("file-descriptor", fd); /* { dg-warning "state: 'fd-closed'" } */
+}
+
void test_passive_open_from_accept (int fd, void *buf)
{
int afd;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-12-01 2:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-01 2:31 [gcc r13-4424] analyzer: fix ICE on bind/connect with a constant fd [PR107928] David Malcolm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).