Fix segfault in nss plugin accepted/tizen/3.0/common/20170721.115213 accepted/tizen/3.0/ivi/20170721.023957 accepted/tizen/3.0/mobile/20170721.023941 accepted/tizen/3.0/tv/20170721.023947 accepted/tizen/3.0/wearable/20170721.023953 submit/tizen_3.0/20170720.055302
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 19 Jul 2017 09:34:17 +0000 (11:34 +0200)
committerjin-gyu.kim <jin-gyu.kim@samsung.com>
Thu, 20 Jul 2017 05:52:32 +0000 (14:52 +0900)
- Initialize groups pointer to NULL
- Delay wrapping with unique_ptr until we are sure that function returning
  groups succeeded
- Treat empty group list as a correct result

Change-Id: I9cf7493d819f3c1afdc2a378bc52f24d0f3f53b9

src/client/client-security-manager.cpp
src/nss/nss_securitymanager.cpp

index a643186f1c37cc350fee8a13f631bf2c511442a6..be22b174fd1f635cc6acfecad4bc3c7b6bd46106 100644 (file)
@@ -1130,6 +1130,12 @@ static void loadGroups(std::vector<gid_t> &vgroups) {
 
 static int group_vector_to_array(const std::vector<gid_t> &vgroups, gid_t **groups, size_t *groups_count)
 {
+    if (vgroups.empty()) {
+        *groups_count = 0;
+        *groups = NULL;
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     size_t size = vgroups.size() * sizeof(gid_t);
     *groups = static_cast<gid_t*>(malloc(size));
     if (*groups == nullptr)
index 0e2ae5e6d456681a38e569cf7e74796571048480..2a975e695996d80a2497d684f57c4856c19de528 100644 (file)
@@ -106,7 +106,7 @@ enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t grou
             return NSS_STATUS_NOTFOUND;
         }
 
-        gid_t *groups;
+        gid_t *groups = NULL;
         size_t groupsCount;
         ret = security_manager_groups_get_for_user(pwnam->pw_uid, &groups, &groupsCount);
 
@@ -114,7 +114,6 @@ enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t grou
             // If user is not managed by Security Manager, we want to apply all the groups
             ret = security_manager_groups_get(&groups, &groupsCount);
         }
-        auto groupsGuard = SecurityManager::makeUnique(groups, free);
 
         if (ret == SECURITY_MANAGER_ERROR_MEMORY) {
             *errnop = ENOMEM;
@@ -131,6 +130,8 @@ enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t grou
             return NSS_STATUS_UNAVAIL;
         }
 
+        auto groupsGuard = SecurityManager::makeUnique(groups, free);
+
         if (((*size) - (*start)) < static_cast<long int>(groupsCount)) {
             long int required = (*start) + groupsCount;
             // value bigger is the lowest power of 2 that is bigger than required value