Group :: Archiving/Compression
RPM: unace
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: 003_security.patch
Download
Download
Description: Fix compilations warnings
Author: Ulf Härnhammar <Ulf.Harnhammar.9485@student.uu.se>
Origin: vendor
Forwarded: no
Index: b/uac_crt.c
===================================================================
--- a/uac_crt.c
+++ b/uac_crt.c
@@ -35,12 +35,15 @@
/* gets file name from header
*/
-CHAR *ace_fname(CHAR * s, thead * head, INT nopath)
+CHAR *ace_fname(CHAR * s, thead * head, INT nopath, unsigned int size)
{
- INT i;
+ unsigned int i;
char *cp;
- strncpy(s, (*(tfhead *) head).FNAME, i = (*(tfhead *) head).FNAME_SIZE);
+ i = (*(tfhead *) head).FNAME_SIZE;
+ if (i > (size - 1))
+ i = size - 1;
+ strncpy(s, (*(tfhead *) head).FNAME, i);
s[i] = 0;
if (nopath)
@@ -58,22 +61,73 @@ CHAR *ace_fname(CHAR * s, thead * head,
}
#endif
+ cp = s;
+ while (*cp == '/') cp++;
+ if (cp != s)
+ memmove(s, cp, strlen(cp) + 1);
+
return s;
}
+int is_directory_traversal(char *str)
+{
+ unsigned int mode, countdots;
+ /* mode 0 = fresh, 1 = just dots, 2 = not just dots */
+
+ mode = countdots = 0;
+
+ while (*str)
+ {
+ char ch = *str++;
+
+ if ((ch == '/') && (mode == 1) && (countdots > 1))
+ return 1;
+
+ if (ch == '/')
+ {
+ mode = countdots = 0;
+ continue;
+ }
+
+ if (ch == '.')
+ {
+ if (mode == 0)
+ mode = 1;
+
+ countdots++;
+ }
+ else
+ mode = 2;
+ }
+
+ if ((mode == 1) && (countdots > 1))
+ return 1;
+
+ return 0;
+}
+
void check_ext_dir(CHAR * f) // checks/creates path of file
{
CHAR *cp,
d[PATH_MAX];
- INT i;
+ unsigned int i;
d[0] = 0;
+ if (is_directory_traversal(f))
+ {
+ f_err = ERR_WRITE;
+ printf("\n Directory traversal attempt: %s\n", f);
+ return;
+ }
+
for (;;)
{
if ((cp = (CHAR *) strchr(&f[strlen(d) + 1], DIRSEP))!=NULL)
{
i = cp - f;
+ if (i > (PATH_MAX - 1))
+ i = PATH_MAX - 1;
strncpy(d, f, i);
d[i] = 0;
}
Index: b/uac_crt.h
===================================================================
--- a/uac_crt.h
+++ b/uac_crt.h
@@ -8,7 +8,7 @@
#include "acestruc.h"
-CHAR *ace_fname(CHAR * s, thead * head, INT nopath);
+CHAR *ace_fname(CHAR * s, thead * head, INT nopath, unsigned int size);
INT create_dest_file(CHAR * file, INT a);
#ifdef UNIX
Index: b/unace.c
===================================================================
--- a/unace.c
+++ b/unace.c
@@ -242,6 +242,7 @@ INT read_arc_head(void) // searc
INT open_archive(INT print_err) // opens archive (or volume)
{
CHAR av_str[80];
+ unsigned int copylen;
archan = open(aname, O_RDONLY | O_BINARY); // open file
@@ -265,8 +266,11 @@ INT open_archive(INT print_err)
sprintf(av_str, "\ncreated on %d.%d.%d by ",
ts_day(adat.time_cr), ts_month(adat.time_cr), ts_year(adat.time_cr));
printf(av_str);
- strncpy(av_str, mhead.AV, mhead.AV_SIZE);
- av_str[mhead.AV_SIZE] = 0;
+ copylen = mhead.AV_SIZE;
+ if (copylen > 79)
+ copylen = 79;
+ strncpy(av_str, mhead.AV, copylen);
+ av_str[copylen] = 0;
printf("%s\n\n", av_str);
}
comment_out("Main comment:"); // print main comment
@@ -302,7 +306,7 @@ void get_next_volname(void)
INT proc_vol(void) // opens volume
{
INT i;
- CHAR s[80];
+ CHAR s[PATH_MAX + 80];
// if f_allvol_pr is 2 we have -y and should never ask
if ((!fileexists_insense(aname) && f_allvol_pr != 2) || !f_allvol_pr)
@@ -430,7 +434,7 @@ void extract_files(int nopath, int test)
if (head.HEAD_TYPE == FILE_BLK)
{
comment_out("File comment:"); // show file comment
- ace_fname(file, &head, nopath); // get file name
+ ace_fname(file, &head, nopath, sizeof(file)); // get file name
printf("\n%s", file);
flush;
dcpr_init_file(); // initialize decompression of file
@@ -498,7 +502,7 @@ void list_files(int verbose)
if (head.HEAD_TYPE == FILE_BLK)
{
ULONG ti=fhead.FTIME;
- ace_fname(file, &head, verbose ? 0 : 1); // get file name
+ ace_fname(file, &head, verbose ? 0 : 1, sizeof(file)); // get file name
size += fhead.SIZE;
psize +=
@@ -590,7 +594,8 @@ int main(INT argc, CHAR * argv[])
init_unace(); // initialize unace
- strcpy(aname, argv[arg_cnt]); // get archive name
+ strncpy(aname, argv[arg_cnt], sizeof(aname) - 4); // get archive name
+ aname[sizeof(aname) - 5] = '\0';
if (!(s = (CHAR *) strrchr(aname, DIRSEP)))
s = aname;
if (!strrchr(s, '.'))