From owner-freebsd-hackers@FreeBSD.ORG Thu Apr 8 15:33:32 2010 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C8DD8106566B for ; Thu, 8 Apr 2010 15:33:32 +0000 (UTC) (envelope-from roam@ringlet.net) Received: from erengrad.hoster.bg (erengrad.hoster.bg [77.77.142.9]) by mx1.freebsd.org (Postfix) with ESMTP id 3F9E28FC17 for ; Thu, 8 Apr 2010 15:33:32 +0000 (UTC) Received: from middenheim.hoster.bg (middenheim.hoster.bg [77.77.142.11]) by erengrad.hoster.bg (Postfix) with ESMTP id DAE83DC114 for ; Thu, 8 Apr 2010 18:04:48 +0300 (EEST) Received: from straylight.ringlet.net (office.hoster.bg [78.90.131.77]) (Authenticated sender: roam@hoster.bg) by mail.hoster.bg (Postfix) with ESMTP id 409CB5C344 for ; Thu, 8 Apr 2010 18:04:32 +0300 (EEST) Received: from roam (uid 1000) (envelope-from roam@ringlet.net) id 416035 by straylight.ringlet.net (DragonFly Mail Agent) Thu, 08 Apr 2010 18:03:49 +0300 Date: Thu, 8 Apr 2010 18:03:49 +0300 From: Peter Pentchev To: Patrick Mahan Message-ID: <20100408150349.GA2929@straylight.ringlet.net> Mail-Followup-To: Patrick Mahan , freebsd-hackers@freebsd.org References: <4BBDE58A.9050502@mahan.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="uAKRQypu60I7Lcqm" Content-Disposition: inline In-Reply-To: <4BBDE58A.9050502@mahan.org> User-Agent: Mutt/1.5.20 (2009-06-14) X-MailScanner-ID: 409CB5C344.099DB X-hoster-MailScanner: Found to be clean X-hoster-MailScanner-SpamCheck: not spam, SpamAssassin (cached, score=0.001, required 10, autolearn=disabled, UNPARSEABLE_RELAY 0.00) X-hoster-MailScanner-From: roam@ringlet.net X-hoster-MailScanner-To: freebsd-hackers@freebsd.org X-Spam-Status: No Cc: freebsd-hackers@freebsd.org Subject: Re: Modifying ELF files X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Apr 2010 15:33:33 -0000 --uAKRQypu60I7Lcqm Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Apr 08, 2010 at 07:17:46AM -0700, Patrick Mahan wrote: >=20 > 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. >=20 > The signature is stored in each app as >=20 > unsigned char signature[40] __attribute__((section(".compsign"))); >=20 > 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) >=20 > An 'ls -l' shows the following: >=20 > % ls compklm.ko > -rw-r--r-- 1 pmahan pmahan 125296 Apr 6 22:50 /home/pmahan/temp/compk= lm.ko >=20 > When I try to run my program > ./signfile --signature=3DA203239897C8EB360D1EB2C84E8E77B16E5B7C9A compklm= =2Eko > open: Text file busy >=20 > 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. >=20 > 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 --=20 Peter Pentchev roam@space.bg roam@ringlet.net roam@FreeBSD.org PGP key: http://people.FreeBSD.org/~roam/roam.key.asc Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553 --uAKRQypu60I7Lcqm Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAku98FEACgkQ7Ri2jRYZRVMmDgCgu6YDmd6MOzTFXzO2smG9Zoag WVQAniVWe1CTr2ivnUbLCorQlxQD1kIe =TjRe -----END PGP SIGNATURE----- --uAKRQypu60I7Lcqm--