Can't undate running process binary in Solaris?
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > Can't undate running process binary in Solaris?




Pages (2): [1] 2 »   Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    Can't undate running process binary in Solaris?  
Boltar


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-05-07 12:19 PM

Hi

I'm trying to get a running process to update its own binary but for
some reason under Solaris it doesn't work , the binary remains
unchanged even though no errors are returned from any function. Does
anyone know why this might happen? My test code is below:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

char *tag = "TEST";

int main(int argc, char **argv)
{
struct stat fs;
char *mptr;
char *start;
char *end;
int fd;

if ((fd = open(argv[0],O_RDWR)) == -1)
{
perror("open()");  exit(1);
}

if (fstat(fd,&fs) == -1)
{
perror("fstat()");  exit(1);
}

mptr = (char *)mmap(
NULL,fs.st_size,PROT_READ | PROT_WRITE,MAP_PRIVATE,fd,
0);
if (mptr == MAP_FAILED)
{
perror("mmap()");  exit(1);
}

end = mptr + fs.st_size - strlen(tag) - 1;
for(start = mptr;start != end;++start)
{
if (start[0] == 'T' &&
start[1] == 'E' &&
start[2] == 'S' &&
start[3] == 'T')
{
printf("Found tag at address 0x%08X\n",start);
memcpy(start,"DONE",4);
if (munmap(mptr,fs.st_size) == -1)
{
perror("munmap()");  exit(1);
}
if (close(fd) == -1)
{
perror("close()");  exit(1);
}
return 0;
}
}

puts("Tag not found.");
return 0;
}

Thanks for any help

B2003






[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
David Schwartz


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-05-07 12:19 PM


Boltar wrote:

> I'm trying to get a running process to update its own binary but for
> some reason under Solaris it doesn't work , the binary remains
> unchanged even though no errors are returned from any function. Does
> anyone know why this might happen? My test code is below:

When a process begins running, it gets its own logical copy of the
program to run from. You have the logical copy of the program that is
in the file and you have the logical copy of the program that is
running. But they are two separate logical copies and any attempt to
modify one of them will result in splitting the physical copies.

Actually, that's almost true. I think on Solaris you simply cannot
modify the file. You can modify the logical copy that is running. (You
do not need to 'mmap', simply 'mprotect' and then write -- it's
already mapped in.)

It would be truly horrible if updating or modifying an executable
resulted in running programs getting their execution binary changed
out from under them.

Note that if you have a program that's always running, like 'init',
and want to put up a new 'init' binary, you can do it several ways:

1) You can unlink the running 'init' and then rename the new one.

2) You can rename the new 'init' on top of the old one.

3) You can rename the running 'init' and then put the new one in
place.

Most operating systems implement this as follows:

1) When a file is executing, it is prohibited from having its data
contents modified.

2) When a program starts executing, the file is mapped into memory.
The pages fault in as they are loaded.

3) The pages are kept write protected. If the mapping is changed to be
writable, it is still kept as write protected internally.

4) If a page is modified, since it was write protected internally, a
fault will occur. The fault handle will see that the mapping was made
writable and go through the following sequence of steps:

A) If the page is not resident in memory, it will be loaded.
B) The page's status will be changed from 'clean copy of data on disk'
to 'anonymous'.
C) The page will be made writable internally.

Note that if the page was already in memory and in use by another
process, a new page will be allocated as anonymous, the data copied,
and that new page will be mapped in. (So when the write does take
place, the process will be writing to its own anonymous page that
starts as a copy of that part of the original executable image.)

This means that if the page is no longer going to be kept in physical
memory, it will be swapped rather than being discarded. (Before it
could be discarded because the OS can just load it back in from the
executable.)

DS






