Hi Bart,

1st, I hope you live in a different timezone.
at 4:07 we all should be in bed  ;)


> so in the end the issue is a stack overflow:
nice find :))

> filenames on the stack
> overflow into a const buffer used by strtok. I had raised it from 2K
> to 4K back in January but that is not enough.

    if not exist unistd.c~ ren unistd.c *.c~

needs 4600 bytes (see below)

so far all retested
   TESTS KE2041
   TESTS JED
   TESTS PICOC

work, but require at least 4600 byte stack




> Since Blair Campbell's LFN work in 2006 cmd_rename() which calls
> fillFnam() together use at least 13 ~256-sized fixed sized filename
> buffers, which is already 3.3K right there.
maybe finally found the reason nobody wants to use this code
fixing bugs is not sexy. leaving bugs as an exercise to the reader.



> You can raise the stack for OW in shell/wlinker.bat to at least 6K,
> maybe 8K is better to be more on the safe side.
so far found code that uses 4600 byte
I will take 8k as it doesn't matter much as everything is swapped out anyway.

> Or alternatively
> redesign that code a bit to use less stack space.
> Or also just compile without -s to enable stack checking and see what
> that gives. I'll do some more tests tomorrow.


I added the following to shell\command.c

int process_input(int xflag, char *commandline)
{
...

      if(tracethisline)
        --tracemode;
    }

+        {
+        extern int stack_check(const char *commandline);
+
+        stack_check(parsedline);
+        }
  }
  while (!canexit || !exitflag);

and later



static void * stack_bottom, * stack_unused;


void stack_check_init()
{
        char current_stack_location;                      
        void **barrier;
        
                                                                        // 
place a barrier at the 
                                                                        // 
bottom of the stack
                                                                        // code 
assumes 8 K right now
        stack_bottom = &current_stack_location - 8*1024 + 50;
        
        stack_unused    = (char*)(&current_stack_location); 
        
        
        
        for (barrier = stack_bottom; barrier < stack_unused ; barrier++)
                {
                *barrier = barrier;
                }
        
}
int stack_check(const char *commandline)
{
        void **barrier;

        for (barrier = stack_bottom; barrier < stack_unused; barrier++)
                {
                if (*barrier != barrier)
                        {  
                        break;
                        
                        }
                }
                
                
        if (barrier < stack_unused)             
                {
                unsigned stack_left = (char*)barrier - (char*)stack_bottom;     
                
                
                if (stack_left < 5000)
                        {
                        printf("stack left %u after 
<%.60s>\n",stack_left,commandline);  
                        cgetchar();
                        }
                
                stack_unused = barrier;
        }
        return 0;
}

int main(void)
{
  /*
   * * main function
   */    

        stack_check_init();

....



Tom





_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to