From owner-freebsd-bugs@FreeBSD.ORG Wed Nov 10 15:50:31 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C3CB216A4D0 for ; Wed, 10 Nov 2004 15:50:31 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9AE5343D48 for ; Wed, 10 Nov 2004 15:50:31 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id iAAFoVkj078720 for ; Wed, 10 Nov 2004 15:50:31 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id iAAFoVlm078719; Wed, 10 Nov 2004 15:50:31 GMT (envelope-from gnats) Resent-Date: Wed, 10 Nov 2004 15:50:31 GMT Resent-Message-Id: <200411101550.iAAFoVlm078719@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Andriy Gapon Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 213BC16A4D0 for ; Wed, 10 Nov 2004 15:46:30 +0000 (GMT) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5413843D4C for ; Wed, 10 Nov 2004 15:44:43 +0000 (GMT) (envelope-from avg@oddity.topspin.kiev.ua) Received: from oddity.topspin.kiev.ua (oddity.topspin.kiev.ua [212.40.38.87]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id RAA05217 for ; Wed, 10 Nov 2004 17:19:17 +0200 (EET) (envelope-from avg@oddity.topspin.kiev.ua) Received: from oddity.topspin.kiev.ua (localhost [127.0.0.1]) iAAFJGpb006683 for ; Wed, 10 Nov 2004 17:19:16 +0200 (EET) (envelope-from avg@oddity.topspin.kiev.ua) Received: (from avg@localhost) by oddity.topspin.kiev.ua (8.12.10/8.12.10/Submit) id iAAFJGbf006682; Wed, 10 Nov 2004 17:19:16 +0200 (EET) (envelope-from avg) Message-Id: <200411101519.iAAFJGbf006682@oddity.topspin.kiev.ua> Date: Wed, 10 Nov 2004 17:19:16 +0200 (EET) From: Andriy Gapon To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: kern/73777: linux emulation: root dir special handling useless and harmful X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Nov 2004 15:50:31 -0000 >Number: 73777 >Category: kern >Synopsis: linux emulation: root dir special handling useless and harmful >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Nov 10 15:50:29 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Andriy Gapon >Release: FreeBSD 5.2.1-RELEASE-p11 i386 >Organization: >Environment: System: FreeBSD 4.X, 5.X linux_base-7.1_7 >Description: A little background: in linux emulation any access to file system node is first tried with "/compt/linux" prepended to its path, original path is tried only if linuxified path is not vaiable. In that fashion linux applications can access both files under linux emulation root (/compat/linux) and those files under the real root that are not shadowed by the former files. This behavior is reverted only for one filesystem node - "/compat/linux" itself. That is, no application under linux emualtion is able to access linux compatibility root, real root ("/") is given to it instead. This seems to be illogical, linux application is probably more ineterested in linux root directory rather than real root directory. Also, no linux application should ever want to "break out" from linux root by "cd ..". So I think that the special handling for root directories should be removed and real root directory should be shadowed by /compat/linux. Existing linux emulation behavior also breaks "mkdir -p" from linux base 7, if you want to creat a directory with more than one path unexstistant component: in this case mkdir first performs chdir("/") and then iterativly mkdir()s and chdir()s to subdirectories. So, the first action, chdir("/") would chdir to real root and directory created either will be wrong one or will not be created at all because of permissions. Please also see my attemps to discuss this issue on mailing lists: http://docs.freebsd.org/cgi/mid.cgi?4178DBA0.8050605 http://docs.freebsd.org/cgi/mid.cgi?4176A6C0.5070408 I have applied the patch attached on my system and have not seen any problems with linux emulation, only improvements. I run oracle 9, ibm websphere 5.1 with mq and wemps. >How-To-Repeat: 1. work as unpriviledged user with shell /compat/linux/bin/bash 2. make sure /var and /compat/linux/var are different directories 3. create /compat/linux/var/foo directory with rwx permission for the user mentioned in step 1. 4. make sure there is no /var/foo directory 5. execute "mkdir -p /var/foo/1/2/3" as user from step 1. 6. see the above command fail with permission denied error 7. apply the attached patch 8. recompile kernel and/or linux.ko, reboot 9. try the same again 10. see successful creation of expected directory >Fix: --- rootdir.patch begins here --- --- sys/compat/linux/linux_util.c.orig Sun Nov 7 15:34:58 2004 +++ sys/compat/linux/linux_util.c Sun Nov 7 15:53:20 2004 @@ -95,9 +95,6 @@ int cflag; { struct nameidata nd; - struct nameidata ndroot; - struct vattr vat; - struct vattr vatroot; int error; const char *prefix; char *ptr, *buf, *cp; @@ -150,55 +147,12 @@ if ((error = namei(&nd)) != 0) goto keeporig; - - /* - * We now compare the vnode of the linux_root to the one - * vnode asked. If they resolve to be the same, then we - * ignore the match so that the real root gets used. - * This avoids the problem of traversing "../.." to find the - * root directory and never finding it, because "/" resolves - * to the emulation root directory. This is expensive :-( - */ - NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path, - td); - - if ((error = namei(&ndroot)) != 0) { - /* Cannot happen! */ - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); - goto keeporig; - } - - if ((error = VOP_GETATTR(nd.ni_vp, &vat, td->td_ucred, td)) != 0) { - goto bad; - } - - if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td->td_ucred, td)) - != 0) { - goto bad; - } - - if (vat.va_fsid == vatroot.va_fsid && - vat.va_fileid == vatroot.va_fileid) { - error = ENOENT; - goto bad; - } - } NDFREE(&nd, NDF_ONLY_PNBUF); vrele(nd.ni_vp); - if (!cflag) { - NDFREE(&ndroot, NDF_ONLY_PNBUF); - vrele(ndroot.ni_vp); - } return error; -bad: - NDFREE(&ndroot, NDF_ONLY_PNBUF); - vrele(ndroot.ni_vp); - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); keeporig: /* Keep the original path; copy it back to the start of the buffer. */ bcopy(ptr, buf, len); --- rootdir.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted: