On Tue, 22 Jun 1999, Brian F. Feldman wrote: > Date: Tue, 22 Jun 1999 01:08:04 -0400 (EDT) > From: Brian F. Feldman <gr...@unixhelp.org> > To: Kris Kennaway <kkenn...@physics.adelaide.edu.au> > Cc: Peter Wemm <pe...@netplex.com.au>, Jean-Marc Zucconi <j...@freebsd.org>, h...@freebsd.org, cvs-committ...@freebsd.org, cvs-...@freebsd.org > Subject: Re: cvs commit: src/sys/kern imgact_gzip.c > > On Tue, 22 Jun 1999, Kris Kennaway wrote: > > > On Tue, 22 Jun 1999, Peter Wemm wrote: > > > > > Ahh yes, I forgot that / was read-write for MFS boots. However: > > > > > > #!/bin/sh > > > skip=18 > > > if /usr/bin/tail +$skip $0 | gzip -cd > /tmp/gztmp$$; then > > > chmod 700 /tmp/gztmp$$ > > > prog="`echo $0 | sed 's|^.*/||'`" > > > if /bin/ln /tmp/gztmp$$ "/tmp/$prog" 2>/dev/null; then > > > trap '/bin/rm -f /tmp/gztmp$$ "/tmp/$prog"; exit $res' 0 > > > (/bin/sleep 5; /bin/rm -f /tmp/gztmp$$ "/tmp/$prog") 2>/dev/null & > > > /tmp/"$prog" ${1+"$@"}; res=$? > > > else > > > trap '/bin/rm -f /tmp/gztmp$$; exit $res' 0 > > > (/bin/sleep 5; /bin/rm -f /tmp/gztmp$$) 2>/dev/null & > > > /tmp/gztmp$$ ${1+"$@"}; res=$? > > > fi > > > else > > > echo Cannot decompress $0; exit 1 > > > fi; exit $res > > > > This is the unpatched (insecure) version of gzexe (all the /tmp/gztmp$$'s), > > but it's functionally the same. > > > > > Now, if tail, sh, gzip, chmod, ln, sleep, rm, etc are all in the gzexe'd > > > crunched linked binary, how is it supposed to decompress itself? "sh" > > > itself > > > is part of the crunched binary, so what is going to decode sh when sh > > > itself > > > is a shell script? > > > > Yes, that seems to be a problem - gzexe depends on those executables. > > However > > it shouldn't be too hard to recode this decompressor in C to perform the > > same > > job without any external dependencies. The question is whether that would be > > easier than fixing the kernel to handle gzipped ELF binaries transparently - > > almost certainly it would be. > > How's what I attached?
[Context left in for cross-post to hackers] Hmm..I don't have a deflate on my system. This should be linked static as well, otherwise you need the runtime linker + libraries, and that has a 69k overhead (when stripped). Possibly this could be optimized further..I don't know if this is small enough to be useful however. Mike's suggestion of a gzipped MFS image is probably best for things like boot floppies. Kris > Brian Fundakowski Feldman _ __ ___ ____ ___ ___ ___ > gr...@freebsd.org _ __ ___ | _ ) __| \ > FreeBSD: The Power to Serve! _ __ | _ \._ \ |) | > http://www.FreeBSD.org/ _ |___/___/___/ > ----- "Never criticize anybody until you have walked a mile in their shoes, because by that time you will be a mile away and have their shoes." -- Unknown
#!/bin/sh of=`basename $1`_z cs=$of.c cat > $cs << . #include <sys/types.h> #include <sys/mman.h> #include <sys/wait.h> #include <sys/stat.h> #include <zlib.h> #include <err.h> #include <unistd.h> #include <stdio.h> $(deflate < $1 | file2c 'u_char program[] = { ' ' };') int main(int argc, char **argv) { int status; u_long destLen = sizeof(program); void *outputaddr; char outputname[256]; int outputfd; snprintf(outputname, sizeof(outputname), "%s.XXXXXX", argv[0]); if ((outputfd = mkstemp(outputname)) == -1) err(1, "mkstemp"); outputaddr = mmap(NULL, destLen, PROT_WRITE, MAP_SHARED, outputfd, 0); if (outputaddr == MAP_FAILED) err(1, "mmap"); status = uncompress(outputaddr, &destLen, program, sizeof(program)); switch (status) { case Z_MEM_ERROR: err(1, "Z_MEM_ERROR"); case Z_BUF_ERROR: err(1, "Z_BUF_ERROR"); case Z_DATA_ERROR: err(1, "Z_DATA_ERROR"); default: break; } msync(outputaddr, 0, MS_SYNC); munmap(outputaddr, destLen); ftruncate(outputfd, destLen); fchmod(outputfd, 0755); close(outputfd); switch (fork()) { case 0: execv(outputname, argv); case -1: err(1, "fork"); default: wait(&status); } unlink(outputname); exit(status); } . cc -lz -O -Wall $cs -o $of rm $cs