]> git.proxmox.com Git - mirror_lxcfs.git/blobdiff - pam/pam_cgfs.c
pam_cgfs: make sure that **p is not NULL
[mirror_lxcfs.git] / pam / pam_cgfs.c
index 73e950330d08301c0ed3829c4ed2aaeb83a2ea36..fd47d7076a2271a1997eb164c9fdf2a3d2a2e184 100644 (file)
@@ -122,10 +122,12 @@ static inline void set_bit(unsigned bit, uint32_t *bitarr)
        bitarr[bit / NBITS] |= (1 << (bit % NBITS));
 }
 static bool string_in_list(char **list, const char *entry);
-char *string_join(const char *sep, const char **parts, bool use_as_prefix);
+static char *string_join(const char *sep, const char **parts, bool use_as_prefix);
 static void trim(char *s);
 static bool write_int(char *path, int v);
-ssize_t write_nointr(int fd, const void* buf, size_t count);
+static ssize_t write_nointr(int fd, const void* buf, size_t count);
+static int write_to_file(const char *filename, const void *buf, size_t count,
+                        bool add_newline);
 
 /* cgroupfs prototypes. */
 static bool cg_belongs_to_uid_gid(const char *path, uid_t uid, gid_t gid);
@@ -151,8 +153,6 @@ static bool cg_systemd_under_user_slice_1(const char *in, uid_t uid);
 static bool cg_systemd_under_user_slice_2(const char *base_cgroup,
                                          const char *init_cgroup, uid_t uid);
 static void cg_systemd_prune_init_scope(char *cg);
-int cg_write_to_file(const char *filename, const void *buf, size_t count,
-                    bool add_newline);
 static bool is_lxcfs(const char *line);
 
 /* cgroupfs v1 prototypes. */
@@ -1318,7 +1318,6 @@ static int cg_get_version_of_mntpt(const char *path)
 static bool cgv2_init(uid_t uid, gid_t gid)
 {
        char *mountpoint;
-       bool ret = false;
        FILE *f = NULL;
        char *current_cgroup = NULL, *init_cgroup = NULL;
        char * line = NULL;
@@ -1327,7 +1326,6 @@ static bool cgv2_init(uid_t uid, gid_t gid)
        current_cgroup = cgv2_get_current_cgroup(getpid());
        if (!current_cgroup) {
                /* No v2 hierarchy present. We're done. */
-               ret = true;
                goto cleanup;
        }
 
@@ -1360,7 +1358,6 @@ static bool cgv2_init(uid_t uid, gid_t gid)
 
                cgv2_add_controller(NULL, mountpoint, current_cgroup, init_cgroup, has_user_slice);
 
-               ret = true;
                goto cleanup;
        }
 
@@ -1645,13 +1642,16 @@ static uint32_t *cg_cpumask(char *buf, size_t nbits)
        return bitarr;
 }
 
-char *string_join(const char *sep, const char **parts, bool use_as_prefix)
+static char *string_join(const char *sep, const char **parts, bool use_as_prefix)
 {
        char *result;
        char **p;
        size_t sep_len = strlen(sep);
        size_t result_len = use_as_prefix * sep_len;
 
+       if (!parts)
+               return NULL;
+
        /* calculate new string length */
        for (p = (char **)parts; *p; p++)
                result_len += (p > (char **)parts) * sep_len + strlen(*p);
@@ -1712,8 +1712,6 @@ static ssize_t cg_get_max_cpus(char *cpulist)
 
        if (!c1 && !c2)
                c1 = maxcpus;
-       else if (c1 > c2)
-               c2 = c1;
        else if (c1 < c2)
                c1 = c2;
 
@@ -1729,7 +1727,7 @@ static ssize_t cg_get_max_cpus(char *cpulist)
        return cpus;
 }
 
-ssize_t write_nointr(int fd, const void* buf, size_t count)
+static ssize_t write_nointr(int fd, const void* buf, size_t count)
 {
        ssize_t ret;
 again:
@@ -1739,7 +1737,7 @@ again:
        return ret;
 }
 
