From owner-freebsd-ports Tue Oct 8 23:58:10 2002 Delivered-To: freebsd-ports@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E85B837B401 for ; Tue, 8 Oct 2002 23:58:06 -0700 (PDT) Received: from topaz.mdcc.cx (topaz.mdcc.cx [212.204.230.141]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4303743E6A for ; Tue, 8 Oct 2002 23:58:06 -0700 (PDT) (envelope-from edwin@mavetju.org) Received: from k7.mavetju (topaz.mdcc.cx [212.204.230.141]) by topaz.mdcc.cx (Postfix) with ESMTP id 22D412B678 for ; Wed, 9 Oct 2002 08:58:01 +0200 (CEST) Received: by k7.mavetju (Postfix, from userid 1001) id C02486A712B; Wed, 9 Oct 2002 16:57:57 +1000 (EST) Date: Wed, 9 Oct 2002 16:57:57 +1000 From: Edwin Groothuis To: freebsd-ports@freebsd.org Subject: A less exploit vulnerable ports building environment Message-ID: <20021009065757.GA7253@k7.mavetju> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i Sender: owner-freebsd-ports@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Greetings, About two months ago it was the OpenSSH distribution which was trojaned, today it is the Sendmail distribution. Hopefully the 4.7 CD will have the right source-tarball. Anyway, my story. What can been done to the FreeBSD port-system to prevent malicious[sp] code to be run as root? Right now, everything without the ports-system is running as root. Is this required? yes and no. Is it safe? yes and no. Can it be reduced? yes. Is it required to run make as root? For certain parts it is, specially the (un)install-part. For the rest it is not needed. Is it safe to run make as root? It is a matter of trust. For certain parts it is, specially the stuff coming with the ports-framework the level of trust is high: it's coming from a controlled environment. For other parts, like running configure, automake, build and install, it's always "keep fingers crossed and pray". In 99% of the times it will act like it did with the submittor/commitor of the port, for 1% it will not and complain. Worst case scenario it will touch files which it wasn't supposed to touch. Can it be reduced? Yes. There are three moments why you need root-privileges: "make install", "make deinstall" and a less often occuring "make clean". For the rest it's not needed. There are three moments where you don't want root-privileges: "make configure", "make build" and "make install". Why not? Because you're running code not submitted by the ports-system but coming from untrusted sources. In the previous paragraph, you see a clash: you need root-privileges to run "make install" and you don't want root-privileges there because you're running untrusted code. This is not a thing which can be solved. What can be solved is changing everything (except for the three mentions moments) to be non-root. Run everything which is writing in the WRKDIR as an unprivileged user (for example, portbuild). Instead of running things as root, run them as portbuild: .if !target(do-extract) do-extract: @${RM} -rf ${WRKDIR} @${MKDIR} ${WRKDIR} + /usr/bin/su -m portbuild -c "\ for file in ${EXTRACT_ONLY}; do \ echo \$$file; \ if ! (cd ${WRKDIR} && ${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} ${_DISTDIR}/\$$file ${EXTRACT_AFTER_ARGS});\ then \ exit 1; \ fi \ done \ + " .endif This approach (i.e. su when going into the WRKDIR) looks good, but it won't work because the user can override the targets and play around as root again. The right approach would be to put a wrapper around the targets which shouldn't be ran as root. (See Skeleton targets in bsd.port.mk): _FETCH_SEQ= pre-everything fetch-depends pre-fetch pre-fetch-script \ do-fetch post-fetch post-fetch-script + _FETCH_WRAP= _EXTRACT_DEP= fetch _EXTRACT_SEQ= extract-message checksum build-depends lib-depends \ misc-depends pre-extract pre-extract-script do-extract \ post-extract post-extract-script + _EXTRACT_WRAP= pre-extract pre-extract-script do-extract post-extract \ + post-extract-script _PATCH_DEP= extract _PATCH_SEQ= patch-message pre-patch pre-patch-script do-patch \ post-patch post-patch-script + _PATCH_WRAP= pre-patch pre-patch-script do-patch post-patch \ + post-patch-script _CONFIGURE_DEP= patch _CONFIGURE_SEQ= configure-message patch-libtool pre-configure \ pre-configure-script do-configure post-configure \ post-configure-script + _CONFIGURE_WRAP=pre-configure pre-configure-script do-configure \ + post-configure post-configure-script _BUILD_DEP= configure _BUILD_SEQ= build-message pre-build pre-build-script do-build \ post-build post-build-script + _BUILD_WRAP= pre-build pre-build-script do-build post-build \ + post-build-script _INSTALL_DEP= build _INSTALL_SEQ= install-message check-categories check-already-installed \ check-umask run-depends lib-depends install-mtree pre-install \ pre-install-script do-install generate-plist post-install \ post-install-script compress-man run-ldconfig fake-pkg \ security-check + _INSTALL_WRAP= _PACKAGE_DEP= install _PACKAGE_SEQ= package-message pre-package pre-package-script \ do-package post-package-script _PACKAGE_WRAP= replace all the ones in _SEQ which are in _WRAP so that they can be wrapped: .for target in extract patch configure build install package . for wrap in ${_${target:U}_WRAP} _${target:U}_SEQ:= ${_${target:U}_SEQ:S/^${wrap}$/wrap-&/} . endfor .endfor And create wrappers for them: .for target in extract patch configure build install package . if ${_${target:U}_WRAP:Mdo-${target}}!="" wrap-do-${target}: @echo Wrapping do-${target} @${SU} portbuild -c "${MAKE} do-${target}" . endif .endfor .for stage in pre post . for name in fetch extract patch configure build install package . if ${_${name:U}_WRAP:M${stage}-${name}}!="" wrap-${stage}-${name}: @echo Wrapping ${stage}-${name} @${SU} portbuild -c "${MAKE} ${stage}-${name}" . endif . if ${_${name:U}_WRAP:M${stage}-${name}-script}!="" wrap-${stage}-${name}-script: @echo Wrapping ${stage}-${name}-script @${SU} portbuild -c "${MAKE} ${stage}-${name}-script" . endif . endfor .endfor With this approach the amount of time the building of a port as root is reduced with (right now) the bigger part of extract, patch, configure and build. I've been running a what more optimized version than described at home and except for some warnings regarding permissions of files in tarballs I didn't encounter much problems. I'll keep running it for a week and then submit it as a patch. Hmm... this has taken more time (and lines in this email) than I hoped for. Comments anyone? Edwin -- Edwin Groothuis | Personal website: http://www.MavEtJu.org edwin@mavetju.org | Weblog: http://www.mavetju.org/weblog/weblog.php bash$ :(){ :|:&};: | Interested in MUDs? http://www.FatalDimensions.org/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ports" in the body of the message