system/5049: ifstated crash on set-state undeclared-state

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

system/5049: ifstated crash on set-state undeclared-state

Michael Knudsen-3
>Number:         5049
>Category:       system
>Synopsis:       ifstated segfaults when set-state references an undeclared state
>Confidential:   yes
>Severity:       serious
>Priority:       low
>Responsible:    bugs
>State:          open
>Quarter:        
>Keywords:      
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 12 12:10:02 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Michael Knudsen
>Release:        3.9-current
>Organization:
net
>Environment:
       
        System      : OpenBSD 3.6
        Architecture: OpenBSD.i386
        Machine     : i386
>Description:
        ifstated will segfault when a broken configuration file
        contains a transition to an undeclared state. However, this may
        go unnoticed for a long period of time because the segfault
        doesn't happen until the transition takes place.
>How-To-Repeat:
beta# cat g.conf
if_up = "de0.link.up"

state auto {
        set-state led-off
}

state led-on {
        init {
                run "gpioctl 20 1"
        }
        if ! $if_up
                set-state led-off
}

state led-off {
        init {
                run "gpioctl 20 0"
        }
        if $if_up
                set-state led-on
}
beta# ./obj/ifstated -vdf g.conf
if_up = "de0.link.up"
ifstated: initial state: auto
ifstated: changing state to auto
ifstated: changing state to led-off
ifstated: running gpioctl 20 0
ifstated: started

ifstated: reloading config
if_up = "de0.link.up"
ifstated: initial state: auto
ifstated: changing state to auto
Segmentation fault (core dumped)
beta#
beta# cat g.conf
if_up = "de0.link.up"

state auto {
        set-state led-of
}

state led-on {
        init {
                run "gpioctl 20 1"
        }
        if ! $if_up
                set-state led-off
}

state led-off {
        init {
                run "gpioctl 20 0"
        }
        if $if_up
                set-state led-on
}
beta# ^D
>Fix:
The following diff fixes the problem by adding a check in link_states()
whether the destination state was actually found:

Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/ifstated/parse.y,v
retrieving revision 1.11
diff -u -r1.11 parse.y
--- parse.y 20 Jan 2006 00:01:20 -0000 1.11
+++ parse.y 12 Mar 2006 11:54:54 -0000
@@ -685,6 +685,7 @@
 link_states(struct ifsd_action *action)
 {
  struct ifsd_action *subaction;
+ int found = 0;
 
  switch (action->type) {
  default:
@@ -697,8 +698,14 @@
  if (strcmp(action->act.statename,
     state->name) == 0) {
  action->act.nextstate = state;
+ found++;
  break;
  }
+ }
+ if (!found) {
+ fprintf(stderr, "error: state '%s' not declared\n",
+    action->act.statename);
+ errors++;
  }
  break;
  }


>Release-Note:
>Audit-Trail:
>Unformatted: