sysctl description spillover and also setting the sysctl ?

Damien Fleuriot ml at my.gd
Wed Nov 30 22:07:26 UTC 2011



On 11/30/11 7:48 PM, Jason Hellenthal wrote:
> 
> 
> On Wed, Nov 30, 2011 at 11:52:46AM -0500, John Baldwin wrote:
>> On Friday, November 25, 2011 2:36:30 am Jason Hellenthal wrote:
>>>
>>> Found a troubling result of the following and figured someone might want to 
>> take a look.
>>>
>>> Pay close attention to the output and behavior.
>>>
>>> sysctl net.inet.udp.blackhole=0
>>> sysctl net.inet.udp.blackhole
>>> sysctl -d net.inet.udp.blackhole=1
>>> sysctl net.inet.udp.blackhole
>>>
>>>
>>> Is this expected ? should it not just display the description instead of 
>> adjusting ? as well not display the description like it is adjusting the 
>> description too ?
>>
>> Hah, cute.  It should probably fail with an error if you do something like 
>> that, yes.
>>
> 
> Yeah thats what I thought about it to but the more I thought about it, if it just displayed the values changing instead of the description when =N is supplied I think that would be acceptable to. 0 -> 1 in this case. Or possibly sys.oid: 0 -> 1 # <Description> since sysctl.conf(5) also takes comments like that.
> 
> Not really thats something at the top of the list for fixes though. Low fruit. Food for thought.
>





Ok so I'm totally not a dev, don't take my findings for granted, but:



(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/src/sbin/sysctl/sysctl -d net.inet.udp.blackhole=1

Breakpoint 5, show_var (oid=0x7fffffffe1d0, nlen=4) at
/usr/src/sbin/sysctl/sysctl.c:549
549     {
(gdb) s
562             bzero(buf, BUFSIZ);
(gdb) s
563             bzero(name, BUFSIZ);
(gdb) s
564             qoid[0] = 0;
(gdb) s
565             memcpy(qoid + 2, oid, nlen * sizeof(int));
(gdb) s
567             qoid[1] = 1;
(gdb) s
568             j = sizeof(name);
(gdb) s
569             i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
(gdb) s
570             if (i || !j)
(gdb) s
573             if (Nflag) {
(gdb) s
578             if (eflag)
(gdb) s
581                     sep = ": ";
(gdb) s
583             if (dflag) {    /* just print description */
(gdb) s
584                     qoid[1] = 5;
(gdb) s
585                     j = sizeof(buf);
(gdb) s
586                     i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
(gdb) s
587                     if (!nflag)
(gdb) s
588                             printf("%s%s", name, sep);
(gdb) s
net.inet.udp.blackhole:
589                     printf("%s", buf);
(gdb) s
Do not send port unreachables for refused connects
590                   return (0);
(gdb) s
719     }


At this point, we have shown the description and should exit.

Instead, we're calling parse() again ?



(gdb) s
parse (string=0x7fffffffee07 "net.inet.udp.blackhole") at
/usr/src/sbin/sysctl/sysctl.c:299
299                     if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
(gdb) s
318                     if (!bflag)
(gdb) s
319                             printf(" -> ");
(gdb) s
 -> 320                 i = nflag;
(gdb) s
321                     nflag = 1;
(gdb) s
322                     j = show_var(mib, len);
(gdb) s


Breakpoint 5, show_var (oid=0x7fffffffe1d0, nlen=4) at
/usr/src/sbin/sysctl/sysctl.c:549
549     {
(gdb) s
562             bzero(buf, BUFSIZ);
(gdb) s
563             bzero(name, BUFSIZ);
(gdb) s
564             qoid[0] = 0;
(gdb) s
565             memcpy(qoid + 2, oid, nlen * sizeof(int));
(gdb) s
567             qoid[1] = 1;
(gdb) s
568             j = sizeof(name);
(gdb) s
569             i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
(gdb) s
570             if (i || !j)
(gdb) s
573             if (Nflag) {
(gdb) s
578             if (eflag)
(gdb) s
581                     sep = ": ";
(gdb) s
583             if (dflag) {    /* just print description */
(gdb) s
584                     qoid[1] = 5;
(gdb) s
585                     j = sizeof(buf);
(gdb) s
586                     i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
(gdb) s
587                     if (!nflag)
(gdb) s
589                     printf("%s", buf);
(gdb) s
Do not send port unreachables for refused connects
590                   return (0);
(gdb) s
719     }
(gdb) s
parse (string=0x7fffffffee07 "net.inet.udp.blackhole") at
/usr/src/sbin/sysctl/sysctl.c:323
323                     if (!j && !bflag)
(gdb) s
324                             putchar('\n');
(gdb) s
__sputc (_c=10, _p=0x80085a810) at stdio.h:457
457             if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c
!= '\n'))
(gdb) s
460                     return (__swbuf(_c, _p));
(gdb) s

461     }
(gdb) s
parse (string=0x7fffffffee07 "net.inet.udp.blackhole") at
/usr/src/sbin/sysctl/sysctl.c:325
325                     nflag = i;
(gdb) s
327     }
(gdb) s
main (argc=0, argv=0x7fffffffeb48) at /usr/src/sbin/sysctl/sysctl.c:154
154             while (argc-- > 0)
(gdb) s
156             exit(warncount);
(gdb) s

Program exited normally.





I think that the issue here is that sysctl continues being run after
displaying the description at line 588.

I would assume that upon reaching the closing hyphen at line 719 ,
sysctl would want to stop.
It was asked to show a description, it has, end of the story.


Instead, at line 590, we simply return 0, then continue running.

Perhaps we would want sysctl to exit, instead of returning 0 ?


More information about the freebsd-hackers mailing list