diff --git a/sys/netcan/can.c b/sys/netcan/can.c index bd8547000491..4e9ef7ce0020 100644 --- a/sys/netcan/can.c +++ b/sys/netcan/can.c @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.6 2018/11/15 10:23:56 maxv Exp $ */ +/* $NetBSD: can.c,v 1.7 2019/07/20 15:34:41 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.6 2018/11/15 10:23:56 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.7 2019/07/20 15:34:41 bouyer Exp $"); #include #include @@ -924,9 +924,7 @@ can_raw_setop(struct canpcb *canp, struct sockopt *sopt) int nfilters = sopt->sopt_size / sizeof(struct can_filter); if (sopt->sopt_size % sizeof(struct can_filter) != 0) return EINVAL; - mutex_enter(&canp->canp_mtx); error = can_pcbsetfilter(canp, sopt->sopt_data, nfilters); - mutex_exit(&canp->canp_mtx); break; } default: diff --git a/sys/netcan/can_pcb.c b/sys/netcan/can_pcb.c index 21e05c3a7fbd..b797ccdfac8d 100644 --- a/sys/netcan/can_pcb.c +++ b/sys/netcan/can_pcb.c @@ -1,4 +1,4 @@ -/* $NetBSD: can_pcb.c,v 1.7 2019/02/25 06:49:44 maxv Exp $ */ +/* $NetBSD: can_pcb.c,v 1.8 2019/07/20 15:34:41 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.7 2019/02/25 06:49:44 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.8 2019/07/20 15:34:41 bouyer Exp $"); #include #include @@ -193,8 +193,8 @@ can_pcbdetach(void *v) so->so_pcb = NULL; mutex_enter(&canp->canp_mtx); can_pcbstate(canp, CANP_DETACHED); - can_pcbsetfilter(canp, NULL, 0); mutex_exit(&canp->canp_mtx); + can_pcbsetfilter(canp, NULL, 0); TAILQ_REMOVE(&canp->canp_table->canpt_queue, canp, canp_queue); sofree(so); /* sofree drops the softnet_lock */ canp_unref(canp); @@ -243,7 +243,9 @@ can_pcbsetfilter(struct canpcb *canp, struct can_filter *fp, int nfilters) { struct can_filter *newf; - KASSERT(mutex_owned(&canp->canp_mtx)); + struct can_filter *oldf; + int oldnf; + int error = 0; if (nfilters > 0) { newf = @@ -252,13 +254,24 @@ can_pcbsetfilter(struct canpcb *canp, struct can_filter *fp, int nfilters) } else { newf = NULL; } - if (canp->canp_filters != NULL) { - kmem_free(canp->canp_filters, - sizeof(struct can_filter) * canp->canp_nfilters); + mutex_enter(&canp->canp_mtx); + oldf = canp->canp_filters; + oldnf = canp->canp_nfilters; + if (newf != NULL && canp->canp_state == CANP_DETACHED) { + error = ECONNRESET; + } else { + canp->canp_filters = newf; + canp->canp_nfilters = nfilters; + newf = NULL; } - canp->canp_filters = newf; - canp->canp_nfilters = nfilters; - return 0; + mutex_exit(&canp->canp_mtx); + if (oldf != NULL) { + kmem_free(oldf, sizeof(struct can_filter) * oldnf); + } + if (newf != NULL) { + kmem_free(newf, sizeof(struct can_filter) * nfilters); + } + return error; }