Modifying ELF files

2010-04-08 Thread Patrick Mahan


In my job, we are producing applications and KLM's for our product
that require them to be signed so that our installer will recognize
and validate our images.

The signature is stored in each app as

unsigned char signature[40] __attribute__((section(.compsign)));

What I need to do is open the file for writing, locate the .compsign
section and stuff in the signature, write it out and close the file.
(simple ELF manipulation)

An 'ls -l' shows the following:

% ls compklm.ko
-rw-r--r--  1 pmahan  pmahan  125296 Apr  6 22:50 /home/pmahan/temp/compklm.ko

When I try to run my program
./signfile --signature=A203239897C8EB360D1EB2C84E8E77B16E5B7C9A compklm.ko
open: Text file busy

Googling and looking at the kernel sources, it seems that it detects
this file contains 'shared text', that is, it is an executable file
and does not allow me to open it for writing.

I understand (from my google search) this is a means to keep you from
shooting yourself in the foot.  But there has got to be a way and I
really don't want to grovel through the compiler code to find it.  I
looked at using libelf.so but it also requires that the file be open
for writing.  So I am kinda of stuck.  If I cannot find a quick solution
we might need to do all of our signing on our FC11 box which does not
have this issue.

Thanks for the education I always get from this list,

Patrick



___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org


Re: Modifying ELF files

2010-04-08 Thread Nate Eldredge

On Thu, 8 Apr 2010, Patrick Mahan wrote:



In my job, we are producing applications and KLM's for our product
that require them to be signed so that our installer will recognize
and validate our images.

The signature is stored in each app as

unsigned char signature[40] __attribute__((section(.compsign)));

What I need to do is open the file for writing, locate the .compsign
section and stuff in the signature, write it out and close the file.
(simple ELF manipulation)

An 'ls -l' shows the following:

% ls compklm.ko
-rw-r--r--  1 pmahan  pmahan  125296 Apr  6 22:50 
/home/pmahan/temp/compklm.ko


When I try to run my program
./signfile --signature=A203239897C8EB360D1EB2C84E8E77B16E5B7C9A compklm.ko
open: Text file busy

Googling and looking at the kernel sources, it seems that it detects
this file contains 'shared text', that is, it is an executable file
and does not allow me to open it for writing.


My understanding was that ETXTBSY occurs when you attempt to open for 
writing a file which is actually being executed, i.e. is mapped into some 
process.  I'm not aware that open(2) actually looks at the file itself to 
see if it is an executable; that would be very surprising to me.


What does fstat -m compklm.ko say?

What happens if you cp compklm.ko foo.ko and try to sign foo.ko?  You 
should then be able to do mv foo.ko compklm.ko; if compklm.ko is 
in fact mapped into some process, it will continue to use the original 
version, which will be kept around (invisibly) until all mappings go away. 
This is what compilers, install(8), etc, normally do.


Does your signfile program do anything with the target file before 
open(..., O_RDWR)?


--

Nate Eldredge
n...@thatsmathematics.com
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org


Re: Modifying ELF files

2010-04-08 Thread Peter Pentchev
On Thu, Apr 08, 2010 at 07:17:46AM -0700, Patrick Mahan wrote:
 
 In my job, we are producing applications and KLM's for our product
 that require them to be signed so that our installer will recognize
 and validate our images.
 
 The signature is stored in each app as
 
 unsigned char signature[40] __attribute__((section(.compsign)));
 
 What I need to do is open the file for writing, locate the .compsign
 section and stuff in the signature, write it out and close the file.
 (simple ELF manipulation)
 
 An 'ls -l' shows the following:
 
 % ls compklm.ko
 -rw-r--r--  1 pmahan  pmahan  125296 Apr  6 22:50 /home/pmahan/temp/compklm.ko
 
 When I try to run my program
 ./signfile --signature=A203239897C8EB360D1EB2C84E8E77B16E5B7C9A compklm.ko
 open: Text file busy
 
 Googling and looking at the kernel sources, it seems that it detects
 this file contains 'shared text', that is, it is an executable file
 and does not allow me to open it for writing.
 
 I understand (from my google search) this is a means to keep you from
 shooting yourself in the foot.  But there has got to be a way and I
 really don't want to grovel through the compiler code to find it.  I
 looked at using libelf.so but it also requires that the file be open
 for writing.  So I am kinda of stuck.  If I cannot find a quick solution
 we might need to do all of our signing on our FC11 box which does not
 have this issue.

