diff options
author | Raimo Niskanen <[email protected]> | 2012-01-04 17:24:04 +0100 |
---|---|---|
committer | Raimo Niskanen <[email protected]> | 2012-01-09 18:35:11 +0100 |
commit | 308721c56345aa6ee0d81d891f036b59541f3cc6 (patch) | |
tree | fef4dcc85bc51f2bc5976a2e9b9eed0cfbc397ff /erts | |
parent | 4e0e77ea852ae9bd63308b37feb4ad72246a8932 (diff) | |
download | otp-308721c56345aa6ee0d81d891f036b59541f3cc6.tar.gz otp-308721c56345aa6ee0d81d891f036b59541f3cc6.tar.bz2 otp-308721c56345aa6ee0d81d891f036b59541f3cc6.zip |
erts: Badarg if port output overflows iov_len
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/io.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 6b89fc32e9..b23b1f628d 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2011. All Rights Reserved. + * Copyright Ericsson AB 1996-2012. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -818,6 +818,11 @@ erts_smp_xports_unlock(Port *prt) #define SET_VEC(iov, bv, bin, ptr, len, vlen) do { \ (iov)->iov_base = (ptr); \ (iov)->iov_len = (len); \ + if (sizeof((iov)->iov_len) < sizeof(len) \ + /* Check if (len) overflowed (iov)->iov_len */ \ + && ((len) >> (sizeof((iov)->iov_len)*CHAR_BIT)) != 0) { \ + goto L_overflow; \ + } \ *(bv)++ = (bin); \ (iov)++; \ (vlen)++; \ @@ -1146,11 +1151,21 @@ int erts_write_to_port(Eterm caller_id, Port *p, Eterm list) ivp[0].iov_len = 0; bvp[0] = NULL; ev.vsize = io_list_to_vec(list, ivp+1, bvp+1, cbin, blimit); + if (ev.vsize < 0) { + if (ivp != iv) { + erts_free(ERTS_ALC_T_TMP, (void *) ivp); + } + if (bvp != bv) { + erts_free(ERTS_ALC_T_TMP, (void *) bvp); + } + driver_free_binary(cbin); + goto bad_value; + } ev.vsize++; #if 0 /* This assertion may say something useful, but it can be falsified during the emulator test suites. */ - ASSERT((ev.vsize >= 0) && (ev.vsize == vsize)); + ASSERT(ev.vsize == vsize); #endif ev.size = size; /* total size */ ev.iov = ivp; |