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;
}
|