-int cg_write_to_file(const char *filename, const void* buf, size_t count, bool add_newline)
+static int write_to_file(const char *filename, const void* buf, size_t count, bool add_newline)
 {
        int fd, saved_errno;
        ssize_t ret;
@@ -1767,6 +1765,7 @@ out_error:
        return -1;
 }
 
+#define __ISOL_CPUS "/sys/devices/system/cpu/isolated"
 static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
 {
        char *lastslash, *fpath, oldv;
@@ -1776,78 +1775,120 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
        ssize_t maxposs = 0, maxisol = 0;
        char *cpulist = NULL, *posscpus = NULL, *isolcpus = NULL;
        uint32_t *possmask = NULL, *isolmask = NULL;
-       bool bret = false;
+       bool bret = false, flipped_bit = false;
 
        lastslash = strrchr(path, '/');
        if (!lastslash) { // bug...  this shouldn't be possible
-               lxcfs_debug("cgfsng:copy_parent_file: bad path %s", path);
+               lxcfs_debug("Invalid path: %s.\n", path);
                return bret;
        }
        oldv = *lastslash;
        *lastslash = '\0';
        fpath = must_make_path(path, "cpuset.cpus", NULL);
        posscpus = read_file(fpath);
-       if (!posscpus)
-               goto cleanup;
+       if (!posscpus) {
+               lxcfs_debug("Could not read file: %s.\n", fpath);
+               goto on_error;
+       }
 
        /* Get maximum number of cpus found in possible cpuset. */
        maxposs = cg_get_max_cpus(posscpus);
        if (maxposs < 0)
-               goto cleanup;
+               goto on_error;
 
-       isolcpus = read_file("/sys/devices/system/cpu/isolated");
-       if (!isolcpus)
-               goto cleanup;
+       if (!file_exists(__ISOL_CPUS)) {
+               /* This system doesn't expose isolated cpus. */
+               lxcfs_debug("%s", "Path: "__ISOL_CPUS" to read isolated cpus from does not exist.\n");
+               cpulist = posscpus;
+               /* No isolated cpus but we weren't already initialized by
+                * someone. We should simply copy the parents cpuset.cpus
+                * values.
+                */
+               if (!am_initialized) {
+                       lxcfs_debug("%s", "Copying cpuset of parent cgroup.\n");
+                       goto copy_parent;
+               }
+               /* No isolated cpus but we were already initialized by someone.
+                * Nothing more to do for us.
+                */
+               goto on_success;
+       }
+
+       isolcpus = read_file(__ISOL_CPUS);
+       if (!isolcpus) {
+               lxcfs_debug("%s", "Could not read file "__ISOL_CPUS"\n");
+               goto on_error;
+       }
        if (!isdigit(isolcpus[0])) {
+               lxcfs_debug("%s", "No isolated cpus detected.\n");
                cpulist = posscpus;
                /* No isolated cpus but we weren't already initialized by
                 * someone. We should simply copy the parents cpuset.cpus
                 * values.
                 */
-               if (!am_initialized)
+               if (!am_initialized) {
+                       lxcfs_debug("%s", "Copying cpuset of parent cgroup.\n");
                        goto copy_parent;
+               }
                /* No isolated cpus but we were already initialized by someone.
                 * Nothing more to do for us.
                 */
-               bret = true;
-               goto cleanup;
+               goto on_success;
        }
 
        /* Get maximum number of cpus found in isolated cpuset. */
        maxisol = cg_get_max_cpus(isolcpus);
        if (maxisol < 0)
-               goto cleanup;
+               goto on_error;
 
        if (maxposs < maxisol)
                maxposs = maxisol;
        maxposs++;
 
        possmask = cg_cpumask(posscpus, maxposs);
-       if (!possmask)
-               goto cleanup;
+       if (!possmask) {
+               lxcfs_debug("%s", "Could not create cpumask for all possible cpus.\n");
+               goto on_error;
+       }
 
        isolmask = cg_cpumask(isolcpus, maxposs);
-       if (!isolmask)
-               goto cleanup;
+       if (!isolmask) {
+               lxcfs_debug("%s", "Could not create cpumask for all isolated cpus.\n");
+               goto on_error;
+       }
 
        for (i = 0; i <= maxposs; i++) {
                if (is_set(i, isolmask) && is_set(i, possmask)) {
+                       flipped_bit = true;
                        clear_bit(i, possmask);
                }
        }
 
+       if (!flipped_bit) {
+               lxcfs_debug("%s", "No isolated cpus present in cpuset.\n");
+               goto on_success;
+       }
+       lxcfs_debug("%s", "Removed isolated cpus from cpuset.\n");
+
        cpulist = cg_cpumask_to_cpulist(possmask, maxposs);
-       if (!cpulist) /* Bug */
-               goto cleanup;
+       if (!cpulist) {
+               lxcfs_debug("%s", "Could not create cpu list.\n");
+               goto on_error;
+       }
 
 copy_parent:
        *lastslash = oldv;
        fpath = must_make_path(path, "cpuset.cpus", NULL);
-       ret = cg_write_to_file(fpath, cpulist, strlen(cpulist), false);
-       if (!ret)
-               bret = true;
+       ret = write_to_file(fpath, cpulist, strlen(cpulist), false);
+       if (ret < 0) {
+               lxcfs_debug("Could not write cpu list to: %s.\n", fpath);
+               goto on_error;
+       }
 
-cleanup:
+on_success:
+       bret = true;
+
+on_error:
        free(fpath);
 
        free(isolcpus);
@@ -1915,7 +1956,7 @@ static bool cg_copy_parent_file(char *path, char *file)
        free(fpath);
        *lastslash = oldv;
        fpath = must_make_path(path, file, NULL);
-       ret = cg_write_to_file(fpath, value, len, false);
+       ret = write_to_file(fpath, value, len, false);
        if (ret < 0)
                lxcfs_debug("Unable to write %s to %s", value, fpath);
        free(fpath);
@@ -1954,7 +1995,7 @@ static bool cgv1_handle_root_cpuset_hierarchy(struct cgv1_hierarchy *h)
                return true;
        }
 
