Re: nfs sub-mounts [TEST PATCH]

G. Allen Morris III (gam3@dharma.sehda.com)
Tue, 27 Oct 1998 00:41:37 -0800


This is a multipart MIME message.

--==_Exmh_-8164710320
Content-Type: text/plain; charset=us-ascii

Here is a patch that makes sub-mounts on knfsd work approximatly the
same as unfsd.

With this patch you can't mount files that have a directory that
is not readble by nobody (if root_squash is on). Mount seems to
fail if it can't get permisions for the root of the filesystem
being mounted.

Allen

---------------------------------
G. Allen Morris III

--==_Exmh_-8164710320
Content-Type: application/x-patch ; name="nfsd-2.1.126-1.patch"
Content-Description: nfsd-2.1.126-1.patch
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="nfsd-2.1.126-1.patch"

Index: linux/fs/nfsd/auth.c
diff -u linux/fs/nfsd/auth.c:1.1 linux/fs/nfsd/auth.c:1.1.2.1
--- linux/fs/nfsd/auth.c:1.1 Fri Oct 16 12:08:05 1998
+++ linux/fs/nfsd/auth.c Mon Oct 26 22:21:59 1998
@@ -43,5 +43,14 @@
current->fsgid =3D exp->ex_anon_gid;
for (i =3D 0; i < NGROUPS; i++)
current->groups[i] =3D cred->cr_groups[i];
+
+ if ((cred->cr_uid)) {
+ cap_lower(current->cap_effective, CAP_DAC_OVERRIDE);
+ cap_lower(current->cap_effective, CAP_DAC_READ_SEARCH);
+ } else {
+ cap_raise(current->cap_effective, CAP_DAC_OVERRIDE);
+ cap_raise(current->cap_effective, CAP_DAC_READ_SEARCH);
+ }
+
rqstp->rq_userset =3D 1;
}
Index: linux/fs/nfsd/export.c
diff -u linux/fs/nfsd/export.c:1.5 linux/fs/nfsd/export.c:1.1.2.9
--- linux/fs/nfsd/export.c:1.5 Sat Oct 24 11:36:37 1998
+++ linux/fs/nfsd/export.c Fri Oct 23 10:22:54 1998
@@ -457,14 +457,17 @@
char *path, struct knfs_fh *f)
{
struct svc_export *exp;
- struct dentry *dentry;
+ struct dentry *dentry =3D NULL;
struct inode *inode;
struct svc_fh fh;
int err;
=

+ err =3D -EPERM;
if (path) {
- dentry =3D lookup_dentry(path, NULL, 0);
-
+ if (!(dentry =3D lookup_dentry(path, NULL, 0))) {
+ printk("nfsd: exp_rootfh path not found %s", path);
+ return -EPERM;
+ }
dev =3D dentry->d_inode->i_dev;
ino =3D dentry->d_inode->i_ino;
=

@@ -474,17 +477,21 @@
} else {
dprintk("nfsd: exp_rootfh(%s:%x/%ld)\n",
clp->cl_ident, dev, ino);
- exp =3D exp_get(clp, dev, ino);
- dentry =3D dget(exp->ex_dentry);
+ if ((exp =3D exp_get(clp, dev, ino)))
+ if (!(dentry =3D dget(exp->ex_dentry))) {
+ printk("exp_rootfh: Aieee, NULL dentry\n");
+ return -EPERM;
+ }
}
- err =3D -EPERM;
- if (!exp)
+ if (!exp) {
+ dprintk("nfsd: exp_rootfh export not found.\n");
goto out;
+ }
=

inode =3D dentry->d_inode;
if (!inode) {
printk("exp_rootfh: Aieee, NULL d_inode\n");
- return -EPERM;
+ goto out;
}
if (inode->i_dev !=3D dev || inode->i_ino !=3D ino) {
printk("exp_rootfh: Aieee, ino/dev mismatch\n");
Index: linux/fs/nfsd/nfsfh.c
diff -u linux/fs/nfsd/nfsfh.c:1.2 linux/fs/nfsd/nfsfh.c:1.1.2.6
--- linux/fs/nfsd/nfsfh.c:1.2 Sat Oct 24 11:36:37 1998
+++ linux/fs/nfsd/nfsfh.c Mon Oct 26 23:25:40 1998
@@ -1061,31 +1061,6 @@
goto out;
=

/*
- * Security: Check that the export is valid for dentry <gam3@acm.org>
- */
- if (fh->fh_dev !=3D fh->fh_xdev) {
- printk("fh_verify: Security: export on other device"
- " (%d, %d).\n", fh->fh_dev, fh->fh_xdev);
- goto out;
- } else {
- struct dentry *tdentry =3D dentry;
-
- do {
- if (exp->ex_dentry =3D=3D tdentry) {
- error =3D 0;
- break;
- }
- if (tdentry->d_parent =3D=3D tdentry)
- break;
- } while ((tdentry =3D tdentry->d_parent));
- if (error) {
- printk("fh_verify: Security: %s/%s bad export.\n",
- dentry->d_parent->d_name.name,
- dentry->d_name.name);
- goto out;
- }
- }
- /*
* Note: it's possible the returned dentry won't be the one in the
* file handle. We can correct the file handle for our use, but
* unfortunately the client will keep sending the broken one. Let's
@@ -1105,6 +1080,7 @@
check_type:
dentry =3D fhp->fh_dentry;
inode =3D dentry->d_inode;
+ exp =3D fhp->fh_export;
if (type > 0 && (inode->i_mode & S_IFMT) !=3D type) {
error =3D (type =3D=3D S_IFDIR)? nfserr_notdir : nfserr_isdir;
goto out;
@@ -1114,9 +1090,45 @@
goto out;
}
=

+ /*
+ * Security: Check that the export is valid for dentry <gam3@acm.org>
+ */
+ if (fh->fh_dev !=3D fh->fh_xdev) {
+ printk("fh_verify: Security: export on other device"
+ " (%d, %d).\n", fh->fh_dev, fh->fh_xdev);
+ goto out;
+ } else if (exp->ex_dentry !=3D dentry) {
+ struct dentry *tdentry =3D dentry;
+ int err2 =3D 0;
+
+ error =3D nfserr_stale;
+ do {
+ tdentry =3D tdentry->d_parent;
+ if (exp->ex_dentry =3D=3D tdentry) {
+ error =3D 0;
+ break;
+ }
+ if ((err2 =3D nfsd_permission(exp, tdentry, MAY_READ))) {
+ error =3D err2;
+#ifdef NFSD_PARANOIA
+ goto out1;
+#else
+ goto out;
+#endif
+ }
+ } while ((tdentry !=3D tdentry->d_parent));
+ if (error) {
+ printk("fh_verify: Security: %s/%s bad export.\n",
+ dentry->d_parent->d_name.name,
+ dentry->d_name.name);
+ goto out;
+ }
+ }
+
/* Finally, check access permissions. */
- error =3D nfsd_permission(fhp->fh_export, dentry, access);
+ error =3D nfsd_permission(exp, dentry, access);
#ifdef NFSD_PARANOIA
+out1:
if (error)
printk("fh_verify: %s/%s permission failure, acc=3D%x, error=3D%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name, access, error);

--==_Exmh_-8164710320--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/