zgv and svgalib revisited
Date: Mon, 26 Oct 1998 14:03:30 +0100 (CET)
From: Marc Heuse <[email protected]>
To: [email protected]
Subject: Re: zgv and svgalib revisited
Cc: [email protected]
Hi,
below is my patch for zgv 4.1 which will be incorporated into the suse linux
6.0 distro, and is available as an update packet for the suse 5.3
what's interesting is the different kind of fixing the bugs (perl slogan:
there's always more than one way to do it)
what i don't like in your patch is the explicit close_on_exec on fd 3 ...
which is rather useless :-( an attacker just opens another fd or closes
stderr before running zgv, and it's gone. this should be done in svgalib,
but you already proposed this ;-)
Greets,
Marc
--- gifeng.c.orig Fri Oct 9 09:02:03 1998
+++ gifeng.c Fri Oct 9 09:05:12 1998
@@ -187,7 +187,8 @@
ginfo->width=width;
ginfo->height=height;
gifhed.wide_lo=0; /* yes, it's nasty, but wide_lo is unimportant anyway :) */
-strcpy(ginfo->type,gifhed.sig+3);
+strncpy(ginfo->type,gifhed.sig+3,SIZE_OF_PICINFO_TYPE - 1);
+ginfo->type[SIZE_OF_PICINFO_TYPE - 1] = '\0';
ginfo->bpp=bpp;
ginfo->numcols=numcols;
}
--- rcfile.c.orig Fri Oct 9 09:08:38 1998
+++ rcfile.c Fri Oct 9 09:13:58 1998
@@ -45,7 +45,8 @@
defaultcfg();
gotrcfile=0;
-strcpy(cfgfile,getenv("HOME"));
+strncpy(cfgfile,getenv("HOME"),sizeof(cfgfile)-10);
+cfgfile[sizeof(cfgfile)-10] = '\0';
strcat(cfgfile,"/.zgvrc");
if((in=fopen(cfgfile,"r"))!=NULL)
@@ -456,7 +457,8 @@
switch(getopt(argc,argv,"a:bcghijJ:klM:m:r:sptTz"))
{
case 'a': /* alternative command */
- strcpy(cfg.cmd,optarg);
+ strncpy(cfg.cmd,optarg,sizeof(cfg.cmd)-1);
+ cfg.cmd[sizeof(cfg.cmd)-1]='\0';
if(strstr(cfg.cmd,"%s")==NULL)
{
fprintf(stderr,"Need '%%s' filename placeholder in command string.\n");
@@ -493,7 +495,7 @@
int vidnum;
strcpy(buf,"dummytoken ");
- strcat(buf,optarg);
+ strncat(buf,optarg,sizeof(buf));
if(getmodenumber(buf,&vidnum)==-1)
{
fprintf(stderr,"Mode '%s' not found.\n",optarg);
--- readjpeg.c.orig Fri Oct 9 09:16:39 1998
+++ readjpeg.c Fri Oct 9 09:16:53 1998
@@ -51,7 +51,7 @@
char buf[256];
strcpy(buf,"Error reading JPEG - ");
-strcat(buf,msgtext);
+strncat(buf,msgtext,sizeof(buf));
if(cfg.onefile_progress)
fprintf(stderr,buf);
else
--- readnbkey.c.orig Fri Oct 9 09:20:40 1998
+++ readnbkey.c Fri Oct 9 09:22:19 1998
@@ -28,11 +28,11 @@
int readnbkey(int ttyfd)
{
int realkey,f;
-char keybuf[1024];
+char keybuf[1024] = '\0';
/* this gets all the characters sent by the key into an ASCIIZ string */
f=0;
-while((keybuf[f++]=getnbkey(ttyfd)));
+while((keybuf[f++]=getnbkey(ttyfd))&&(strlen(keybuf)<sizeof(keybuf)));
realkey=0;
--- zgv.c.orig Sun Mar 2 02:32:44 1997
+++ zgv.c Fri Oct 9 09:54:46 1998
@@ -206,7 +206,8 @@
for(i=argc-argsleft,entnum=1;i<=argc-1;i++)
if(stat(argv[i],&buf) != -1 && !S_ISDIR(buf.st_mode))
{
- strcpy(gifdir[entnum].name,argv[i]);
+ strncpy(gifdir[entnum].name,argv[i],sizeof(gifdir[entnum].name)-1);
+ gifdir[entnum].name[sizeof(gifdir[entnum].name)-1]='\0';
gifdir[entnum].marked=1;
gifdir[entnum].isdir=0;
entnum++;
@@ -604,9 +605,10 @@
char *ptr,sav;
ptr=strstr(cfg.cmd,"%s"); /* we know it's there - see rcfile.c */
sav=*ptr; *ptr=0;
- strcpy(buf,cfg.cmd);
- strcat(buf,gifdir[curent].name);
- strcat(buf,ptr+2);
+ strncpy(buf,cfg.cmd,sizeof(buf)-1);
+ buf[sizeof(buf)-1]='\0';
+ strncat(buf,gifdir[curent].name,sizeof(buf));
+ strncat(buf,ptr+2,sizeof(buf));
*ptr=sav;
screenoff();
system(buf);
@@ -851,9 +853,9 @@
if(drawdirmsg)
{
if(updating_index)
- sprintf(ctmp,"Updating index of %s",cdir);
+ snprintf(ctmp,sizeof(ctmp),"Updating index of %s",cdir);
else
- sprintf(ctmp,"Directory of %s",cdir);
+ snprintf(ctmp,sizeof(ctmp),"Directory of %s",cdir);
set_max_text_width(560);
if(unshow)
@@ -895,16 +897,17 @@
/* if '/.xvpics' is in the (absolute) path somewhere, we're
* in a xvpics subdir. So look for the thumbnail here! :-)
*/
- if(strstr(cdir,"/.xvpics")!=NULL)
- strcpy(ctmp,gifdir[f].name);
- else
- sprintf(ctmp ,".xvpics/%s",gifdir[f].name);
- sprintf(ctmp2,"%s/.xvpics/",getenv("HOME")?getenv("HOME"):"");
+ if(strstr(cdir,"/.xvpics")!=NULL) {
+ strncpy(ctmp,gifdir[f].name,sizeof(ctmp)-1);
+ ctmp[sizeof(ctmp)-1]='\0';
+ } else
+ snprintf(ctmp,sizeof(ctmp),".xvpics/%s",gifdir[f].name);
+ snprintf(ctmp2,sizeof(ctmp2)-1,"%s/.xvpics/",getenv("HOME")?getenv("HOME"):"");
ptr=ctmp2+strlen(ctmp2);
getcwd(ptr,sizeof(ctmp2)-strlen(ctmp2)-1); ctmp2[strlen(ctmp2)]=0;
/* convert /foo/bar/baz to _foo_bar_baz */
while((ptr=strchr(ptr,'/'))!=NULL) *ptr++='_';
- strcat(ctmp2,"/"); strcat(ctmp2,gifdir[f].name);
+ strcat(ctmp2,"/"); strncat(ctmp2,gifdir[f].name,sizeof(ctmp2));
gifdir[f].xvw=gifdir[f].xvh=0;
if(gifdir[f].isdir)
@@ -1032,7 +1035,8 @@
{
entnum++;
gifdir[entnum].isdir=isdir;
- strcpy(gifdir[entnum].name,anentry->d_name);
+ strncpy(gifdir[entnum].name,anentry->d_name,sizeof(gifdir[entnum].name)-1);
+ gifdir[entnum].name[sizeof(gifdir[entnum].name)-1]='\0';
gifdir[entnum].marked=0;
}
}
@@ -1059,11 +1063,12 @@
if(gifdptr->isdir)
{
buf[0]='(';
- strcpy(buf+1,gifdptr->name);
+ strncpy(buf+1,gifdptr->name,sizeof(buf)-2);
strcat(buf,")");
}
else
- strcpy(buf,gifdptr->name);
+ strncpy(buf,gifdptr->name,sizeof(buf)-1);
+buf[sizeof(buf)-1]='\0';
}
@@ -1249,7 +1254,7 @@
return;
#ifdef PNG_SUPPORT
case _PICERR_PNG_ERR: /* a PNG error in zgv_pngerr */
- strcpy(buf,zgv_pngerr); break;
+ strncpy(buf,zgv_pngerr,sizeof(buf)-1); buf[sizeof(buf)-1]='\0'; break;
#endif /* PNG_SUPPORT */
default:
strcat(buf,"unknown error (ulp!)");
@@ -1278,7 +1283,7 @@
if(cfg.nodelprompt==0)
{
- sprintf(buf,"Really delete %s?",filename);
+ snprintf(buf,sizeof(buf),"Really delete %s?",filename);
retn=msgbox(zgv_ttyfd,buf,MSGBOXTYPE_YESNO, idx_light,idx_dark,idx_black);
}
@@ -1289,7 +1294,7 @@
idx_light,idx_dark,idx_black);
else
{
- sprintf(buf,".xvpics/%s",filename);
+ snprintf(buf,sizeof(buf),".xvpics/%s",filename);
remove(buf); /* don't care if it fails */
rmdir(".xvpics"); /* same here */
}
@@ -1314,7 +1319,7 @@
if(sofar!=total)
{
vga_setcolor(idx_black);
- sprintf(tmp,"Reading - %2d%%",done);
+ snprintf(tmp,sizeof(tmp),"Reading - %2d%%",done);
vgadrawtext(xv332_how_far_xpos+(BARWIDTH-70)/2,
xv332_how_far_ypos+GDFSIZ*6+39-4,2,tmp);
}
@@ -1447,14 +1452,14 @@
continue; /* the picture file doesn't exist */
/* test for normal .xvpics/wibble */
- sprintf(buf,".xvpics/%s",gifdir[f].name);
+ snprintf(buf,sizeof(buf),".xvpics/%s",gifdir[f].name);
/* and for ~/.xvpics/foo_bar_baz/wibble */
- sprintf(buf2,"%s/.xvpics/",getenv("HOME")?getenv("HOME"):"");
+ snprintf(buf2,sizeof(buf2),"%s/.xvpics/",getenv("HOME")?getenv("HOME"):"");
ptr=buf2+strlen(buf2);
getcwd(ptr,sizeof(buf2)-strlen(buf2)-1); buf2[strlen(buf2)]=0;
while((ptr=strchr(ptr,'/'))!=NULL) *ptr++='_';
- strcat(buf2,"/"); strcat(buf2,gifdir[f].name);
+ strcat(buf2,"/"); strncat(buf2,gifdir[f].name,sizeof(buf2));
r1=stat(buf,&xvpic); r2=stat(buf2,&xvpic2);
@@ -1501,7 +1506,7 @@
}
/* make sure filename for xvpic is in buf */
- strcat(buf,"/"); strcat(buf,gifdir[f].name);
+ strcat(buf,"/"); strncat(buf,gifdir[f].name,sizeof(buf));
}
makexv332(gifdir[f].name,buf,(fwinxpos(f-startfrom+1)<<16) |
--- zgv.h.orig Sun Mar 2 02:32:44 1997
+++ zgv.h Fri Oct 9 09:04:47 1998
@@ -19,10 +19,12 @@
#define _PICERR_ISRLE -9
#define _PICERR_PNG_ERR -10
+#define SIZE_OF_PICINFO_TYPE 4
+
typedef struct {
int width,height;
int bpp,numcols;
- char type[4];
+ char type[SIZE_OF_PICINFO_TYPE];
} PICINFO;
typedef void (*hffunc)(int,int);
Type Bits/KeyID Date User ID
pub 2048/DB5C03C5 1997/09/23 Marc Heuse <[email protected]>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: 2.6.3i
mQENAzQnbFEAAAEIAL/tj4hn/DVjEWAZhuqRdxZQDy5B+gZbE0CD/mUnZqpem+9L
KY+I8te7jMfTQExzqn5jYb5BaibT0SbEBWSx9Gha8EiBLAVcAjvrXpV+HJLcnPRG
YDk5a3s7GrA+QVHbbd9DWgqjMfUMw9oUDAhhjgK20SeOtFGBD2U17GkQF6TK7EjC
CTOuz2Hx/tisDuroJJnxZdbLNvCceOf/D/bbFcR7DfnEJWJ3f9JC4fibZMlX5rXL
Ct/TKhZMd4d42uL7L4KvkT5JCnFuEw1jRDPpBjZ030cK2uWCM//iEVLGmGKOs6Pg
o3Lfnnd6I6bTPHgrNsapNWmocbIGDC/4w9tcA8UABRG0Jk1hcmMgSGV1c2UgPG1h
cmMuaGV1c2VAbWFpbC5kZXViYS5jb20+iQEVAwUQNCdsUQwv+MPbXAPFAQFWEwf5
AWt6PbKLLCCBPnzBMdXatKEJvNzrZRXNSpbgKQUDAKApRUnOkDJ9yp3tfJG0/BsL
XBf+ldmjjoo/OZeWhIhNb71bbCs8BK7/YK5LKef2eq4pzSiWYosrOfjlfyOVhAiP
AiWYtK/HBELy6Zs8QwoPX0QX0+R2+ocMS0TDz7nwBgO5wcj3yMU0geTrnlDpJdj1
RgFQLE6T9qO5coRjj1EAoT5gQMxP9L4TQuifYiQ6S2vh6blr3amjPohKSDzZ62/x
rQ1KMXJd7MlMQndn8UwKt4XgoFIsZOFRrkDiXfm6zFnH40UcotoA+Ygojp52+Y6A
MuixTDbuf3Jph2jEG6r4Dw==
=/n63
-----END PGP PUBLIC KEY BLOCK-----