[Info-vax] ChatGPT solved it for me, again...
Arne Vajhøj
arne at vajhoej.dk
Mon Feb 20 09:46:47 EST 2023
On 2/20/2023 5:08 AM, Johnny Billquist wrote:
> On 2023-02-17 14:55, Simon Clubley wrote:
>> On 2023-02-17, Arne Vajhøj <arne at vajhoej.dk> wrote:
>>> On 2/17/2023 8:20 AM, Simon Clubley wrote:
>>>> On 2023-02-17, Slo <slovuj at gmail.com> wrote:
>>>>> fgets(sys1, 256, stdin);
>>>>> printf("Enter name of system #2: ");
>>>>> fgets(sys2, 256, stdin);
>>>>> sys1[strcspn(sys1, "\n")] = '\0';
>>>>> sys2[strcspn(sys2, "\n")] = '\0';
>>>>
>>>> OUCH! OUCH! OUCH!!!!!
>>>>
>>>> fgets() is not guaranteed to return a newline character.
>> That code will continue searching memory for a byte with the value of
>> a newline character and will then modify the first such byte it finds.
>>
>> In other words, an out of bounds write vulnerability that may be
>> exploitable in some circumstances when the code is part of a larger
>> program.
>>
>> Even worse, the generated code _appears_ to work ok for normal inputs.
>
> No. You are incorrect. fgets() will put into the buffer up to n-1
> characters, and *always* put a NUL in at the end.
> strcspn() will search the string for a specific character, and return
> the index for that character if found, or the index to the NUL character
> that terminates the string, if character is not found. It will never
> search beyond the string read by fgets().
As I think everybody has agreed by now then the code
is safe.
I still stand by my original assessment that I would not
have used strcspn for this. It seems weird to me to
search through the entire string in a way that can handle
multiple stop characters when one knows that there is
only one stop character and really are only interested
in the last char in the string.
Also note that even though in all practical cases
the Pascal and C code will act identical, then it is
possible to create a case where they do not on VMS.
$ type p.pas
program p(input,output);
type
pstr = varying [255] of char;
var
line : pstr;
begin
readln(line);
writeln(line.length:1);
end.
$ pas p
$ link p
$ type c.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char line[256];
fgets(line, 256, stdin);
line[strcspn(line, "\n")] = '\0';
printf("%d\n", strlen(line));
return 0;
}
$ cc c
$ link c
$ run p
ABC
3
$
$ run c
ABC
3
$
$ define/user sys$input z.txt
$ run p
7
$ define/user sys$input z.txt
$ run c
3
The VMS knowledgeable has of course already guessed
the reason - the file z.txt is RFM:VAR and contains
a line with newline in.
I do not blame ChatGPT for not thinking about that. This
is a very special case.
Arne
More information about the Info-vax
mailing list