X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=bin%2Frootwrap.c;h=e95784c9dc3dc5604ae2e21497efe5bea894c903;hb=4675f892ad1e6262b981f7618ede09b4c82205ab;hp=f2c851a3544347ea5cdc522cf29a62f3f68c49e8;hpb=83b35c64b6e1f7c90b577724d3e3a1fa57b7b747;p=vlc diff --git a/bin/rootwrap.c b/bin/rootwrap.c index f2c851a354..e95784c9dc 100644 --- a/bin/rootwrap.c +++ b/bin/rootwrap.c @@ -21,6 +21,7 @@ #if HAVE_CONFIG_H # include #endif +#define _XPG4_2 /* ancilliary data on Solaris */ #include /* exit() */ #include @@ -45,6 +46,16 @@ #ifndef AF_LOCAL # define AF_LOCAL AF_UNIX #endif +/* Required yet non-standard cmsg functions */ +#ifndef CMSG_ALIGN +# define CMSG_ALIGN(len) (((len) + sizeof(intptr_t)-1) & ~(sizeof(intptr_t)-1)) +#endif +#ifndef CMSG_SPACE +# define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len)) +#endif +#ifndef CMSG_LEN +# define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) +#endif static inline int is_allowed_port (uint16_t port) { @@ -95,34 +106,45 @@ static int send_fd (int p, int fd) */ static void rootprocess (int fd) { - struct sockaddr_storage ss; + union + { + struct sockaddr sa; + struct sockaddr_storage ss; + struct sockaddr_in sin; +#ifdef AF_INET6 + struct sockaddr_in6 sin6; +#endif + } addr; - while (recv (fd, &ss, sizeof (ss), 0) == sizeof (ss)) + while (recv (fd, &addr.ss, sizeof (addr.ss), 0) == sizeof (addr.ss)) { unsigned len; int sock; + int family; - switch (ss.ss_family) + switch (addr.sa.sa_family) { case AF_INET: - if (!is_allowed_port (((struct sockaddr_in *)&ss)->sin_port)) + if (!is_allowed_port (addr.sin.sin_port)) { if (send_err (fd, EACCES)) return; continue; } len = sizeof (struct sockaddr_in); + family = PF_INET; break; #ifdef AF_INET6 case AF_INET6: - if (!is_allowed_port (((struct sockaddr_in6 *)&ss)->sin6_port)) + if (!is_allowed_port (addr.sin6.sin6_port)) { if (send_err (fd, EACCES)) return; continue; } len = sizeof (struct sockaddr_in6); + family = PF_INET6; break; #endif @@ -132,17 +154,17 @@ static void rootprocess (int fd) continue; } - sock = socket (ss.ss_family, SOCK_STREAM, IPPROTO_TCP); + sock = socket (family, SOCK_STREAM, IPPROTO_TCP); if (sock != -1) { const int val = 1; setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (val)); #ifdef AF_INET6 - if (ss.ss_family == AF_INET6) + if (addr.sa.sa_family == AF_INET6) setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof (val)); #endif - if (bind (sock, (struct sockaddr *)&ss, len) == 0) + if (bind (sock, &addr.sa, len) == 0) { send_fd (fd, sock); close (sock);