]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix a variety of potential buffer overflows
authorMatthew Jordan <mjordan@digium.com>
Thu, 19 Apr 2012 02:27:08 +0000 (02:27 +0000)
committerMatthew Jordan <mjordan@digium.com>
Thu, 19 Apr 2012 02:27:08 +0000 (02:27 +0000)
* chan_mobile: Fixed an overrun where the cind_state buffer (an integer array
  of size 16) would be overrun due to improper bounds checking. At worst, the
  buffer can be overrun by a total of 48 bytes (assuming 4-byte integers),
  which would still leave it within the allocated memory of struct hfp.  This
  would corrupt other elements in that struct but not necessarily cause any
  further issues.

* app_sms: The array imsg is of size 250, while the array (ud) that the data
  is copied into is of size 160.  If the size of the inbound message is
  greater then 160, up to 90 bytes could be overrun in ud.  This would corrupt
  the user data header (array udh) adjacent to ud.

* chan_unistim: A number of invalid memmoves are corrected.  These would move
  data (which may or may not be valid) into the ends of these buffers.

* asterisk: ast_console_toggle_loglevel does not check that the console log
  level being set is less then or equal to the allowed log levels of 32.

* format_pref: In ast_codec_pref_prepend, if any occurrence of the specified
  codec is not found, the value used to index into the array pref->order
  would be one greater then the maximum size of the array.

* jitterbuf: If the element being placed into the jitter buffer lands in the
  last available slot in the jitter history buffer, the insertion sort attempts
  to move the last entry in the buffer into one slot past the maximum length
  of the buffer.  Note that this occurred for both the min and max jitter
  history buffers.

* tdd: If a read from fsk_serial returns a character that is greater then 32,
  an attempt to read past one of the statically defined arrays containing the
  values that character maps to would occur.

* localtime: struct ast_time and tm are not the same size - ast_time is larger,
  although it contains the elements of tm within it in the same layout.  Hence,
  when using memcpy to copy the contents of tm into ast_time, the size of tm
  should be used, as opposed to the size of ast_time.

* extconf: this treats ast_timing's minmask array as if it had a length of 48,
  when it has defined the size of the array as 24.  pbx.h defines minmask as
  having a size of 48.

(issue ASTERISK-19668)
Reported by: Matt Jordan
........

Merged revisions 362485 from http://svn.asterisk.org/svn/asterisk/branches/1.8

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@362496 65c4cc65-6c06-0410-ace0-fbb531ad65f3

addons/chan_mobile.c
apps/app_sms.c
channels/chan_unistim.c
main/asterisk.c
main/format_pref.c
main/jitterbuf.c
main/stdtime/localtime.c
main/tdd.c
utils/extconf.c

index ee560a6058e671664c3e04c74a4481ff3cea05d9..e03e8647e05cd8533c564118af20bd507c85e4d5 100644 (file)
@@ -2120,7 +2120,7 @@ static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value)
                return HFP_CIND_NONE;
        }
 
