All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 0/3] Socket next patches
@ 2020-05-20 13:00 Daniel P. Berrangé
  2020-05-20 13:00 ` [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support Daniel P. Berrangé
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Daniel P. Berrangé @ 2020-05-20 13:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrangé,
	Markus Armbruster, Gerd Hoffmann, Marc-André Lureau,
	Paolo Bonzini

The following changes since commit f2465433b43fb87766d79f42191607dac4aed5b4:

  Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2020-05-19 13:42:58 +0100)

are available in the Git repository at:

  https://github.com/berrange/qemu tags/socket-next-pull-request

for you to fetch changes up to e339273bfc514824410a49837e4f16dd4e51ae8e:

  qemu-options: updates for abstract unix sockets (2020-05-20 10:34:53 +0100)

----------------------------------------------------------------
Add support for UNIX sockets in the abstract namespace

----------------------------------------------------------------

Xiaoqiang Zhao (3):
  qemu-sockets: add abstract UNIX domain socket support
  tests/util-sockets: add abstract unix socket cases
  qemu-options: updates for abstract unix sockets

 chardev/char-socket.c     |  4 ++
 chardev/char.c            |  7 +++
 qapi/sockets.json         |  8 +++-
 qemu-options.hx           |  8 +++-
 tests/test-util-sockets.c | 92 +++++++++++++++++++++++++++++++++++++++
 util/qemu-sockets.c       | 39 ++++++++++++++---
 6 files changed, 148 insertions(+), 10 deletions(-)

-- 
2.26.2




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support
  2020-05-20 13:00 [PULL 0/3] Socket next patches Daniel P. Berrangé
@ 2020-05-20 13:00 ` Daniel P. Berrangé
  2020-05-20 14:23   ` Markus Armbruster
  2020-05-20 13:00 ` [PULL 2/3] tests/util-sockets: add abstract unix socket cases Daniel P. Berrangé
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Daniel P. Berrangé @ 2020-05-20 13:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrangé,
	xiaoqiang zhao, Markus Armbruster, Gerd Hoffmann,
	Marc-André Lureau, Paolo Bonzini

From: xiaoqiang zhao <zxq_yx_007@163.com>

unix_listen/connect_saddr now support abstract address types

two aditional BOOL switches are introduced:
tight: whether to set @addrlen to the minimal string length,
       or the maximum sun_path length. default is TRUE
abstract: whether we use abstract address. default is FALSE

cli example:
-monitor unix:/tmp/unix.socket,abstract,tight=off
OR
-chardev socket,path=/tmp/unix.socket,id=unix1,abstract,tight=on

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 chardev/char-socket.c |  4 ++++
 chardev/char.c        |  7 +++++++
 qapi/sockets.json     |  8 +++++++-
 util/qemu-sockets.c   | 39 ++++++++++++++++++++++++++++++++-------
 4 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 232e0a8604..e77699db48 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1380,6 +1380,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
     const char *host = qemu_opt_get(opts, "host");
     const char *port = qemu_opt_get(opts, "port");
     const char *fd = qemu_opt_get(opts, "fd");
+    bool tight = qemu_opt_get_bool(opts, "tight", true);
+    bool abstract = qemu_opt_get_bool(opts, "abstract", false);
     SocketAddressLegacy *addr;
     ChardevSocket *sock;
 
@@ -1431,6 +1433,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
         addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
         q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
         q_unix->path = g_strdup(path);
+        q_unix->tight = tight;
+        q_unix->abstract = abstract;
     } else if (host) {
         addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
         addr->u.inet.data = g_new(InetSocketAddress, 1);
diff --git a/chardev/char.c b/chardev/char.c
index 0196e2887b..ea06c5ff4d 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -939,6 +939,13 @@ QemuOptsList qemu_chardev_opts = {
         },{
             .name = "logappend",
             .type = QEMU_OPT_BOOL,
+        },{
+            .name = "tight",
+            .type = QEMU_OPT_BOOL,
+            .def_value_str = "on",
+        },{
+            .name = "abstract",
+            .type = QEMU_OPT_BOOL,
         },
         { /* end of list */ }
     },
