From 1be958e68279a95633d948fe901c951c0f323f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Schieli?= Date: Sat, 18 Mar 2017 11:32:01 +0100 Subject: [PATCH] Helper functions needed to secure the promiscuous mode. The jack_group2gid() function does a thread-safe lookup of a unix gid from a unix group name. The jack_promiscuous_perms() function adjusts the permissions of a shared resource (socket, semaphore, shm segment, ...) referenced by a fd and/or a path so it can be used by any member of the provided unix group. By using those functions it will be possible to enable a secure promiscuous mode. 'Secure' meaning here that one is not forced to launch every clients with a (way) too permissive 0000 umask. --- common/promiscuous.c | 95 ++++++++++++++++++++++++++++++++++++++++++++ common/promiscuous.h | 39 ++++++++++++++++++ common/wscript | 3 ++ 3 files changed, 137 insertions(+) create mode 100644 common/promiscuous.c create mode 100644 common/promiscuous.h diff --git a/common/promiscuous.c b/common/promiscuous.c new file mode 100644 index 00000000..aa6850c1 --- /dev/null +++ b/common/promiscuous.c @@ -0,0 +1,95 @@ +/* + Copyright (C) 2014-2017 Cédric Schieli + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#endif +#include "JackError.h" +#endif + + +int +jack_group2gid(const char* group) +{ +#ifdef WIN32 + return -1; +#else + size_t buflen; + char *buf; + int ret; + struct group grp; + struct group *result; + + if (!group || !*group) + return -1; + + ret = strtol(group, &buf, 10); + if (!*buf) + return ret; + +/* MacOSX only defines _SC_GETGR_R_SIZE_MAX starting from 10.4 */ +#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 + buflen = 4096; +#else + buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + if (buflen == -1) + buflen = 4096; +#endif + buf = (char*)malloc(buflen); + + while (buf && ((ret = getgrnam_r(group, &grp, buf, buflen, &result)) == ERANGE)) { + buflen *= 2; + buf = (char*)realloc(buf, buflen); + } + if (!buf) + return -1; + free(buf); + if (ret || !result) + return -1; + return grp.gr_gid; +#endif +} + +#ifndef WIN32 +int +jack_promiscuous_perms(int fd, const char* path, gid_t gid) +{ + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + if (gid >= 0) { + if (((fd < 0) ? chown(path, -1, gid) : fchown(fd, -1, gid)) < 0) { + jack_log("Cannot chgrp %s: %s. Falling back to permissive perms.", path, strerror(errno)); + } else { + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + } + } + if (((fd < 0) ? chmod(path, mode) : fchmod(fd, mode)) < 0) { + jack_log("Cannot chmod %s: %s. Falling back to default (umask) perms.", path, strerror(errno)); + return -1; + } + return 0; +} +#endif diff --git a/common/promiscuous.h b/common/promiscuous.h new file mode 100644 index 00000000..437fc03c --- /dev/null +++ b/common/promiscuous.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2014-2017 Cédric Schieli + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef __jack_gid_h__ +#define __jack_gid_h__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +int jack_group2gid (const char *group); /*!< Lookup gid for a UNIX group in a thread-safe way */ +#ifndef WIN32 +int jack_promiscuous_perms (int fd, const char *path, gid_t gid); /*!< Set promiscuous permissions on object referenced by fd and/or path */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __jack_gid_h__ */ + + diff --git a/common/wscript b/common/wscript index 860cbace..cbdaacc2 100644 --- a/common/wscript +++ b/common/wscript @@ -82,6 +82,7 @@ def build(bld): common_libsources += [ 'JackDebugClient.cpp', 'timestamps.c', + 'promiscuous.c', '../posix/JackPosixThread.cpp', '../posix/JackPosixProcessSync.cpp', '../posix/JackPosixMutex.cpp', @@ -97,6 +98,7 @@ def build(bld): common_libsources += [ 'JackDebugClient.cpp', 'timestamps.c', + 'promiscuous.c', '../posix/JackPosixThread.cpp', '../posix/JackFifo.cpp', '../posix/JackPosixProcessSync.cpp', @@ -111,6 +113,7 @@ def build(bld): common_libsources += [ 'JackDebugClient.cpp', 'timestamps.c', + 'promiscuous.c', '../posix/JackPosixProcessSync.cpp', '../posix/JackPosixThread.cpp', '../posix/JackPosixMutex.cpp',