It's not the compiler code you want to find it, but the install(1)
program that is used to, well, install files into e.g. /bin, /usr/bin,
etc.  What it does is create a temporary file in the directory where
it wants to place the final file, write into the temporary file, and
then, when the file is complete and only when it is complete, it
does a rename(2) syscall, moving the temporary file over the real
one.  If a program (or the kernel) is using the old version of
the real file, its inode and its data blocks are still present on
the disk and they are only deleted when the last consumer closes
the file (or rather, the file descriptor it's holding on that inode).
This also guarantees that anyone who tries to open the file will
only open it when it's ready, and will not try to execute
a partially-written-out executable or something.

So, what you need to do if you want to modify a file is create
a new one in the same directory (well, it's really on the same
filesystem, but the most portable way to ensure that is to
use the same directory - unless you require from the user to
specify a temporary directory you can use on the same filesystem).
Then, read the original file, write into the new one, and when
you're ready, do a rename(tempfile, realfile).

Hope that helps.

G'luck,
Peter

-- 
Peter Pentchev  r...@space.bgr...@ringlet.netr...@freebsd.org
PGP key:http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint FDBA FD79 C26F 3C51 C95E  DF9E ED18 B68D 1619 4553


signature.asc
Description: Digital signature


Re: Modifying ELF files

2010-04-08 Thread Patrick Mahan
 On Thu, 8 Apr 2010, Patrick Mahan wrote:
 
 
  In my job, we are producing applications and KLM's for our product
  that require them to be signed so that our installer will recognize
  and validate our images.
 
  The signature is stored in each app as
 
  unsigned char signature[40] __attribute__((section(.compsign)));
 
  What I need to do is open the file for writing, locate the .compsign
  section and stuff in the signature, write it out and close the file.
  (simple ELF manipulation)
 
  An 'ls -l' shows the following:
 
  % ls compklm.ko
  -rw-r--r--  1 pmahan  pmahan  125296 Apr  6 22:50 
  /home/pmahan/temp/compklm.ko
 
  When I try to run my program
  ./signfile --signature=A203239897C8EB360D1EB2C84E8E77B16E5B7C9A compklm.ko
  open: Text file busy
 
  Googling and looking at the kernel sources, it seems that it detects
  this file contains 'shared text', that is, it is an executable file
  and does not allow me to open it for writing.
 
 My understanding was that ETXTBSY occurs when you attempt to open for 
 writing a file which is actually being executed, i.e. is mapped into some 
 process.  I'm not aware that open(2) actually looks at the file itself to 
 see if it is an executable; that would be very surprising to me.
 
 What does fstat -m compklm.ko say?


% fstat -m compklm.ko
USER CMD  PID   FD MOUNT  INUM MODE SZ|DV R/W NAME
% 
 
 What happens if you cp compklm.ko foo.ko and try to sign foo.ko?  You 
 should then be able to do mv foo.ko compklm.ko; if compklm.ko is 
 in fact mapped into some process, it will continue to use the original 
 version, which will be kept around (invisibly) until all mappings go away. 
 This is what compilers, install(8), etc, normally do.
 
 Does your signfile program do anything with the target file before 
 open(..., O_RDWR)?


I've just found my problem.  We have a wrapper program that basically handles
parsing command line options and is suppose to adjust the argv[] array so
that it only contains the remaining non-option targets starting at index zero.
So I am doing 'open(argv[0], O_RDWR, 0)' expecting it to be the .ko file.
Turns out it was not operating as described (whipping post to be erected later);
so argv[0] actually pointed at the operating program, not the first target past
the cmd line options. *-)

Mystery solved.

Thanks,

Patrick 
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org