From:	MERC::"uunet!VM1.NODAK.EDU!owner-anu-news" 21-MAR-1993 14:53:50.83
To:	Multiple recipients of list ANU-NEWS <ANU-NEWS@VM1.NoDak.EDU>
CC:	
Subj:	Patch to writing beyond allocated memory chunk

Find enclosed a patch that takes care of two cases
of writing to an array beyond the currently allocated size.
The patch applies to ANU-NEWS V6.1b6 .

The patch also revokes a fudge in newsutility.c (first introduced
by 921008_NEWSUTILITY.PATCH for ANU-NEWS V6.1b5 and now incorporated
in V6.1b6), which tries to hide one of the manifestations of the
original bug.

I have found two manifestations of these runaways, but there may
be others less obvious.

The runaway in newsfiles.c manifested itself during the execution
of the UPDATE command (using FASTLOAD mechanism), where the 'ga' array
gets deallocated and a new 'ga' array of 20 elements is allocated
but not extended (reallocated) when its size grows beyond 20.
This eventually leads to some elements of the array getting cleared
to 0 which in turn leads later to a pointer reference to nil and hence
an access violation.

The runaway in newsrc.c manifested itself when using together FASTLOAD
and RCFILTER in personal profile (and possibly in other cases as well).
The error occurs during program initialization in routine
NEWSUTILITY\init_screen.  The cause is similar to the one previously
described, but involves the 'ca' array.  Writing to the 'ca' array
beyond its allocated size causes high-order word of 'ga[0]->grp_count'
being overwritten by part of some address, which leads the code
in newsutility.c:
  num_grps = ga[0]->grp_count;
  c$cks(smg$create_virtual_display(c$rfi(num_grps + 40),c$ac(devcol),&grp_vd,0,0
,0));
to obtain a huge number for 'num_grps' and hence SMG declares
LIB-F-INSVIRMEM signal which crashes the program (or depending
on the actual value the allocation of large virtual memory may even
succeeded and cause a really slow performance by SMG routine).

The patch is in VMS_SHARE packing to make sure it transfers correctly.

  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !!  Mark Martinec, System Manager            tel  +386 1 159-199 !!
  !!  J. Stefan Institute, Jamova 39           fax  +386 1 161-029 !!
  !!  61000 Ljubljana, Slovenia       e-mail: Mark.Martinec@ijs.si !!
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_UNPACK_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 8.2
$!   On 21-MAR-1993 01:37:55.66   By user MARK
$!
$! The VMS_SHARE software that created this archive
$!    was written by  Andy Harper, Kings College London UK
$!    -- December 1992
$!
$! Credit is due to these people for their original ideas:
$!    James Gray, Michael Bednarek
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. PATCH.PATCH;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_UNPACK_TEMP","SYS$SCRATCH:."+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if .not. f$trnlnm("SHARE_UNPACK_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto start
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$unpack: subroutine ! P1=filename, P2=checksum, P3=attributes
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'"
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn' File skipped"
$ delete 'f'*
$ exit
$dirok:
$ x=f$search(P1)
$ if x .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped"
$ delete 'f'*
$ exit
$file_absent:
$ w "-I-UNPACK, Unpacking file ", P1
$ n=P1
$ if P3 .nes. "" then $ n=f
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='n'
PROCEDURE GetHex(s,p)LOCAL x1,x2;x1:=INDEX(t,SUBSTR(s,p,1))-1;x2:=INDEX(t,
SUBSTR(s,p+1,1))-1;RETURN 16*x1+x2;ENDPROCEDURE;
PROCEDURE SkipPartsep LOOP EXITIF MARK(NONE)=END_OF(b);EXITIF INDEX(ERASE_LINE,
"-+-+-+-+-+-+-+-+")=1;ENDLOOP;ENDPROCEDURE;PROCEDURE ProcessLine LOCAL c,s,l,b,
n,p;c := ERASE_CHARACTER(1);s := ERASE_LINE;IF c = "X" THEN SPLIT_LINE; ENDIF;
MOVE_HORIZONTAL(-1);l := LENGTH(s);p := 1;LOOP EXITIF p > l;c := SUBSTR(s,p,1);
p := p+1;CASE c FROM ' ' TO '`' ['`']: COPY_TEXT(ASCII(GetHex(s,p))); p:=p+2;[
' ']: p:=p+1;[INRANGE,OUTRANGE]: COPY_TEXT(c);ENDCASE;ENDLOOP;ENDPROCEDURE;
PROCEDURE Decode POSITION(BEGINNING_OF(b));LOOP EXITIF MARK(NONE)=END_OF(b);
IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+-")=1 THEN SkipPartSep;ELSE ProcessLine;
MOVE_HORIZONTAL(1);ENDIF;ENDLOOP;ENDPROCEDURE;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);t:="0123456789ABCDEF";f:=GET_INFO(
COMMAND_LINE,"file_name");b:=CREATE_BUFFER(f,f);Decode;WRITE_FILE(b,GET_INFO(
COMMAND_LINE,"output_file"));QUIT;
$ if p3 .eqs. "" then $ goto dl
$ open/write fdl &f
$ write fdl "RECORD"
$ write fdl P3
$ close fdl
$ w "-I-CONVRFM, Converting record format to ", P3
$ convert/fdl=&f &f-1 &P1
$dl: delete 'f'*
$ checksum 'P1'
$ if checksum$checksum .nes. P2 then $ -
  e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ exit
