diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2015-05-18 22:21:16 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2015-05-18 22:21:16 +0000 |
commit | 8a374c39a832fd0519e33614ee2a2a7ac55b45e0 (patch) | |
tree | e218b60d3ace47cc06b1669c39a809fd8f8575f5 /usr/src | |
parent | a0bf79e3491312031d4ee3ae93520518d3c1372b (diff) | |
download | illumos-joyent-8a374c39a832fd0519e33614ee2a2a7ac55b45e0.tar.gz |
OS-4283 SegFault upon invoking lx_select
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/poll_select.c | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/poll_select.c b/usr/src/lib/brand/lx/lx_brand/common/poll_select.c index 1dce9b278d..64adedf6ab 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/poll_select.c +++ b/usr/src/lib/brand/lx/lx_brand/common/poll_select.c @@ -64,37 +64,52 @@ lx_select(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, struct timeval tv, *tvp = NULL; int fd_set_len = howmany(nfds, 8); int r; + int res; hrtime_t start = NULL, end; lx_debug("\tselect(%d, 0x%p, 0x%p, 0x%p, 0x%p)", p1, p2, p3, p4, p5); if (nfds > 0) { if (p2 != NULL) { - rfdsp = alloca(fd_set_len); - if (rfdsp == NULL) - return (-ENOMEM); - if (uucopy((void *)p2, rfdsp, fd_set_len) != 0) - return (-errno); + rfdsp = malloc(fd_set_len); + if (rfdsp == NULL) { + res = -ENOMEM; + goto err; + } + if (uucopy((void *)p2, rfdsp, fd_set_len) != 0) { + res = -errno; + goto err; + } } if (p3 != NULL) { - wfdsp = alloca(fd_set_len); - if (wfdsp == NULL) - return (-ENOMEM); - if (uucopy((void *)p3, wfdsp, fd_set_len) != 0) - return (-errno); + wfdsp = malloc(fd_set_len); + if (wfdsp == NULL) { + res = -ENOMEM; + goto err; + } + if (uucopy((void *)p3, wfdsp, fd_set_len) != 0) { + res = -errno; + goto err; + } } if (p4 != NULL) { - efdsp = alloca(fd_set_len); - if (efdsp == NULL) - return (-ENOMEM); - if (uucopy((void *)p4, efdsp, fd_set_len) != 0) - return (-errno); + efdsp = malloc(fd_set_len); + if (efdsp == NULL) { + res = -ENOMEM; + goto err; + } + if (uucopy((void *)p4, efdsp, fd_set_len) != 0) { + res = -errno; + goto err; + } } } if (p5 != NULL) { tvp = &tv; - if (uucopy((void *)p5, &tv, sizeof (tv)) != 0) - return (-errno); + if (uucopy((void *)p5, &tv, sizeof (tv)) != 0) { + res = -errno; + goto err; + } start = gethrtime(); } @@ -106,8 +121,10 @@ lx_select(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, else r = select(nfds, rfdsp, wfdsp, efdsp, tvp); #endif - if (r < 0) - return (-errno); + if (r < 0) { + res = -errno; + goto err; + } if (tvp != NULL) { long long tv_total; @@ -128,18 +145,35 @@ lx_select(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, tv.tv_usec = tv_total % MICROSEC; } - if (uucopy(&tv, (void *)p5, sizeof (tv)) != 0) - return (-errno); + if (uucopy(&tv, (void *)p5, sizeof (tv)) != 0) { + res = -errno; + goto err; + } } - if ((rfdsp != NULL) && (uucopy(rfdsp, (void *)p2, fd_set_len) != 0)) - return (-errno); - if ((wfdsp != NULL) && (uucopy(wfdsp, (void *)p3, fd_set_len) != 0)) - return (-errno); - if ((efdsp != NULL) && (uucopy(efdsp, (void *)p4, fd_set_len) != 0)) - return (-errno); + if ((rfdsp != NULL) && (uucopy(rfdsp, (void *)p2, fd_set_len) != 0)) { + res = -errno; + goto err; + } + if ((wfdsp != NULL) && (uucopy(wfdsp, (void *)p3, fd_set_len) != 0)) { + res = -errno; + goto err; + } + if ((efdsp != NULL) && (uucopy(efdsp, (void *)p4, fd_set_len) != 0)) { + res = -errno; + goto err; + } + + res = r; - return (r); +err: + if (rfdsp != NULL) + free(rfdsp); + if (wfdsp != NULL) + free(wfdsp); + if (efdsp != NULL) + free(efdsp); + return (res); } long |