tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

locking errors in IPF in netbsd-6



recently I had occasion to run "ipfstat -f" (which I had never run before)
on a netbsd-6 system, and it immediately rebooted.  no dump device configured, 
alas.

I tried it again later on a test system and ipfstat hung instead:

db{0}> t/a  fffffe8429568680
trace: pid 328 lid 1 at 0xfffffe811e2e4d00
sleepq_block() at netbsd:sleepq_block+0xad
turnstile_block() at netbsd:turnstile_block+0x2bb
rw_vector_enter() at netbsd:rw_vector_enter+0x1eb
ipf_findtoken() at netbsd:ipf_findtoken+0x44
fr_nat_ioctl() at netbsd:fr_nat_ioctl+0x4a3
cdev_ioctl() at netbsd:cdev_ioctl+0x77
VOP_IOCTL() at netbsd:VOP_IOCTL+0x3b
vn_ioctl() at netbsd:vn_ioctl+0x76
sys_ioctl() at netbsd:sys_ioctl+0x13c
syscall() at netbsd:syscall+0xc4


there are some obvious locking problems to do with "ipf_tokens"
in the version of IPF in the 6.x branch, this lock can be unlocked
when it's not held.  does the attached patch look correct?

(the more recent version of IPF in -current doesn't have these problems)

-Chuck
Index: src/sys/dist/ipf/netinet/fil.c
===================================================================
RCS file: /home/chs/netbsd/cvs/src/sys/dist/ipf/netinet/Attic/fil.c,v
retrieving revision 1.53
diff -u -p -r1.53 fil.c
--- src/sys/dist/ipf/netinet/fil.c      15 Feb 2012 17:55:21 -0000      1.53
+++ src/sys/dist/ipf/netinet/fil.c      3 Mar 2013 21:50:39 -0000
@@ -6617,9 +6617,6 @@ ipf_deltoken(int type, int uid, void *pt
 /* matches the tuple (type, uid, ptr).  If one cannot be found then one is  */
 /* allocated.  If one is found then it is moved to the top of the list of   */
 /* currently active tokens.                                                 */
-/*                                                                          */
-/* NOTE: It is by design that this function returns holding a read lock on  */
-/*       ipf_tokens.  Callers must make sure they release it!               */
 /* ------------------------------------------------------------------------ */
 ipftoken_t *
 ipf_findtoken(int type, int uid, void *ptr)
@@ -6638,8 +6635,10 @@ ipf_findtoken(int type, int uid, void *p
        if (it == NULL) {
                it = new;
                new = NULL;
-               if (it == NULL)
+               if (it == NULL) {
+                       RWLOCK_EXIT(&ipf_tokens);
                        return NULL;
+               }
                it->ipt_data = NULL;
                it->ipt_ctx = ptr;
                it->ipt_uid = uid;
@@ -7014,7 +7013,6 @@ ipf_genericiter(void *data, int uid, voi
                RWLOCK_EXIT(&ipf_tokens);
        } else
                error = EFAULT;
-       RWLOCK_EXIT(&ipf_tokens);
 
        return error;
 }
Index: src/sys/dist/ipf/netinet/ip_lookup.c
===================================================================
RCS file: /home/chs/netbsd/cvs/src/sys/dist/ipf/netinet/Attic/ip_lookup.c,v
retrieving revision 1.19
diff -u -p -r1.19 ip_lookup.c
--- src/sys/dist/ipf/netinet/ip_lookup.c        15 Feb 2012 17:55:22 -0000      
1.19
+++ src/sys/dist/ipf/netinet/ip_lookup.c        3 Mar 2013 19:31:43 -0000
@@ -612,7 +612,6 @@ iplookup_iterate(void *data, int uid, vo
        SPL_SCHED(s);
        token = ipf_findtoken(iter.ili_key, uid, ctx);
        if (token == NULL) {
-               RWLOCK_EXIT(&ipf_tokens);
                SPL_X(s);
                return ESRCH;
        }


Home | Main Index | Thread Index | Old Index