$ endsubroutine
$start:
$!
$ create 'f'
X***`20newsfiles_orig.c
X---`20newsfiles.c
X**************
X***`20840,845
X`20`20`20`20`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20`20`20`20`20`7D
X`20`20
X`20`20`20`20`20`20ga`5B++ga_size`5D`20=`20(GRP_PTR)`20malloc(sizeof`20newsgrp)
V;
X`20`20`20`20`20`20newsgrp.grp_unread`20=`20newsgrp.grp_count;
X`20`20`20`20`20`20newsgrp.grp_reg`20=`20NEWGROUP_REG`20`7C`20(1`20`26`20(profi
Vle_flags`20`26`20PROFILE_NEWREGISTER));
X---`20840,849`20-----
X`20`20`20`20`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20`20`20`20`20`7D
X`20`20
X+`20`20`20`20`20if`20(ga_size`20>`20(ga_malloc`20-`205))`20`7B
X+`20`20`20`20`20`20`20ga_malloc`20+=`20100;
X+`20`20`20`20`20`20`20ga`20=`20realloc(ga,ga_malloc`20*`20(sizeof`20*ga));
X+`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20ga`5B++ga_size`5D`20=`20(GRP_PTR)`20malloc(sizeof`20newsgrp)
V;
X`20`20`20`20`20`20newsgrp.grp_unread`20=`20newsgrp.grp_count;
X`20`20`20`20`20`20newsgrp.grp_reg`20=`20NEWGROUP_REG`20`7C`20(1`20`26`20(profi
Vle_flags`20`26`20PROFILE_NEWREGISTER));
X***`20newsrc_orig.c
X---`20newsrc.c
X**************
X***`20371,377
X`20`20`20`20if`20(profile_filter`20`26`26`20!reorder_groups)`20`7B
X`20`20`20`20`20`20ca_i`20=`201;
X`20`20`20`20`20`20for`20(g`20=`201;`20g`20<=`20ga_size`20;`20++g)`20`7B
X!`20`20`20`20`20`20`20if`20((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_OLDGROUP)`20
V`26`26`20(ca_i`20<=`20ga_size))
X`20`20`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20`7D
X---`20371,378`20-----
X`20`20`20`20if`20(profile_filter`20`26`26`20!reorder_groups)`20`7B
X`20`20`20`20`20`20ca_i`20=`201;
X`20`20`20`20`20`20for`20(g`20=`201;`20g`20<=`20ga_size`20;`20++g)`20`7B
X!`20`20`20`20`20`20`20if`20((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_OLDGROUP)`20
V`26`26`20(ca_i`20<=`20ga_size))`20`7B
X!`20`20`20`20`20`20`20`20`20if`20(ca_i`20>=`20ca_msize)`20ca`20=`20(GRP_PTR
V`20*)`20realloc(ca,((ca_msize`20+=`2020))`20*`20(sizeof`20*ca));
X`20`20`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X`20`20`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20`20`20`7D
X**************
X***`20373,378
X`20`20`20`20`20`20for`20(g`20=`201;`20g`20<=`20ga_size`20;`20++g)`20`7B
X`20`20`20`20`20`20`20`20if`20((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_OLDGROUP)
V`20`26`26`20(ca_i`20<=`20ga_size))
X`20`20`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20`7D
X`20`20
X---`20374,380`20-----
X`20`20`20`20`20`20`20`20if`20((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_OLDGROUP)
V`20`26`26`20(ca_i`20<=`20ga_size))`20`7B
X`20`20`20`20`20`20`20`20`20`20if`20(ca_i`20>=`20ca_msize)`20ca`20=`20(GRP_PTR
V`20*)`20realloc(ca,((ca_msize`20+=`2020))`20*`20(sizeof`20*ca));
X`20`20`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X+`20`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20`7D
X`20`20
X**************
X***`20382,388
X`20`20`20`20for`20(g`20=`201;`20g`20<=`20ga_size`20;`20++g)`20`7B
X`20`20`20`20`20`20if`20(`20`20`20include_all_groups
X`20`20`20`20`20`20`20`20`20`20`26`26`20!(ga`5Bg`5D->grp_flags`20`26`20NEWS_M_O
VLDGROUP)
X!`20`20`20`20`20`20`20`20`20`26`26`20(ca_i`20<=`20ga_size))
X`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X`20`20`20`20`20`20add_class_member(((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_LOCAL
V)
X`20`20`09`09`20`20`20`20`20?`20local_class`20:`20net_class),ga`5Bg`5D->grp_num
V);
X---`20384,391`20-----
X`20`20`20`20for`20(g`20=`201;`20g`20<=`20ga_size`20;`20++g)`20`7B
X`20`20`20`20`20`20if`20(`20`20`20include_all_groups
X`20`20`20`20`20`20`20`20`20`20`26`26`20!(ga`5Bg`5D->grp_flags`20`26`20NEWS_M_O
VLDGROUP)
X!`20`20`20`20`20`20`20`20`20`26`26`20(ca_i`20<=`20ga_size))`20`7B
X!`20`20`20`20`20`20`20if`20(ca_i`20>=`20ca_msize)`20ca`20=`20(GRP_PTR`20*)`20r
Vealloc(ca,((ca_msize`20+=`2020))`20*`20(sizeof`20*ca));
X`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X`20`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20add_class_member(((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_LOCAL
V)
X**************
X***`20384,389
X`20`20`20`20`20`20`20`20`20`20`26`26`20!(ga`5Bg`5D->grp_flags`20`26`20NEWS_M_O
VLDGROUP)
X`20`20`20`20`20`20`20`20`20`20`26`26`20(ca_i`20<=`20ga_size))
X`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X`20`20`20`20`20`20add_class_member(((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_LOCAL
V)
X`20`20`09`09`20`20`20`20`20?`20local_class`20:`20net_class),ga`5Bg`5D->grp_num
V);
X`20`20#if`20ARBITRON
X---`20387,393`20-----
X`20`20`20`20`20`20`20`20`20`20`26`26`20(ca_i`20<=`20ga_size))`20`7B
X`20`20`20`20`20`20`20`20if`20(ca_i`20>=`20ca_msize)`20ca`20=`20(GRP_PTR`20*)
V`20realloc(ca,((ca_msize`20+=`2020))`20*`20(sizeof`20*ca));
X`20`20`20`20`20`20`20`20ca`5Bca_i++`5D`20=`20ga`5Bg`5D;
X+`20`20`20`20`20`20`20`7D
X`20`20`20`20`20`20add_class_member(((ga`5Bg`5D->grp_flags`20`26`20NEWS_M_LOCAL
V)
X`20`20`09`09`20`20`20`20`20?`20local_class`20:`20net_class),ga`5Bg`5D->grp_num
V);
X`20`20#if`20ARBITRON
X***`20newsutility_orig.c
X---`20newsutility.c
X**************
X***`201964,1970
X`20`20`20`20set_level(1);
X`20`20`20`20broad_trap();
X`20`20`20`20smg_active`20=`201;
X!`20`20`20num_grps`20=`205000;`20/*`20ga`5B0`5D->grp_count;`20trying`20to`20fi
Vx`20FASTLOAD`20RRS*/
X`20`20`20`20c$cks(smg$create_virtual_display(c$rfi(num_grps`20+`2040),c$ac(dev
Vcol),`26grp_vd,0,0,0));
X`20`20`20`20gv_size`20=`20num_grps`20+`2040;
X`20`20`20`20c$cks(smg$create_virtual_display(c$ac(3),c$ac(devcol),`26grp_heade
Vr_vd,0,c$ac(SMG$M_REVERSE`20+`20SMG$M_BOLD),0));
X---`201964,1970`20-----
X`20`20`20`20set_level(1);
X`20`20`20`20broad_trap();
X`20`20`20`20smg_active`20=`201;
X!`20`20`20num_grps`20=`20ga`5B0`5D->grp_count;
X`20`20`20`20c$cks(smg$create_virtual_display(c$rfi(num_grps`20+`2040),c$ac(dev
Vcol),`26grp_vd,0,0,0));
X`20`20`20`20gv_size`20=`20num_grps`20+`2040;
X`20`20`20`20c$cks(smg$create_virtual_display(c$ac(3),c$ac(devcol),`26grp_heade
Vr_vd,0,c$ac(SMG$M_REVERSE`20+`20SMG$M_BOLD),0));
$ call unpack PATCH.PATCH;1 1215143689 ""
$ v=f$verify(v)
$ exit
