From 225830dcb8bf1a6583d0f4ca182584024783923e Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Thu, 17 Dec 2015 16:49:59 -0800 Subject: [PATCH] server: Add a socket with an existing fd This adds functionality to allow system-level control over handing out file descriptors for sockets, to allow tighter security when running a Wayland compositor under a Wayland session server. Allows writing socket activated Wayland servers. Signed-off-by: Bryce Harrington Reviewed-by: Pekka Paalanen Cc: Sung-Jin Park Cc: Sangjin Lee --- src/wayland-server-core.h | 3 +++ src/wayland-server.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index 85b4b9e..1700cd3 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -131,6 +131,9 @@ wl_display_add_socket(struct wl_display *display, const char *name); const char * wl_display_add_socket_auto(struct wl_display *display); +int +wl_display_add_socket_fd(struct wl_display *display, int sock_fd); + void wl_display_terminate(struct wl_display *display); diff --git a/src/wayland-server.c b/src/wayland-server.c index 1364d5d..55c0cf9 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -1198,6 +1198,49 @@ wl_display_add_socket_auto(struct wl_display *display) return NULL; } +/** Add a socket with an existing fd to Wayland display for the clients to connect. + * + * \param display Wayland display to which the socket should be added. + * \param sock_fd The existing socket file descriptor to be used + * \return 0 if success. -1 if failed. + * + * The existing socket fd must already be created, opened, and locked. + * The fd must be properly set to CLOEXEC and bound to a socket file + * with both bind() and listen() already called. + * + * \memberof wl_display + */ +WL_EXPORT int +wl_display_add_socket_fd(struct wl_display *display, int sock_fd) +{ + struct wl_socket *s; + struct stat buf; + + /* Require a valid fd or fail */ + if (sock_fd < 0 || fstat(sock_fd, &buf) < 0 || !S_ISSOCK(buf.st_mode)) { + return -1; + } + + s = wl_socket_alloc(); + if (s == NULL) + return -1; + + /* Reuse the existing fd */ + s->fd = sock_fd; + + s->source = wl_event_loop_add_fd(display->loop, s->fd, + WL_EVENT_READABLE, + socket_data, display); + if (s->source == NULL) { + wl_log("failed to establish event source\n"); + return -1; + } + + wl_list_insert(display->socket_list.prev, &s->link); + + return 0; +} + /** Add a socket to Wayland display for the clients to connect. * * \param display Wayland display to which the socket should be added. -- 2.7.4