File: 0015-CVE-2023-40477.patch

package info (click to toggle)
unrar-nonfree 1%3A6.2.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: non-free
  • in suites: bookworm
  • size: 1,976 kB
  • sloc: cpp: 28,439; makefile: 712; sh: 11
file content (106 lines) | stat: -rw-r--r-- 3,727 bytes parent folder | download
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
From: YOKOTA Hiroshi <yokota.hgml@gmail.com>
Date: Fri, 21 Jul 2023 00:33:42 +0900
Subject: CVE-2023-40477

---
 getbits.cpp     |  8 ++++----
 pathfn.cpp      |  2 +-
 recvol3.cpp     | 11 +++++++++--
 secpassword.cpp |  8 ++++----
 4 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/getbits.cpp b/getbits.cpp
index 8805f27..5d5ad2b 100644
--- a/getbits.cpp
+++ b/getbits.cpp
@@ -5,11 +5,11 @@ BitInput::BitInput(bool AllocBuffer)
   ExternalBuffer=false;
   if (AllocBuffer)
   {
-    // getbits*() attempt to read data from InAddr, ... InAddr+3 positions.
-    // So let's allocate 3 additional bytes for situation, when we need to
+    // getbits*() attempt to read data from InAddr, ... InAddr+4 positions.
+    // So let's allocate 4 additional bytes for situation, when we need to
     // read only 1 byte from the last position of buffer and avoid a crash
-    // from access to next 3 bytes, which contents we do not need.
-    size_t BufSize=MAX_SIZE+3;
+    // from access to next 4 bytes, which contents we do not need.
+    size_t BufSize=MAX_SIZE+4;
     InBuf=new byte[BufSize];
 
     // Ensure that we get predictable results when accessing bytes in area
diff --git a/pathfn.cpp b/pathfn.cpp
index 49d16a8..7a54354 100644
--- a/pathfn.cpp
+++ b/pathfn.cpp
@@ -746,7 +746,7 @@ static void GenArcName(wchar *ArcName,size_t MaxSize,const wchar *GenerateMask,u
       // Here we ensure that we have enough 'N' characters to fit all digits
       // of archive number. We'll replace them by actual number later
       // in this function.
-      if (NCount<Digits)
+      if (NCount<Digits && wcslen(Mask)+Digits-NCount<ASIZE(Mask))
       {
         wmemmove(Mask+I+Digits,Mask+I+NCount,wcslen(Mask+I+NCount)+1);
         wmemset(Mask+I,'N',Digits);
diff --git a/recvol3.cpp b/recvol3.cpp
index ecf6dd3..0138d0f 100644
--- a/recvol3.cpp
+++ b/recvol3.cpp
@@ -226,7 +226,7 @@ bool RecVolumes3::Restore(CommandData *Cmd,const wchar *Name,bool Silent)
       if (WrongParam)
         continue;
     }
-    if (P[1]+P[2]>255)
+    if (P[0]<=0 || P[1]<=0 || P[2]<=0 || P[1]+P[2]>255 || P[0]+P[2]-1>255)
       continue;
     if (RecVolNumber!=0 && RecVolNumber!=P[1] || FileNumber!=0 && FileNumber!=P[2])
     {
@@ -238,7 +238,14 @@ bool RecVolumes3::Restore(CommandData *Cmd,const wchar *Name,bool Silent)
     wcsncpyz(PrevName,CurName,ASIZE(PrevName));
     File *NewFile=new File;
     NewFile->TOpen(CurName);
-    SrcFile[FileNumber+P[0]-1]=NewFile;
+
+    // This check is redundant taking into account P[I]>255 and P[0]+P[2]-1>255
+    // checks above. Still we keep it here for better clarity and security.
+    int SrcPos=FileNumber+P[0]-1;
+    if (SrcPos<0 || SrcPos>=ASIZE(SrcFile))
+      continue;
+    SrcFile[SrcPos]=NewFile;
+
     FoundRecVolumes++;
 
     if (RecFileSize==0)
diff --git a/secpassword.cpp b/secpassword.cpp
index 42ed47d..08da549 100644
--- a/secpassword.cpp
+++ b/secpassword.cpp
@@ -70,7 +70,7 @@ void SecPassword::Clean()
 {
   PasswordSet=false;
   if (Password.size()>0)
-    cleandata(&Password[0],Password.size());
+    cleandata(&Password[0],Password.size()*sizeof(Password[0]));
 }
  
 
@@ -141,7 +141,7 @@ size_t SecPassword::Length()
   wchar Plain[MAXPASSWORD];
   Get(Plain,ASIZE(Plain));
   size_t Length=wcslen(Plain);
-  cleandata(Plain,ASIZE(Plain));
+  cleandata(Plain,sizeof(Plain));
   return Length;
 }
 
@@ -156,8 +156,8 @@ bool SecPassword::operator == (SecPassword &psw)
   Get(Plain1,ASIZE(Plain1));
   psw.Get(Plain2,ASIZE(Plain2));
   bool Result=wcscmp(Plain1,Plain2)==0;
-  cleandata(Plain1,ASIZE(Plain1));
-  cleandata(Plain2,ASIZE(Plain2));
+  cleandata(Plain1,sizeof(Plain1));
+  cleandata(Plain2,sizeof(Plain2));
   return Result;
 }