From 459813a64ebd531b4fd4e7e4a08ecf564c721870 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Wed, 26 Aug 2020 13:08:55 +0200 Subject: [PATCH] logger: extract privilege related code Change-Id: I7cd79b564227bb5b7479d04248430ae457b34b46 Signed-off-by: Michal Bloch --- Makefile.am | 1 + src/logger/logger.c | 104 +-------------------------------- src/logger/logger_internal.h | 2 - src/logger/logger_privileges.c | 129 +++++++++++++++++++++++++++++++++++++++++ src/logger/logger_privileges.h | 22 +++++++ src/tests/logger.c | 4 +- 6 files changed, 155 insertions(+), 107 deletions(-) create mode 100644 src/logger/logger_privileges.c create mode 100644 src/logger/logger_privileges.h diff --git a/Makefile.am b/Makefile.am index 6ef1825..57230f5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,6 +121,7 @@ dlog_logger_LDFLAGS = \ dlog_logger_SOURCES = \ external/sd-daemon/sd-daemon.c \ src/logger/logger.c \ + src/logger/logger_privileges.c \ src/logger/dlogutil_line.c \ src/logger/fd_entity.c \ src/logger/log_buffer.c \ diff --git a/src/logger/logger.c b/src/logger/logger.c index 1860bbc..b1a0626 100644 --- a/src/logger/logger.c +++ b/src/logger/logger.c @@ -19,6 +19,8 @@ #endif #include "logger_internal.h" +#include "logger_privileges.h" + #include #include #include @@ -49,108 +51,6 @@ static const int MS_TO_NS = 1000000; struct backend_data g_backend = {}; -/** - * @brief Parse permissions - * @details Parse a string representation of permissions to the internal integral one - * @param[in] str The string representation - * @return The integer representation - */ -int parse_permissions(const char * str) -{ - int ret, parsed; - char * parse_safety; - - if (!str) - return S_IWUSR | S_IWGRP | S_IWOTH; // 0222: everyone can write - - parsed = strtol(str, & parse_safety, 8); // note, rights are octal - if (parse_safety != (str + strlen(str))) - return 0; - - ret = 0; - - // note that R and X are pretty useless, only W makes sense - if (parsed & 00001) ret |= S_IXOTH; - if (parsed & 00002) ret |= S_IWOTH; - if (parsed & 00004) ret |= S_IROTH; - if (parsed & 00010) ret |= S_IXGRP; - if (parsed & 00020) ret |= S_IWGRP; - if (parsed & 00040) ret |= S_IRGRP; - if (parsed & 00100) ret |= S_IXUSR; - if (parsed & 00200) ret |= S_IWUSR; - if (parsed & 00400) ret |= S_IRUSR; - if (parsed & 01000) ret |= S_ISVTX; - if (parsed & 02000) ret |= S_ISGID; - if (parsed & 04000) ret |= S_ISUID; - - if (parsed & ~07777) - printf("Warning: useless bits in permissions %s!", str); - - return ret; -} - -/** - * @brief Get numerical ids for specified user and group - * @details Converts user and group strings to proper uid and gid identifiers - * @param[in] user The new user - * @param[in] group The new group - * @param[out] uid The uid for user - * @param[out] gid The numerical gid for group - * @return 0 on success, else -errno - */ -int usergr2id(const char * user, const char * group, uid_t *uid, gid_t *gid) -{ - struct passwd pwd, *ppwd; - struct group grp, *pgrp; - int bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - - assert(user); - assert(group); - - if (bufsize == -1) - bufsize = 1024; - - char *const buffer = (char *)alloca(bufsize); - - if (getgrnam_r(user, &grp, buffer, bufsize, &pgrp)) - return -errno; - if (!pgrp) - return -ENOENT; - - if (getpwnam_r(group, &pwd, buffer, bufsize, &ppwd)) - return -errno; - if (!ppwd) - return -ENOENT; - - *uid = pwd.pw_uid; - *gid = grp.gr_gid; - - return 0; -} - -/** - * @brief Reset privileges - * @details Resets privileges to those specified at build-time - * @return 0 on success, else -errno - */ -int reset_self_privileges() -{ - uid_t uid; - gid_t gid; - int r; - - r = usergr2id(DLOG_SERVER_USER, DLOG_SERVER_GROUP, &uid, &gid); - if (r < 0) - return r; - - if (getegid() != gid && setgid(gid) < 0) - return -errno; - if (geteuid() != uid && setuid(uid) < 0) - return -errno; // should never happen - - return 0; -} - static bool cond_reader_logger_free(void *ptr, void *user_data) { struct reader_logger *reader = (struct reader_logger *)ptr; diff --git a/src/logger/logger_internal.h b/src/logger/logger_internal.h index 8445435..296f307 100644 --- a/src/logger/logger_internal.h +++ b/src/logger/logger_internal.h @@ -10,8 +10,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/src/logger/logger_privileges.c b/src/logger/logger_privileges.c new file mode 100644 index 0000000..c5b1265 --- /dev/null +++ b/src/logger/logger_privileges.c @@ -0,0 +1,129 @@ +/* Copyright (c) 2020, Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#include "logger_privileges.h" + +// POSIX +#include +#include +#include +#include + +// C +#include +#include +#include +#include +#include + +/** + * @brief Parse permissions + * @details Parse a string representation of permissions to the internal integral one + * @param[in] str The string representation + * @return The integer representation + */ +int parse_permissions(const char *str) +{ + int ret, parsed; + char *parse_safety; + + if (!str) + return S_IWUSR | S_IWGRP | S_IWOTH; // 0222: everyone can write + + parsed = strtol(str, & parse_safety, 8); // note, rights are octal + if (parse_safety != (str + strlen(str))) + return 0; + + ret = 0; + + // note that R and X are pretty useless, only W makes sense + if (parsed & 00001) ret |= S_IXOTH; + if (parsed & 00002) ret |= S_IWOTH; + if (parsed & 00004) ret |= S_IROTH; + if (parsed & 00010) ret |= S_IXGRP; + if (parsed & 00020) ret |= S_IWGRP; + if (parsed & 00040) ret |= S_IRGRP; + if (parsed & 00100) ret |= S_IXUSR; + if (parsed & 00200) ret |= S_IWUSR; + if (parsed & 00400) ret |= S_IRUSR; + if (parsed & 01000) ret |= S_ISVTX; + if (parsed & 02000) ret |= S_ISGID; + if (parsed & 04000) ret |= S_ISUID; + + if (parsed & ~07777) + printf("Warning: useless bits in permissions %s!", str); + + return ret; +} + +/** + * @brief Get numerical ids for specified user and group + * @details Converts user and group strings to proper uid and gid identifiers + * @param[in] user The new user + * @param[in] group The new group + * @param[out] uid The uid for user + * @param[out] gid The numerical gid for group + * @return 0 on success, else -errno + */ +int usergr2id(const char *user, const char *group, uid_t *uid, gid_t *gid) +{ + struct passwd pwd, *ppwd; + struct group grp, *pgrp; + int bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + + assert(user); + assert(group); + + if (bufsize == -1) + bufsize = 1024; + + char *const buffer = (char *)alloca(bufsize); + + if (getgrnam_r(user, &grp, buffer, bufsize, &pgrp)) + return -errno; + if (!pgrp) + return -ENOENT; + + if (getpwnam_r(group, &pwd, buffer, bufsize, &ppwd)) + return -errno; + if (!ppwd) + return -ENOENT; + + *uid = pwd.pw_uid; + *gid = grp.gr_gid; + + return 0; +} + +/** + * @brief Reset privileges + * @details Resets privileges to those specified at build-time + * @return 0 on success, else -errno + */ +int reset_self_privileges() +{ + uid_t uid; + gid_t gid; + + int r = usergr2id(DLOG_SERVER_USER, DLOG_SERVER_GROUP, &uid, &gid); + if (r < 0) + return r; + + if (getegid() != gid && setgid(gid) < 0) + return -errno; + if (geteuid() != uid && setuid(uid) < 0) + return -errno; // should never happen + + return 0; +} diff --git a/src/logger/logger_privileges.h b/src/logger/logger_privileges.h new file mode 100644 index 0000000..45dcd43 --- /dev/null +++ b/src/logger/logger_privileges.h @@ -0,0 +1,22 @@ +#pragma once + +/* Copyright (c) 2020, Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#include + +int parse_permissions(const char *str); +int reset_self_privileges(); +int usergr2id(const char *user, const char *group, uid_t *uid, gid_t *gid); + diff --git a/src/tests/logger.c b/src/tests/logger.c index 99e86fe..dc1a0fa 100644 --- a/src/tests/logger.c +++ b/src/tests/logger.c @@ -6,12 +6,10 @@ #include #include #include "../logger/logger_internal.h" +#include "../logger/logger_privileges.h" #include "../logger/log_storage.h" #include "../logger/reader_pipe.h" -int parse_permissions(const char *str); -int usergr2id(const char *user, const char *group, uid_t *uid, gid_t *gid); -int reset_self_privileges(); int bind_fd_create(const char *path, int type); int listen_fd_create(const char *path, int permissions); int systemd_sock_get(const char *path, int type); -- 2.7.4