diff --git a/qapi/sockets.json b/qapi/sockets.json
index ea933ed4b2..cbd6ef35d0 100644
--- a/qapi/sockets.json
+++ b/qapi/sockets.json
@@ -73,12 +73,18 @@
 # Captures a socket address in the local ("Unix socket") namespace.
 #
 # @path: filesystem path to use
+# @tight: pass a socket address length confined to the minimum length of the
+#         abstract string, rather than the full sockaddr_un record length
+#         (only matters for abstract sockets, default true). (Since 5.1)
+# @abstract: whether this is an abstract address, default false. (Since 5.1)
 #
 # Since: 1.3
 ##
 { 'struct': 'UnixSocketAddress',
   'data': {
-    'path': 'str' } }
+    'path': 'str',
+    '*tight': 'bool',
+    '*abstract': 'bool' } }
 
 ##
 # @VsockSocketAddress:
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 86c48b9fa5..b37d288866 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -863,6 +863,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
     char *pathbuf = NULL;
     const char *path;
     size_t pathlen;
+    size_t addrlen;
 
     sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
     if (sock < 0) {
@@ -879,9 +880,11 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
     }
 
     pathlen = strlen(path);
-    if (pathlen > sizeof(un.sun_path)) {
+    if (pathlen > sizeof(un.sun_path) ||
+        (saddr->abstract && pathlen > (sizeof(un.sun_path) - 1))) {
         error_setg(errp, "UNIX socket path '%s' is too long", path);
         error_append_hint(errp, "Path must be less than %zu bytes\n",
+                          saddr->abstract ? sizeof(un.sun_path) - 1 :
                           sizeof(un.sun_path));
         goto err;
     }
@@ -903,7 +906,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
         close(fd);
     }
 
-    if (unlink(path) < 0 && errno != ENOENT) {
+    if (!saddr->abstract && unlink(path) < 0 && errno != ENOENT) {
         error_setg_errno(errp, errno,
                          "Failed to unlink socket %s", path);
         goto err;
@@ -911,9 +914,19 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
 
     memset(&un, 0, sizeof(un));
     un.sun_family = AF_UNIX;
-    memcpy(un.sun_path, path, pathlen);
+    addrlen = sizeof(un);
 
-    if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
+    if (saddr->abstract) {
+        un.sun_path[0] = '\0';
+        memcpy(&un.sun_path[1], path, pathlen);
+        if (saddr->tight) {
+            addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + pathlen;
+        }
+    } else {
+        memcpy(un.sun_path, path, pathlen);
+    }
+
+    if (bind(sock, (struct sockaddr *) &un, addrlen) < 0) {
         error_setg_errno(errp, errno, "Failed to bind socket to %s", path);
         goto err;
     }
@@ -936,6 +949,7 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
     struct sockaddr_un un;
     int sock, rc;
     size_t pathlen;
+    size_t addrlen;
 
     if (saddr->path == NULL) {
         error_setg(errp, "unix connect: no path specified");
@@ -949,21 +963,32 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
     }
 
     pathlen = strlen(saddr->path);
-    if (pathlen > sizeof(un.sun_path)) {
+    if (pathlen > sizeof(un.sun_path) ||
+        (saddr->abstract && pathlen > (sizeof(un.sun_path) - 1))) {
         error_setg(errp, "UNIX socket path '%s' is too long", saddr->path);
         error_append_hint(errp, "Path must be less than %zu bytes\n",
+                          saddr->abstract ? sizeof(un.sun_path) - 1 :
                           sizeof(un.sun_path));
         goto err;
     }
 
     memset(&un, 0, sizeof(un));
     un.sun_family = AF_UNIX;
-    memcpy(un.sun_path, saddr->path, pathlen);
+    addrlen = sizeof(un);
 
+    if (saddr->abstract) {
+        un.sun_path[0] = '\0';
+        memcpy(&un.sun_path[1], saddr->path, pathlen);
+        if (saddr->tight) {
+            addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + pathlen;
+        }
+    } else {
+        memcpy(un.sun_path, saddr->path, pathlen);
+    }
     /* connect to peer */
     do {
         rc = 0;
-        if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) {
+        if (connect(sock, (struct sockaddr *) &un, addrlen) < 0) {
             rc = -errno;
         }
     } while (rc == -EINTR);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PULL 2/3] tests/util-sockets: add abstract unix socket cases
  2020-05-20 13:00 [PULL 0/3] Socket next patches Daniel P. Berrangé
  2020-05-20 13:00 ` [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support Daniel P. Berrangé
@ 2020-05-20 13:00 ` Daniel P. Berrangé
  2020-05-20 13:00 ` [PULL 3/3] qemu-options: updates for abstract unix sockets Daniel P. Berrangé
  2020-05-21 18:58 ` [PULL 0/3] Socket next patches Peter Maydell
  3 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrangé @ 2020-05-20 13:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrangé,
	xiaoqiang zhao, Markus Armbruster, Gerd Hoffmann,
	Marc-André Lureau, Paolo Bonzini

From: xiaoqiang zhao <zxq_yx_007@163.com>

add cases to test tight and non-tight for abstract address type

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 tests/test-util-sockets.c | 92 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
index 5fd947c7bf..2ca1e99f17 100644
--- a/tests/test-util-sockets.c
+++ b/tests/test-util-sockets.c
@@ -227,6 +227,93 @@ static void test_socket_fd_pass_num_nocli(void)
     g_free(addr.u.fd.str);
 }
 
+#ifdef __linux__
+static gchar *abstract_sock_name;
+
+static gpointer unix_server_thread_func(gpointer user_data)
+{
+    SocketAddress addr;
+    Error *err = NULL;
+    int fd = -1;
+    int connfd = -1;
+    struct sockaddr_un un;
+    socklen_t len = sizeof(un);
+
+    addr.type = SOCKET_ADDRESS_TYPE_UNIX;
+    addr.u.q_unix.path = abstract_sock_name;
+    addr.u.q_unix.tight = user_data != NULL;
+    addr.u.q_unix.abstract = true;
+
+    fd = socket_listen(&addr, 1, &err);
+    g_assert_cmpint(fd, >=, 0);
+    g_assert(fd_is_socket(fd));
+
+    connfd = accept(fd, (struct sockaddr *)&un, &len);
+    g_assert_cmpint(connfd, !=, -1);
+
+    close(fd);
+
+    return NULL;
+}
+
+static gpointer unix_client_thread_func(gpointer user_data)
+{
+    SocketAddress addr;
+    Error *err = NULL;
+    int fd = -1;
+
+    addr.type = SOCKET_ADDRESS_TYPE_UNIX;
+    addr.u.q_unix.path = abstract_sock_name;
+    addr.u.q_unix.tight = user_data != NULL;
+    addr.u.q_unix.abstract = true;
+
+    fd = socket_connect(&addr, &err);
+
+    g_assert_cmpint(fd, >=, 0);
+
+    close(fd);
+
+    return NULL;
+}
+
+static void test_socket_unix_abstract_good(void)
+{
+    GRand *r = g_rand_new();
+
+    abstract_sock_name = g_strdup_printf("unix-%d-%d", getpid(),
+                                         g_rand_int_range(r, 100, 1000));
+
+    /* non tight socklen serv and cli */
+    GThread *serv = g_thread_new("abstract_unix_server",
+                                 unix_server_thread_func,
+                                 NULL);
+
+    sleep(1);
+
+    GThread *cli = g_thread_new("abstract_unix_client",
+                                unix_client_thread_func,
+                                NULL);
+
+    g_thread_join(cli);
+    g_thread_join(serv);
+
+    /* tight socklen serv and cli */
+    serv = g_thread_new("abstract_unix_server",
+                        unix_server_thread_func,
+                        (gpointer)1);
+
+    sleep(1);
+
+    cli = g_thread_new("abstract_unix_client",
+                       unix_client_thread_func,
+                       (gpointer)1);
+
+    g_thread_join(cli);
+    g_thread_join(serv);
+
+    g_free(abstract_sock_name);
+}
+#endif
 
 int main(int argc, char **argv)
 {
@@ -265,6 +352,11 @@ int main(int argc, char **argv)
                         test_socket_fd_pass_num_nocli);
     }
 