-       if (i >= sizeof(hfp->cind_state)) {
+       if (i >= ARRAY_LEN(hfp->cind_state)) {
                ast_debug(2, "[%s] CIEV event index too high (%s)\n", hfp->owner->id, buf);
                return HFP_CIND_NONE;
        }
@@ -2602,7 +2602,7 @@ static int hfp_parse_cind_indicator(struct hfp_pvt *hfp, int group, char *indica
        int value;
 
        /* store the current indicator */
-       if (group >= sizeof(hfp->cind_state)) {
+       if (group >= ARRAY_LEN(hfp->cind_state)) {
                ast_debug(1, "ignoring CIND state '%s' for group %d, we only support up to %d indicators\n", indicator, group, (int) sizeof(hfp->cind_state));
                return -1;
        }
index d216932a6a6badc06bd9785f7872b8a51c30f9c3..8ce251cba2a6a0767066c81cf7683a157062cbc8 100644 (file)
@@ -1269,8 +1269,8 @@ static int sms_handleincoming_proto2(sms_t *h)
                switch (msg) {
                case 0x13:                          /* Body */
                        ast_verb(3, "SMS-P2 Body#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
-                       if (msgsz >= sizeof(h->imsg)) {
-                               msgsz = sizeof(h->imsg) - 1;
+                       if (msgsz >= sizeof(h->ud)) {
+                               msgsz = sizeof(h->ud) - 1;
                        }
                        for (i = 0; i < msgsz; i++) {
                                h->ud[i] = h->imsg[f + i];
index b748b2b8571afdc9062cbab1a6517f0c229aacb0..4d9e2bbfada1bd4a022ce78630a235b5384b810c 100644 (file)
@@ -3248,7 +3248,7 @@ static void key_main_page(struct unistimsession *pte, char keycode)
                if (!ast_strlen_zero(pte->device->call_forward)) {
                        /* Cancel call forwarding */
                        memmove(pte->device->call_forward + 1, pte->device->call_forward,
-                                       sizeof(pte->device->call_forward));
+                                       sizeof(pte->device->call_forward) - 1);
                        pte->device->call_forward[0] = '\0';
                        Sendicon(TEXT_LINE0, FAV_ICON_NONE, pte);
                        pte->device->output = OUTPUT_HANDSET;   /* Seems to be reseted somewhere */
@@ -5032,7 +5032,7 @@ static int ParseBookmark(const char *text, struct unistim_device *d)
                        ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used\n:", p);
                        return 0;
                }
-               memmove(line, line + 2, sizeof(line));
+               memmove(line, line + 2, sizeof(line) - 2);
        } else {
                /* No position specified, looking for a free slot */
                for (p = 0; p <= 5; p++) {
index 9b1a2b93cfc085bcd49572770fcb6036c4076fb9..8018c9b34961de8f2ac46d4370399eafe5120f49 100644 (file)
@@ -1104,6 +1104,11 @@ int ast_safe_system(const char *s)
 void ast_console_toggle_loglevel(int fd, int level, int state)
 {
        int x;
+
+       if (level >= NUMLOGLEVELS) {
+               level = NUMLOGLEVELS - 1;
+       }
+
        for (x = 0;x < AST_MAX_CONNECTS; x++) {
                if (fd == consoles[x].fd) {
                        /*
index 48fac7731ddf7bf62ea4c8b6dceddaa392538afe..11308e1e01d557e962d4a8d71d1194ec35c85bf1 100644 (file)
@@ -195,6 +195,11 @@ void ast_codec_pref_prepend(struct ast_codec_pref *pref, struct ast_format *form
                        break;
        }
 
+       /* If we failed to find any occurrence, set to the end */
+       if (x == AST_CODEC_PREF_SIZE) {
+               --x;
+       }
+
        if (only_if_existing && !pref->order[x]) {
                ast_format_list_destroy(f_list);
                return;
index a49d04e64ec75709b8dc3067eec8fbb25b776898..40bbb554c6796cad63b48e72d813abc3af56008f 100644 (file)
@@ -242,7 +242,9 @@ static void history_calc_maxbuf(jitterbuf *jb)
                                /* found where it fits */
                                if (toins > jb->hist_maxbuf[j]) {
                                        /* move over */
-                                       memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
+                                       if (j != JB_HISTORY_MAXBUF_SZ - 1) {
+                                               memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
+                                       }
                                        /* insert */
                                        jb->hist_maxbuf[j] = toins;
 
@@ -259,7 +261,9 @@ static void history_calc_maxbuf(jitterbuf *jb)
                                /* found where it fits */
                                if (toins < jb->hist_minbuf[j]) {
                                        /* move over */
-                                       memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
+                                       if (j != JB_HISTORY_MAXBUF_SZ - 1) {
+                                               memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
+                                       }
                                        /* insert */
                                        jb->hist_minbuf[j] = toins;
 
index 4e0fd760c990edfe0832f78d4581c74713161cda..bbbb5dbfdce05cb6d6b5645efccc2baaf37411c3 100644 (file)
@@ -2339,7 +2339,11 @@ char *ast_strptime_locale(const char *s, const char *format, struct ast_tm *tm,
        prevlocale = ast_setlocale(locale);
        res = strptime(s, format, &tm2);
        ast_setlocale(prevlocale);
-       memcpy(tm, &tm2, sizeof(*tm));
+       /* ast_time and tm are not the same size - tm is a subset of
+        * ast_time.  Hence, the size of tm needs to be used for the
+        * memcpy
+        */
+       memcpy(tm, &tm2, sizeof(tm2));
        tm->tm_usec = 0;
        /* strptime(3) doesn't set .tm_isdst correctly, so to force ast_mktime(3)
         * to deal with it correctly, we set it to -1. */
index 2ae80a3bec0b25de609334a77fb352e6bad76fef..d0334d1db41f4121673a1817df6fb998c281f8bf 100644 (file)
@@ -69,19 +69,21 @@ static int tdd_decode_baudot(struct tdd_state *tdd,unsigned char data)      /* covert
                                 '5','\"',')','2','=','6','0','1',
                                 '9','?','+','^','.','/',';','^' };
        int d = 0;  /* return 0 if not decodeable */
-       switch (data) {
-       case 0x1f:
-               tdd->modo = 0;
-               break;
-       case 0x1b:
-               tdd->modo = 1;
-               break;
-       default:
-               if (tdd->modo == 0)
-                       d = ltrs[data];
-               else
-                       d = figs[data];
-               break;
+       if (data < 32) {
+               switch (data) {
+               case 0x1f:
+                       tdd->modo = 0;
+                       break;
+               case 0x1b:
+                       tdd->modo = 1;
+                       break;
+               default:
+                       if (tdd->modo == 0)
+                               d = ltrs[data];
+                       else
+                               d = figs[data];
+                       break;
+               }
        }
        return d;
 }
index 20b2e5b2a1944e690d5774bd5cdc591bb13309a8..8245a161f1606e159858e3a3a8d39d2e8f2aedd6 100644 (file)
@@ -2910,7 +2910,7 @@ struct ast_timing {
        unsigned int monthmask;                 /*!< Mask for month */
        unsigned int daymask;                   /*!< Mask for date */
        unsigned int dowmask;                   /*!< Mask for day of week (mon-sun) */
-       unsigned int minmask[24];               /*!< Mask for minute */
+       unsigned int minmask[48];               /*!< Mask for minute */
        char *timezone;                 /*!< NULL, or zoneinfo style timezone */
 };
 /* end of pbx.h */