Bug 31490

Summary: [sysctl] [patch] Panic in sysctl_sysctl_next_ls on empy node
Product: Base System Reporter: Maxim Katargin <kmv>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description Maxim Katargin 2001-10-25 16:00:01 UTC
Panic in sysctl_sysctl_next_ls on empy node.

Fix: 

+       isnamelen = namelen ? 1 : 0
        *len = level;
        SLIST_FOREACH(oidp, lsp, oid_link) {
                *next = oidp->oid_number;
@@ -572,7 +574,7 @@
                        len, level+1, oidpp))
                        return (0);
        next:
-               namelen = 1;
+               namelen = isnamelen;
                *len = level;
        }
        return 1;--PpQtttzuQhNISVrw6kIH6cbMc7LfkKbBhUVHEtzBDconjykP
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

Index: kern/kern_sysctl.c
===================================================================
RCS file: /ext/vcvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.92.2.5
diff -u -r1.92.2.5 kern_sysctl.c
--- kern/kern_sysctl.c  2001/06/18 23:48:13     1.92.2.5
+++ kern/kern_sysctl.c  2001/10/25 14:54:42
@@ -528,7 +528,9 @@
        int *next, int *len, int level, struct sysctl_oid **oidpp)
 {
        struct sysctl_oid *oidp;
+       int isnamelen;
Comment 1 iedowse freebsd_committer freebsd_triage 2002-12-01 19:58:48 UTC
State Changed
From-To: open->feedback


Could you provide some information about how to repeat the problem 
that the patch is supposed to fix?
Comment 2 Hiten Pandya 2002-12-03 14:56:11 UTC
Hi there.

This bug happens in 5.0-CURRENT, and it seems that it is a very old bug.
I have some test code, which was devised by me to find this bug, when it
was discussed by me, Brian Feldman and Robert Watson; it happened in the
MAC_DEBUG code.

Test code: http://www.unixdaemons.com/~hiten/work/misc/sysctlbug1.c
I have attached the test case, and an updated patch with this followup.

TEST CASE:
==========
%----
/*
 * Code for reproducing Sysctl (empty node) bug.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/kernel.h>
#include <sys/module.h>

static int bug_load(module_t, int, void *);

SYSCTL_DECL(_bugfoo);

SYSCTL_NODE(, 0, bugfoo, CTLFLAG_RW, 0, "Bugfoo and Family");
SYSCTL_NODE(_bugfoo, OID_AUTO, mac, CTLFLAG_RW, 0, "Bugfoo and Family");
SYSCTL_NODE(_bugfoo_mac, OID_AUTO, debug, CTLFLAG_RW, 0, "BF [1]");
SYSCTL_NODE(_bugfoo_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, "BF [2]");

static int	mac_debug_label_fallback = 0;
SYSCTL_INT(_bugfoo_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
&mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
"when label is corrupted.");

TUNABLE_INT("bugfoo.mac.debug_label_fallback", &mac_debug_label_fallback);

/* Module initialisation stuff */
static moduledata_t bugctl_mod = {
	"bugctl",
	bug_load,
	0
};

static int
bug_load(module_t mod, int cmd, void *arg)
{
    int  err = 0;

    switch (cmd) {
    case MOD_LOAD:

		printf("Sysctl Bug Manipulation\n");
		break;          /* Success*/
	    
    case MOD_UNLOAD:
	    
		break;          /* Success */
	
    default: 
	err = EINVAL;
        break;
    }

    return(err);
}

/* Now declare the module to the system */
DECLARE_MODULE(bugctl, bugctl_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
----%

UPDATED PATCH:
==============

Index: kern_sysctl.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.135
diff -u -r1.135 kern_sysctl.c
--- kern_sysctl.c	2002/10/27 07:12:34	1.135
+++ kern_sysctl.c	2002/12/03 14:51:07
@@ -538,7 +538,10 @@
 	int *next, int *len, int level, struct sysctl_oid **oidpp)
 {
 	struct sysctl_oid *oidp;
+	int i_namelen;
 
+	i_namelen = namelen ? 1 : 0;
+	
 	*len = level;
 	SLIST_FOREACH(oidp, lsp, oid_link) {
 		*next = oidp->oid_number;
@@ -585,7 +588,7 @@
 			len, level+1, oidpp))
 			return (0);
 	next:
-		namelen = 1;
+		namelen = i_namelen;
 		*len = level;
 	}
 	return 1;

Cheers.

-- 
Hiten Pandya (hiten@unixdaemons.com, hiten@uk.FreeBSD.org)
http://www.unixdaemons.com/~hiten/
Comment 3 K. Macy freebsd_committer freebsd_triage 2007-11-16 21:33:10 UTC
State Changed
From-To: feedback->closed


No longer present.