-1

I have been trying to implement a shell in Linux as a learning experience...the change directory function and the program itself gives different outputs under different privileges.

1)Execution under normal user authority

    [Vivek-lappy]/home/Vivek-lappy/Documents/Zeus/Zeus>ls /
    0     dev   initrd.img  live-build  mnt   root  srv  usr
    bin   etc   lib     lost+found  opt   run   sys  var
    boot  home  lib64   media       proc  sbin  tmp  vmlinuz
    [Vivek-lappy]/home/Vivek-lappy/Documents/Zeus/Zeus>cd /
    PWD=/
    [Vivek-lappy]/>ls
    Segmentation fault

gdb shows the following errors:

    Program received signal SIGSEGV, Segmentation fault.
    _IO_vfprintf_internal (s=0x0, format=0x402953 "command:%s\n", 
    ap=ap@entry=0x7fffffffdd08) at vfprintf.c:1278
    1278    vfprintf.c: No such file or directory.

2) Execution under sudo privileges

   [root](null)>ls /
    0     dev   initrd.img  live-build  mnt   root  srv  usr
    bin   etc   lib     lost+found  opt   run   sys  var
    boot  home  lib64   media       proc  sbin  tmp  vmlinuz
   [root](null)>cd /
    PWD=/
   [root]/>ls
   0     dev   initrd.img   live-build  mnt   root  srv  usr
   bin   etc   lib      lost+found  opt   run   sys  var
   boot  home  lib64    media       proc  sbin  tmp  vmlinuz
   [root]/>

3) Additional information Code for Change directory function

    void add(char * name,char * value){
    unsetenv(name);setenv(name,value,1);
    }

    void dump(char * name){

       char * value=getenv(name);
       printf("%s=%s\n",name,value); 
   }


 int cd(char * argv[],int argc){

char cwd[1024];

if(argc>2){
    printf("\n Too many arguments cd accepts only one argument that is the directory name\n");
    return -1;
}

if(argv[1]==NULL){
    if(chdir(getenv("HOME"))==0){
        add("PWD",getenv("HOME"));
        dump("PWD");
        return 0;
    }

}


if(chdir(argv[1])!=0){
        printf("\n No Such Directory\n");
        printf("\nUSAGE:> cd Dir_name [Where Directory_Name is the Directory name] \n");
        return -1;

}
if (!getcwd (cwd, sizeof(cwd))) {
    perror ("getcwd");
    exit (EXIT_FAILURE);

}

else{

    add("PWD",cwd);
    dump("PWD");


}


return 0;


}

Code for execute :

  int execute(char * argv[],int argc){

   int status;        

    if(strcmp(argv[0],"cd")==0){
        cd(argv,argc);
  }
  else if(strcmp(argv[0],"list")==0){

    list();
  }
  else if(strcmp(argv[0],"color")==0){

    color();

  }
  else if(strcmp(argv[0],"history")==0){
    history();
    }
    else
 {

    pid_t pid=fork();   
    if(pid<0){

        fprintf(stderr, "cant fork process%s\n",strerror(errno) );
        return 1;
    }
    else if(pid==0){

            if(execvp(argv[0],argv)<0){
                fprintf(stderr, "cant run program:%s\n",strerror(errno) );

            return 1;
            }

        }
    else
    {
        while(wait(&status)!=pid)
            ;


    }



 }

 return 0;
}

Why is the output of the same program different with different privileges?

Chainsaw
  • 11
  • 7
  • 1
    Your `ls` execution caused a seg fault. So you should show the `ls` code. And show the stack trace in gdb when the seg fault occurs. – kaylum Mar 25 '16 at 10:46
  • Your `ls` is calling vfprintf() with a NULL first argument (the FILE *) – joop Mar 25 '16 at 10:49
  • hello @kaylum why does the same code not cause a seg fault with root privileges? and i am executing ls with fork+execvp system calls. – Chainsaw Mar 25 '16 at 10:50
  • Because root has a different setting for `PATH` and you are manipulating the environment. – joop Mar 25 '16 at 10:51
  • How about you show that code and then we'll discuss the possible problems? In particular, it would be good to see the exact code that triggers the seg fault. – kaylum Mar 25 '16 at 10:53
  • @kaylum added code for the execute function – Chainsaw Mar 25 '16 at 11:01
  • That doesn't look like it contains the code that causes the crash. Do you have code calling `vfprintf` with a string like this: `"command:%s\n"`? Or can you please give the gdb stack trace as already requested? – kaylum Mar 25 '16 at 11:03
  • i had a "command:%s\n" in cd function itself which i thought was buggy which i removed and compiled any idea why its still showing? not even part of the source code anymore! – Chainsaw Mar 25 '16 at 11:06
  • Get some sleep. And clean up your code. – joop Mar 25 '16 at 11:06
  • Then it means you are probably not running the code you think you are. Add some more `printf` statements to verify. And please show the stack trace (requesting third time). – kaylum Mar 25 '16 at 11:07
  • how do i get the stack trace? – Chainsaw Mar 25 '16 at 11:10
  • Run the program in gdb. When it gets a seg fault it will drop back to the gdb prompt. At the gdb prompt run `bt`. – kaylum Mar 25 '16 at 11:12
  • added printf statements to verify if i was compiling the same code. i am. – Chainsaw Mar 25 '16 at 11:14
  • (gdb) bt #0 _IO_vfprintf_internal (s=0x0, format=0x40296b "command:%s\n", ap=ap@entry=0x7fffffffdd08) at vfprintf.c:1278 #1 0x00007ffff7a83d47 in __fprintf (stream=, format=) at fprintf.c:32 #2 0x0000000000401fb5 in add_to_history () #3 0x0000000000402336 in main () – Chainsaw Mar 25 '16 at 11:15
  • Keep going with your debugging. It clearly shows a problem stemming from `add_to_history`. We can't really help you because there is clearly missing information that we don't have. The best advice you'll get is to learn to use the debugger properly. – kaylum Mar 25 '16 at 11:25
  • Thank you @kaylum will look up resources on gdb. – Chainsaw Mar 25 '16 at 11:29

1 Answers1

0

Your segmentation fault is most likely because of using a pointer pointing to some uninitialized or random data. Depending on the contents of such random data you might get a segmentation fault or the data might seem valid enough for your program to continue execution. Different circumstances (like sudo or not) might give different contents in your random or uninitialized data.

To debug this further I would adjust your limits so that a core dump file is produced. With that core dump you will be able to see in the debugger exactly where your program segfaults. You probably already did this as you know that the segfault is in the function vprintf which you didn't write yourself, but if you look higher up in the call stack you will probably find your own code doing a call to some *printf function with bad arguments.

Henrik Carlqvist
  • 1,138
  • 5
  • 6