+#ifdef __linux__
+    g_test_add_func("/util/socket/unix-abstract/good",
+                    test_socket_unix_abstract_good);
+#endif
+
 end:
     return g_test_run();
 }
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PULL 3/3] qemu-options: updates for abstract unix sockets
  2020-05-20 13:00 [PULL 0/3] Socket next patches Daniel P. Berrangé
  2020-05-20 13:00 ` [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support Daniel P. Berrangé
  2020-05-20 13:00 ` [PULL 2/3] tests/util-sockets: add abstract unix socket cases Daniel P. Berrangé
@ 2020-05-20 13:00 ` Daniel P. Berrangé
  2020-05-21 18:58 ` [PULL 0/3] Socket next patches Peter Maydell
  3 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrangé @ 2020-05-20 13:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrangé,
	xiaoqiang zhao, Markus Armbruster, Gerd Hoffmann,
	Marc-André Lureau, Paolo Bonzini

From: xiaoqiang zhao <zxq_yx_007@163.com>

add options documents changes for -chardev

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 qemu-options.hx | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index e2dca8a4e9..93bde2bbc8 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2938,7 +2938,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
     "         [,server][,nowait][,telnet][,websocket][,reconnect=seconds][,mux=on|off]\n"
     "         [,logfile=PATH][,logappend=on|off][,tls-creds=ID][,tls-authz=ID] (tcp)\n"
     "-chardev socket,id=id,path=path[,server][,nowait][,telnet][,websocket][,reconnect=seconds]\n"
-    "         [,mux=on|off][,logfile=PATH][,logappend=on|off] (unix)\n"
+    "         [,mux=on|off][,logfile=PATH][,logappend=on|off][,abstract=on|off][,tight=on|off] (unix)\n"
     "-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr]\n"
     "         [,localport=localport][,ipv4][,ipv6][,mux=on|off]\n"
     "         [,logfile=PATH][,logappend=on|off]\n"
@@ -3105,9 +3105,13 @@ The available backends are:
 
         ``nodelay`` disables the Nagle algorithm.
 
-    ``unix options: path=path``
+    ``unix options: path=path[,abstract=on|off][,tight=on|off]``
         ``path`` specifies the local path of the unix socket. ``path``
         is required.
+        ``abstract`` specifies the use of the abstract socket namespace,
+        rather than the filesystem.  Optional, defaults to false.
+        ``tight`` sets the socket length of abstract sockets to their minimum,
+        rather than the full sun_path length.  Optional, defaults to true.
 
 ``-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr][,localport=localport][,ipv4][,ipv6]``
     Sends all traffic from the guest to a remote host over UDP.
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support
  2020-05-20 13:00 ` [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support Daniel P. Berrangé
@ 2020-05-20 14:23   ` Markus Armbruster
  2020-05-20 14:33     ` Daniel P. Berrangé
  0 siblings, 1 reply; 7+ messages in thread
From: Markus Armbruster @ 2020-05-20 14:23 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: xiaoqiang zhao, Marc-André Lureau, Paolo Bonzini,
	qemu-devel, Gerd Hoffmann

I apologize for chiming in so late...

Daniel P. Berrangé <berrange@redhat.com> writes:

> From: xiaoqiang zhao <zxq_yx_007@163.com>
>
> unix_listen/connect_saddr now support abstract address types
>
> two aditional BOOL switches are introduced:
> tight: whether to set @addrlen to the minimal string length,
>        or the maximum sun_path length. default is TRUE

When and why would anyone pass 'tight': false?

> abstract: whether we use abstract address. default is FALSE
>
> cli example:
> -monitor unix:/tmp/unix.socket,abstract,tight=off
> OR
> -chardev socket,path=/tmp/unix.socket,id=unix1,abstract,tight=on
>
> Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support
  2020-05-20 14:23   ` Markus Armbruster
