summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2021-02-17 12:29:27 +0100
committerAndreas Schneider <asn@samba.org>2021-03-15 08:04:58 +0100
commitba970e5d32cceb0750eaa71fb83da3e2eef881d5 (patch)
tree6c7b485096014361c8dff27ca42cd1626ed53621
parentefd2967e060a3a7ca3de589a23511bb38151ed8b (diff)
downloadsocket_wrapper-ba970e5d32cceb0750eaa71fb83da3e2eef881d5.tar.gz
socket_wrapper-ba970e5d32cceb0750eaa71fb83da3e2eef881d5.tar.xz
socket_wrapper-ba970e5d32cceb0750eaa71fb83da3e2eef881d5.zip
swrap: export a public socket_wrapper_indicate_no_inet_fd() helper function
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14640 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r--doc/socket_wrapper.169
-rw-r--r--doc/socket_wrapper.1.adoc25
-rw-r--r--src/socket_wrapper.c22
-rw-r--r--src/socket_wrapper.h25
-rw-r--r--src/socket_wrapper_noop.c6
-rw-r--r--tests/test_public_functions.c31
6 files changed, 178 insertions, 0 deletions
diff --git a/doc/socket_wrapper.1 b/doc/socket_wrapper.1
index b6363cd..c988227 100644
--- a/doc/socket_wrapper.1
+++ b/doc/socket_wrapper.1
@@ -281,6 +281,75 @@ bool socket_wrapper_enabled(void);
.\}
This returns true when socket wrapper is actively in use.
.RE
+.sp
+void socket_wrapper_indicate_no_inet_fd(int fd);
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+This allows socket_wrapper aware applications to
+indicate that the given fd does not belong to
+an inet socket.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+socket_wrapper may not be able to intercept the __close_nocancel()
+syscall made from within libc.so. As result it\(cqs possible
+that the in memory meta date of socket_wrapper references
+stale file descriptors, which are already reused for unrelated
+kernel objects, e.g. files, directories, ...
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+Socket wrapper already intercepts a lot of unrelated
+functions like eventfd(), timerfd_create(), ... in order
+to remove stale meta data for the returned fd, but
+it will never be able to handle all possible syscalls.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+socket_wrapper_indicate_no_inet_fd() gives applications a way
+to do the same, explicitly without waiting for new syscalls to
+be added to libsocket_wrapper.so.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+This is a no\-op if socket_wrapper is not in use or
+if the there is no in memory meta data for the given fd.
+.RE
.SH "RESOURCES"
.sp
\fBProject web site:\fP \c
diff --git a/doc/socket_wrapper.1.adoc b/doc/socket_wrapper.1.adoc
index fd0b745..39c46ee 100644
--- a/doc/socket_wrapper.1.adoc
+++ b/doc/socket_wrapper.1.adoc
@@ -156,6 +156,31 @@ bool socket_wrapper_enabled(void);
- This returns true when socket wrapper is actively in use.
+void socket_wrapper_indicate_no_inet_fd(int fd);
+
+- This allows socket_wrapper aware applications to
+ indicate that the given fd does not belong to
+ an inet socket.
+
+- socket_wrapper may not be able to intercept the __close_nocancel()
+ syscall made from within libc.so. As result it's possible
+ that the in memory meta date of socket_wrapper references
+ stale file descriptors, which are already reused for unrelated
+ kernel objects, e.g. files, directories, ...
+
+- Socket wrapper already intercepts a lot of unrelated
+ functions like eventfd(), timerfd_create(), ... in order
+ to remove stale meta data for the returned fd, but
+ it will never be able to handle all possible syscalls.
+
+- socket_wrapper_indicate_no_inet_fd() gives applications a way
+ to do the same, explicitly without waiting for new syscalls to
+ be added to libsocket_wrapper.so.
+
+- This is a no-op if socket_wrapper is not in use or
+ if the there is no in memory meta data for the given fd.
+
+
RESOURCES
---------
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 63de148..714cd25 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -7456,6 +7456,28 @@ static void swrap_remove_stale(int fd)
swrap_remove_wrapper(__func__, swrap_noop_close, fd);
}
+/*
+ * This allows socket_wrapper aware applications to
+ * indicate that the given fd does not belong to
+ * an inet socket.
+ *
+ * We already overload a lot of unrelated functions
+ * like eventfd(), timerfd_create(), ... in order to
+ * call swrap_remove_stale() on the returned fd, but
+ * we'll never be able to handle all possible syscalls.
+ *
+ * socket_wrapper_indicate_no_inet_fd() gives them a way
+ * to do the same.
+ *
+ * We don't export swrap_remove_stale() in order to
+ * make it easier to analyze SOCKET_WRAPPER_DEBUGLEVEL=3
+ * log files.
+ */
+void socket_wrapper_indicate_no_inet_fd(int fd)
+{
+ swrap_remove_wrapper(__func__, swrap_noop_close, fd);
+}
+
static int swrap_close(int fd)
{
return swrap_remove_wrapper(__func__, libc_close, fd);
diff --git a/src/socket_wrapper.h b/src/socket_wrapper.h
index f1a97e8..3ec5031 100644
--- a/src/socket_wrapper.h
+++ b/src/socket_wrapper.h
@@ -61,4 +61,29 @@
*/
bool socket_wrapper_enabled(void);
+/*
+ * This allows socket_wrapper aware applications to
+ * indicate that the given fd does not belong to
+ * an inet socket.
+ *
+ * socket_wrapper may not be able to intercept the __close_nocancel()
+ * syscall made from within libc.so. As result it's possible
+ * that the in memory meta date of socket_wrapper references
+ * stale file descriptors, which are already reused for unrelated
+ * kernel objects, e.g. files, directories, ...
+ *
+ * Socket wrapper already intercepts a lot of unrelated
+ * functions like eventfd(), timerfd_create(), ... in order
+ * to remove stale meta data for the returned fd, but
+ * it will never be able to handle all possible syscalls.
+ *
+ * socket_wrapper_indicate_no_inet_fd() gives applications a way
+ * to do the same, explicitly without waiting for new syscalls to
+ * be added to libsocket_wrapper.so.
+ *
+ * This is a no-op if socket_wrapper is not in use or
+ * if the there is no in memory meta data for the given fd.
+ */
+void socket_wrapper_indicate_no_inet_fd(int fd);
+
#endif /* __SOCKET_WRAPPER_H__ */
diff --git a/src/socket_wrapper_noop.c b/src/socket_wrapper_noop.c
index 45aff8f..aadf350 100644
--- a/src/socket_wrapper_noop.c
+++ b/src/socket_wrapper_noop.c
@@ -55,3 +55,9 @@ bool socket_wrapper_enabled(void)
{
return false;
}
+
+void socket_wrapper_indicate_no_inet_fd(int fd)
+{
+ (void) fd; /* unused */
+ return;
+}
diff --git a/tests/test_public_functions.c b/tests/test_public_functions.c
index 11d03ef..816cd7d 100644
--- a/tests/test_public_functions.c
+++ b/tests/test_public_functions.c
@@ -60,6 +60,31 @@ static void test_call_enabled_false(void **state)
assert_false(s != NULL);
}
+static void test_call_indicate_no_inet_fd(void **state)
+{
+ int rc;
+ int s = -1;
+
+ (void) state; /* unused */
+
+ socket_wrapper_indicate_no_inet_fd(987654321);
+ socket_wrapper_indicate_no_inet_fd(-1);
+
+ rc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (rc >= 0) {
+ s = rc;
+ rc = 0;
+ }
+ assert_return_code(rc, errno);
+
+ socket_wrapper_indicate_no_inet_fd(987654321);
+ socket_wrapper_indicate_no_inet_fd(-1);
+ socket_wrapper_indicate_no_inet_fd(s);
+ socket_wrapper_indicate_no_inet_fd(0);
+ socket_wrapper_indicate_no_inet_fd(1);
+ socket_wrapper_indicate_no_inet_fd(2);
+}
+
int main(void) {
int rc;
@@ -70,6 +95,12 @@ int main(void) {
cmocka_unit_test_setup_teardown(test_call_enabled_false,
setup_disabled,
teardown_disabled),
+ cmocka_unit_test_setup_teardown(test_call_indicate_no_inet_fd,
+ setup_enabled,
+ teardown_enabled),
+ cmocka_unit_test_setup_teardown(test_call_indicate_no_inet_fd,
+ setup_disabled,
+ teardown_disabled),
};
rc = cmocka_run_group_tests(max_sockets_tests, NULL, NULL);