summaryrefslogtreecommitdiff
blob: a643f1cb82f6ac09916b13749cfd0f663a6ad7b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
Patches taken as references: 
https://github.com/mark4o/opus-tools/commit/8c412e619b83eb6dd32191909cf6672e93e5802e
https://trac.xiph.org/attachment/ticket/2212/0001-oggenc-Fix-large-alloca-on-bad-AIFF-input.patch
To fix bug report:
http://www.openwall.com/lists/oss-security/2015/08/29/1
    https://bugs.gentoo.org/show_bug.cgi?id=559170
https://bugs.gentoo.org/show_bug.cgi?id=537422
--- a/oggenc/audio.h
+++ b/oggenc/audio.h
@@ -25,7 +25,7 @@
 
 typedef struct {
     short format;
-    short channels;
+    unsigned short channels;
     int samplerate;
     int bytespersec;
     short align;
@@ -44,7 +44,7 @@
 } wavfile;
 
 typedef struct {
-    short channels;
+    unsigned short channels;
     int totalframes;
     short samplesize;
     int rate;
--- a/oggenc/audio.c
+++ b/oggenc/audio.c
@@ -245,8 +245,8 @@
 int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen)
 {
     int aifc; /* AIFC or AIFF? */
-    unsigned int len;
-    unsigned char *buffer;
+    unsigned int len,readlen;
+    unsigned char buffer[22];
     unsigned char buf2[8];
     aiff_fmt format;
     aifffile *aiff = malloc(sizeof(aifffile));
@@ -269,9 +269,9 @@
         return 0; /* Weird common chunk */
     }

-    buffer = alloca(len);
-
-    if(fread(buffer,1,len,in) < len)
+    readlen = len < sizeof(buffer) ? len : sizeof(buffer);
+    if(fread(buffer,1,readlen,in) < readlen ||
+        (len > readlen && !seek_forward(in, len-readlen)))
     {
         fprintf(stderr, _("Warning: Unexpected EOF in reading AIFF header\n"));
         return 0;
@@ -277,11 +277,18 @@
         return 0;
     }
 
-    format.channels = READ_U16_BE(buffer);
+    format.channels = (short)READ_U16_BE(buffer);
     format.totalframes = READ_U32_BE(buffer+2);
     format.samplesize = READ_U16_BE(buffer+6);
     format.rate = (int)read_IEEE80(buffer+8);
 
+    if(format.channels <=0)
+    {
+    	fprintf(stderr, _("ERROR: Invalid channel count in AIFF header\n"));
+	return 0;
+
+    }
+
     aiff->bigendian = 1;
 
     if(aifc)
@@ -449,11 +449,17 @@
     }

     format.format =      READ_U16_LE(buf);
-    format.channels =    READ_U16_LE(buf+2);
+    format.channels =    (short)READ_U16_LE(buf+2);
     format.samplerate =  READ_U32_LE(buf+4);
     format.bytespersec = READ_U32_LE(buf+8);
     format.align =       READ_U16_LE(buf+12);
     format.samplesize =  READ_U16_LE(buf+14);
+
+    if(format.channels == 0)
+    {
+      fprintf(stderr, _("ERROR: Zero channels in WAV header\n"));
+      return 0;
+    }

     if(format.format == -2) /* WAVE_FORMAT_EXTENSIBLE */
     {