@ 2020-05-20 14:33     ` Daniel P. Berrangé
  0 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrangé @ 2020-05-20 14:33 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: xiaoqiang zhao, Marc-André Lureau, Paolo Bonzini,
	qemu-devel, Gerd Hoffmann

On Wed, May 20, 2020 at 04:23:50PM +0200, Markus Armbruster wrote:
> I apologize for chiming in so late...
> 
> Daniel P. Berrangé <berrange@redhat.com> writes:
> 
> > From: xiaoqiang zhao <zxq_yx_007@163.com>
> >
> > unix_listen/connect_saddr now support abstract address types
> >
> > two aditional BOOL switches are introduced:
> > tight: whether to set @addrlen to the minimal string length,
> >        or the maximum sun_path length. default is TRUE
> 
> When and why would anyone pass 'tight': false?

In the abstract namespace the length of the socket is critical
information. ie

   "\0foo" (length == 4,  tight=true)

is a completely different socket from

   "\0foo\0..repeated...\0" (length == sizeof(sun_path), tight=false)

In theory you can have any length in between those extremes,
each being a different socket, but in practice no one is that
insane. Apps either use the full length, or the minimal
length. The "tight" terminology is copied from "socat" which
uses this same option name


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PULL 0/3] Socket next patches
  2020-05-20 13:00 [PULL 0/3] Socket next patches Daniel P. Berrangé
                   ` (2 preceding siblings ...)
  2020-05-20 13:00 ` [PULL 3/3] qemu-options: updates for abstract unix sockets Daniel P. Berrangé
@ 2020-05-21 18:58 ` Peter Maydell
  3 siblings, 0 replies; 7+ messages in thread
From: Peter Maydell @ 2020-05-21 18:58 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Marc-André Lureau, Paolo Bonzini, Gerd Hoffmann,
	QEMU Developers, Markus Armbruster

On Wed, 20 May 2020 at 14:03, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> The following changes since commit f2465433b43fb87766d79f42191607dac4aed5b4:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2020-05-19 13:42:58 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/berrange/qemu tags/socket-next-pull-request
>
> for you to fetch changes up to e339273bfc514824410a49837e4f16dd4e51ae8e:
>
>   qemu-options: updates for abstract unix sockets (2020-05-20 10:34:53 +0100)
>
> ----------------------------------------------------------------
> Add support for UNIX sockets in the abstract namespace
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.1
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-05-21 18:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-20 13:00 [PULL 0/3] Socket next patches Daniel P. Berrangé
2020-05-20 13:00 ` [PULL 1/3] qemu-sockets: add abstract UNIX domain socket support Daniel P. Berrangé
2020-05-20 14:23   ` Markus Armbruster
2020-05-20 14:33     ` Daniel P. Berrangé
2020-05-20 13:00 ` [PULL 2/3] tests/util-sockets: add abstract unix socket cases Daniel P. Berrangé
2020-05-20 13:00 ` [PULL 3/3] qemu-options: updates for abstract unix sockets Daniel P. Berrangé
2020-05-21 18:58 ` [PULL 0/3] Socket next patches Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.