[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
Boltar


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-05-07 12:19 PM

On 5 Jul, 12:05, David Schwartz <dav...@webmaster.com> wrote:
> modify the file. You can modify the logical copy that is running. (You
> do not need to 'mmap', simply 'mprotect' and then write -- it's
> already mapped in.)

What address would I pass to mprotect to do this?

> It would be truly horrible if updating or modifying an executable
> resulted in running programs getting their execution binary changed
> out from under them.

Not really. Self modifying code can be damn useful. Its only in the
last 20 years or so that this idea that somehow its wrong has come
about.

B2003








[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
Eric Sosman


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-05-07 06:21 PM

Boltar wrote On 07/05/07 06:40,:
> Hi
>
> I'm trying to get a running process to update its own binary but for
> some reason under Solaris it doesn't work , the binary remains
> unchanged even though no errors are returned from any function. Does
> anyone know why this might happen? My test code is below:
> [...]
>
>    mptr = (char *)mmap(
>        NULL,fs.st_size,PROT_READ | PROT_WRITE,MAP_PRIVATE,fd, 0);
^^^^^^^^^^^
You told the system "Make sure any changes are private
to this process," and it did what you told it to.  If you
wanted something else to happen, you should have said so!

--
Eric.Sosman@sun.com





[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
Frank Cusack


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-06-07 12:24 AM

On Thu, 05 Jul 2007 03:40:12 -0700 Boltar <boltar2003@yahoo.co.uk> wrote:
> I'm trying to get a running process to update its own binary but for
> some reason under Solaris it doesn't work , the binary remains
> unchanged even though no errors are returned from any function. Does
> anyone know why this might happen? My test code is below:
...
>         mptr = (char *)mmap(
>                 NULL,fs.st_size,PROT_READ | PROT_WRITE,MAP_PRIVATE,fd,
^^^^^^^^^^^

-frank





[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
Frank Cusack


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-06-07 12:24 AM

On Thu, 05 Jul 2007 13:34:23 -0700 Frank Cusack <fcusack@fcusack.com> wrote:
> On Thu, 05 Jul 2007 03:40:12 -0700 Boltar <boltar2003@yahoo.co.uk> wrote: 
> ... 
>                                                          ^^^^^^^^^^^

Actually, even when you fix that i don't think you'll be able to
update in-place.  You will probably get ETXTBUSY or whatever the
error is, if not at mmap() time, than maybe you'll get SEGV or
a bus error when you actually write to memory.

If a program's text is busy (I mean, if a program is running),
Solaris will not let you, e.g., do something like "echo > program".

Or do I have it backwards and it's Linux that doesn't allow this?

-frank





[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
Rainer Weikusat


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-06-07 12:24 AM

Frank Cusack <fcusack@fcusack.com> writes:
> On Thu, 05 Jul 2007 13:34:23 -0700 Frank Cusack <fcusack@fcusack.com> wrot
e: 

[...]
[vbcol=seagreen] 
>
> Actually, even when you fix that i don't think you'll be able to
> update in-place.  You will probably get ETXTBUSY or whatever the
> error is, if not at mmap() time, than maybe you'll get SEGV or
> a bus error when you actually write to memory.
>
> If a program's text is busy (I mean, if a program is running),
> Solaris will not let you, e.g., do something like "echo > program".
>
> Or do I have it backwards and it's Linux that doesn't allow this?

Linux 2.6 returns an 'is busy' error on attempt to modify a file which
is currently being executed.





[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
Eric Sosman


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-06-07 12:24 AM

Frank Cusack wrote On 07/05/07 16:41,:
> On Thu, 05 Jul 2007 13:34:23 -0700 Frank Cusack <fcusack@fcusack.com> wrot
e:
> 
>
>
> Actually, even when you fix that i don't think you'll be able to
> update in-place.  You will probably get ETXTBUSY or whatever the
> error is, if not at mmap() time, than maybe you'll get SEGV or
> a bus error when you actually write to memory.
>
> If a program's text is busy (I mean, if a program is running),
> Solaris will not let you, e.g., do something like "echo > program".
>
> Or do I have it backwards and it's Linux that doesn't allow this?

Solaris allows the update (I tried it).

I'm not sure what Boltar's goal in self-modifying the
executable is, though.  He mentioned this thread in another
having to do with license-enforcement schemes, but I don't
see any way to use self-modification for enforcement (it's
too easy to protect the file against being written, or to
restore an unmodified backup copy).  Boltar, what are you
trying to accomplish?  Maybe there's an easier way ...

--
Eric.Sosman@sun.com





[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
David Schwartz


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-06-07 12:24 AM

On Jul 5, 1:41 pm, Frank Cusack <fcus...@fcusack.com> wrote:

> If a program's text is busy (I mean, if a program is running),
> Solaris will not let you, e.g., do something like "echo > program".
>
> Or do I have it backwards and it's Linux that doesn't allow this?
>
> -frank

Neither of them will allow you to modify a running binary. There is a
difference in implementation though, which is probably what you are
remembering. I can't remember the exact details of the different
though. I believe Linux would let you do some things that Solaris
would not involving different ways to replace the executable with
another or rename/remove it.

If anyone remembers it precisely, please post the details.

DS






[ Post a follow-up to this message ]



    Re: Can't undate running process binary in Solaris?  
Boltar


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-06-07 12:19 PM

On 6 Jul, 09:30, Boltar <boltar2...@yahoo.co.uk> wrote:
> On 5 Jul, 16:39, Eric Sosman <Eric.Sos...@sun.com> wrote:
> 
> 
> 
> 
>
> I tried MAP_SHARED , that didn't work either. What should it be?

Ignore me. Tried it again and it did work. Must've done something
wrong first time.

B2003







[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 09:10 AM.      Post New Thread    Post A Reply      
Pages (2): [1] 2 »   Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register