[Bug 219988] [kernel] sys/kern/kern_sysctl.c:a sleep-under-rmlock bug in sysctl_add_oid

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Wed Jun 14 15:17:37 UTC 2017


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=219988

Conrad Meyer <cem at freebsd.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |cem at freebsd.org
            Version|11.0-RELEASE                |CURRENT
           Hardware|i386                        |Any

--- Comment #1 from Conrad Meyer <cem at freebsd.org> ---
I suggest moving the allocation out from under the lock rather than converting
an M_WAITOK allocation to M_NOWAIT.  E.g.,

--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -698,11 +698,12 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct
sysctl_oid_list *parent,
        int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char
*descr,
        const char *label)
 {
-       struct sysctl_oid *oidp;
+       struct sysctl_oid *oidp, *storage;

        /* You have to hook up somewhere.. */
        if (parent == NULL)
                return(NULL);
+       storage = malloc(sizeof(*storage), M_SYSCTLOID, M_WAITOK|M_ZERO);
        /* Check if the node already exists, otherwise create it */
        SYSCTL_WLOCK();
        oidp = sysctl_find_oidname(name, parent);
@@ -713,14 +714,16 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct
sysctl_oid_list *parent,
                        if (clist != NULL)
                                sysctl_ctx_entry_add(clist, oidp);
                        SYSCTL_WUNLOCK();
+                       free(storage);
                        return (oidp);
                } else {
                        SYSCTL_WUNLOCK();
                        printf("can't re-use a leaf (%s)!\n", name);
+                       free(storage);
                        return (NULL);
                }
        }
-       oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, M_WAITOK|M_ZERO);
+       oidp = storage;
        oidp->oid_parent = parent;
        SLIST_INIT(&oidp->oid_children);
        oidp->oid_number = number;

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list