-       if (cg_write_to_file(clonechildrenpath, "1", 1, false) < 0) {
+       if (write_to_file(clonechildrenpath, "1", 1, false) < 0) {
                /* Set clone_children so children inherit our settings */
                lxcfs_debug("Failed to write 1 to %s", clonechildrenpath);
                free(clonechildrenpath);
@@ -2014,6 +2055,7 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
        }
 
        if (v == '1') {  /* already set for us by someone else */
+               lxcfs_debug("%s", "\"cgroup.clone_children\" was already set to \"1\".\n");
                free(clonechildrenpath);
                free(cgpath);
                return true;
@@ -2021,13 +2063,14 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
 
        /* copy parent's settings */
        if (!cg_copy_parent_file(cgpath, "cpuset.mems")) {
+               lxcfs_debug("%s", "Failed to copy \"cpuset.mems\" settings.\n");
                free(cgpath);
                free(clonechildrenpath);
                return false;
        }
        free(cgpath);
 
-       if (cg_write_to_file(clonechildrenpath, "1", 1, false) < 0) {
+       if (write_to_file(clonechildrenpath, "1", 1, false) < 0) {
                /* Set clone_children so children inherit our settings */
                lxcfs_debug("Failed to write 1 to %s", clonechildrenpath);
                free(clonechildrenpath);
@@ -2114,10 +2157,7 @@ static bool cgv1_create_one(struct cgv1_hierarchy *h, const char *cgroup, uid_t
                break;
        }
 
-       if (!created)
-               return false;
-
-       return true;
+       return created;
 }
 
 /* Try to remove @cgroup for all given controllers in a cgroupfs v1 hierarchy