From ccb3e316868f381831d9ddda530af83102f67697 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 15 Jul 2009 03:58:02 -0400 Subject: [PATCH] Modify Solaris Rx NetIfPoller to avoid Panic This patch changes the common error reporting type from CE_PANIC to CE_WARN and adds appropriate cleanup processing so that we do not leak resources if an error occurs. LICENSE MIT FIXES 124498 Reviewed-on: http://gerrit.openafs.org/http://gerrit.openafs.org/97 Reviewed-by: Russ Allbery Tested-by: Derrick Brashear Reviewed-by: Derrick Brashear --- src/rx/SOLARIS/rx_knet.c | 56 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/rx/SOLARIS/rx_knet.c b/src/rx/SOLARIS/rx_knet.c index 335a4aacd..46c76f07b 100644 --- a/src/rx/SOLARIS/rx_knet.c +++ b/src/rx/SOLARIS/rx_knet.c @@ -605,8 +605,8 @@ void osi_NetIfPoller() { cred_t *cr; - ldi_ident_t li; - ldi_handle_t lh; + ldi_ident_t li = NULL; + ldi_handle_t lh = NULL; struct lifnum lifn; struct lifconf lifc; struct lifreq lifr; @@ -614,7 +614,7 @@ osi_NetIfPoller() struct sockaddr_in *sin4_local; struct sockaddr_in *sin4_dst; major_t udpmajor; - caddr_t lifcbuf; + caddr_t lifcbuf = NULL; int i, count, error, rv; int ifcount; int metric; @@ -637,15 +637,18 @@ osi_NetIfPoller() udpmajor = ddi_name_to_major(UDP_MOD_NAME); error = ldi_ident_from_major(udpmajor, &li); - if (error) - cmn_err(CE_PANIC, "osi_NetIfPoller: ldi_ident_from_major failed: %d", + if (error) { + cmn_err(CE_WARN, "osi_NetIfPoller: ldi_ident_from_major failed: %d", error); + goto cleanup; + } error = ldi_open_by_name(UDP_DEV_NAME, FREAD, cr, &lh, li); - if (error) - cmn_err(CE_PANIC, + if (error) { + cmn_err(CE_WARN, "osi_NetIfPoller: ldi_open_by_name failed: %d", error); - + goto cleanup; + } /* First, how many interfaces do we have? */ (void) bzero((void *)&lifn, sizeof(struct lifnum)); @@ -653,10 +656,11 @@ osi_NetIfPoller() error = ldi_ioctl(lh, SIOCGLIFNUM, (intptr_t)&lifn, FKIOCTL, cr, &rv); - if (error) - cmn_err(CE_PANIC, - "osi_NetIfPoller: ldi_ioctl: SIOCGLIFNUM failed: %d", error); - + if (error) { + cmn_err(CE_WARN, + "osi_NetIfPoller: ldi_ioctl: SIOCGLIFNUM failed: %d", error); + goto cleanup; + } ifcount = lifn.lifn_count; /* Set up some stuff for storing the results of SIOCGLIFCONF */ @@ -672,10 +676,11 @@ osi_NetIfPoller() /* Get info on each of our available interfaces. */ error = ldi_ioctl(lh, SIOCGLIFCONF, (intptr_t)&lifc, FKIOCTL, cr, &rv); - if (error) - cmn_err(CE_PANIC, - "osi_NetIfPoller: ldi_ioctl: SIOCGLIFCONF failed: %d", error); - + if (error) { + cmn_err(CE_WARN, + "osi_NetIfPoller: ldi_ioctl: SIOCGLIFCONF failed: %d", error); + goto cleanup; + } lifrp = lifc.lifc_req; count = 0; @@ -695,10 +700,12 @@ osi_NetIfPoller() /* Get this interface's Flags */ error = ldi_ioctl(lh, SIOCGLIFFLAGS, (intptr_t)&lifr, FKIOCTL, cr, &rv); - if (error) - cmn_err(CE_PANIC, - "osi_NetIfPoller: ldi_ioctl: SIOCGLIFFLAGS failed: %d", + if (error) { + cmn_err(CE_WARN, + "osi_NetIfPoller: ldi_ioctl: SIOCGLIFFLAGS failed: %d", error); + goto cleanup; + } /* Ignore plumbed but down interfaces. */ if ((lifr.lifr_flags & IFF_UP) == 0) @@ -749,11 +756,14 @@ osi_NetIfPoller() } /* Bottom of loop: for each interface ... */ - kmem_free(lifcbuf, ifcount * sizeof(struct lifreq)); - + cleanup: /* End of thread. Time to clean up */ - (void) ldi_close(lh, FREAD, cr); - (void) ldi_ident_release(li); + if (lifcbuf) + kmem_free(lifcbuf, ifcount * sizeof(struct lifreq)); + if (lh) + (void) ldi_close(lh, FREAD, cr); + if (li) + (void) ldi_ident_release(li); /* Schedule this to run again after afs_if_poll_interval seconds */ (void) timeout((void(*) (void *)) osi_StartNetIfPoller, NULL, -- 2.39.5