Module Name:    src
Committed By:   kre
Date:           Thu May 23 11:13:17 UTC 2019

Modified Files:
        src/sbin/mount_portal: pt_file.c puffs_portal.c

Log Message:
PR bin/54222

Don't use portal_node_reclaim() inappropriately.   It frees data we
did not allocate, but which might have been allocated by someone else.

While here, various other cleanups (avoid losing fd's if fork fails,
don't compose mangled st_mode S_IFMT values - puffs or's in what it
thinks is correct to the value we set, one case I saw was producing
0110600 for the mode, the 011 isn't any defined type at all - I'd
never seen ls print a '?' as the first char of ls -l output before!

This is still not really correct, but is I believe, better than before.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sbin/mount_portal/pt_file.c
cvs rdiff -u -r1.9 -r1.10 src/sbin/mount_portal/puffs_portal.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/mount_portal/pt_file.c
diff -u src/sbin/mount_portal/pt_file.c:1.19 src/sbin/mount_portal/pt_file.c:1.20
--- src/sbin/mount_portal/pt_file.c:1.19	Wed May 10 13:58:25 2017
+++ src/sbin/mount_portal/pt_file.c	Thu May 23 11:13:17 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: pt_file.c,v 1.19 2017/05/10 13:58:25 christos Exp $	*/
+/*	$NetBSD: pt_file.c,v 1.20 2019/05/23 11:13:17 kre Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: pt_file.c,v 1.19 2017/05/10 13:58:25 christos Exp $");
+__RCSID("$NetBSD: pt_file.c,v 1.20 2019/05/23 11:13:17 kre Exp $");
 #endif /* not lint */
 
 #include <stdio.h>
@@ -154,7 +154,7 @@ portal_file(struct portal_cred *pcr, cha
 	fd = open(pbuf, O_RDWR | O_CREAT, 0666);
 	if (fd < 0) {
 		error = errno;
-		if (error == EACCES) {
+		if (error == EACCES || error == EISDIR) {
 			DEBUG_SYSLOG(LOG_DEBUG, "Error:  could not open '%s' "
 			    "read/write with create flag.  "
 			    "Trying read-only open...", pbuf);

Index: src/sbin/mount_portal/puffs_portal.c
diff -u src/sbin/mount_portal/puffs_portal.c:1.9 src/sbin/mount_portal/puffs_portal.c:1.10
--- src/sbin/mount_portal/puffs_portal.c:1.9	Wed May 10 16:35:18 2017
+++ src/sbin/mount_portal/puffs_portal.c	Thu May 23 11:13:17 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_portal.c,v 1.9 2017/05/10 16:35:18 christos Exp $	*/
+/*	$NetBSD: puffs_portal.c,v 1.10 2019/05/23 11:13:17 kre Exp $	*/
 
 /*
  * Copyright (c) 2007  Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: puffs_portal.c,v 1.9 2017/05/10 16:35:18 christos Exp $");
+__RCSID("$NetBSD: puffs_portal.c,v 1.10 2019/05/23 11:13:17 kre Exp $");
 #endif /* !lint */
 
 #include <sys/types.h>
@@ -344,17 +344,19 @@ provide(struct puffs_usermount *pu, stru
 
 	switch (fork()) {
 	case -1:
+		close(s[0]); close(s[1]);
 		goto bad;
 	case 0:
+		close(s[0]);
 		error = activate_argv(portc, portn->path, v, &fd);
 		sendfd(s[1], fd, error);
 		exit(0);
 	default:
+		close(s[1]);
 		puffs_framev_addfd(pu, s[0], PUFFS_FBIO_READ);
 		puffs_framev_enqueue_directreceive(pcc, s[0], pufbuf, 0);
 		puffs_framev_removefd(pu, s[0], 0);
 		close(s[0]);
-		close(s[1]);
 
 		if (puffs_framebuf_tellsize(pufbuf) < sizeof(int)) {
 			errno = EIO;
@@ -535,7 +537,7 @@ portal_node_lookup(struct puffs_usermoun
 	return 0;
 }
 
-int fakeid = 3;
+unsigned int fakeid = 3;
 
 /* XXX: libpuffs'ize */
 int
@@ -544,6 +546,7 @@ portal_node_getattr(struct puffs_usermou
 {
 	struct timeval tv;
 	struct timespec ts;
+	int res = 0;
 
 	puffs_vattr_null(va);
 	if (opc == PORTAL_ROOT) {
@@ -551,7 +554,11 @@ portal_node_getattr(struct puffs_usermou
 		va->va_mode = 0777;
 		va->va_nlink = 2;
 		va->va_uid = va->va_gid = 0;
+#if 0	/* XXX Huh? */
 		va->va_fileid = fakeid++;
+#else
+		va->va_fileid = 2;	/*XXX; ROOTINO*/
+#endif
 		va->va_size = va->va_bytes = 0;
 		va->va_gen = 0;
 		va->va_rdev = PUFFS_VNOVAL;
@@ -564,36 +571,55 @@ portal_node_getattr(struct puffs_usermou
 	} else {
 		/* cheat for now */
 		int error;
+		int newfd;
 		struct stat st;
 		struct portal_node *portn = opc;
 		struct portal_cred portc;
 		char **v = conf_match(&q, portn->path);
+
 		if (v == NULL)
 			return ENOENT;
-		credtr(&portc, pcr, 0777);
-		error = provide(pu, portn, &portc, v);
-		if (error)
-			return error;
+		if (portn->fd == -1) {
+			credtr(&portc, pcr, 0777);
+			error = provide(pu, portn, &portc, v);
+			if (error)
+				return error;
+			newfd = 1;
+		} else
+			newfd = 0;
+
 		if (fstat(portn->fd, &st) == -1)
-			return errno;
-		va->va_type = S_ISDIR(st.st_mode) ? VDIR : VREG; /* XXX */
-		va->va_mode = st.st_mode;
-		va->va_nlink = st.st_nlink;
-		va->va_uid = st.st_uid;
-		va->va_gid = st.st_gid;
-		va->va_fileid = st.st_ino;
-		va->va_size = va->va_bytes = st.st_size;
-		va->va_gen = 0;
-		va->va_rdev = st.st_rdev;
-		va->va_blocksize = st.st_blksize;
-		va->va_atime = st.st_atim;
-		va->va_ctime = st.st_ctim;
-		va->va_mtime = st.st_mtim;
-		va->va_birthtime = st.st_birthtim;
-		portal_node_reclaim(pu, opc);
+			res = errno;
+		else {
+#if 0
+			va->va_type = S_ISDIR(st.st_mode) ? VDIR : VREG; /* XXX */
+#else
+			va->va_type = puffs_mode2vt(st.st_mode);
+#endif
+			/* puffs supplies S_IFMT bits later */
+			va->va_mode = (st.st_mode & ~S_IFMT);
+
+			va->va_nlink = st.st_nlink ? st.st_nlink : 1;
+			va->va_uid = st.st_uid;
+			va->va_gid = st.st_gid;
+			va->va_fileid = st.st_ino ? st.st_ino : fakeid++;
+			va->va_size = va->va_bytes = st.st_size;
+			va->va_gen = 0;
+			va->va_rdev = st.st_rdev;
+			va->va_blocksize = st.st_blksize;
+			va->va_atime = st.st_atim;
+			va->va_ctime = st.st_ctim;
+			va->va_mtime = st.st_mtim;
+			va->va_birthtime = st.st_birthtim;
+		}
+		if (newfd) {
+			puffs_framev_removefd(pu, portn->fd, 0);
+			close(portn->fd);
+			portn->fd = -1;
+		}
 	}
 
-	return 0;
+	return res;
 }
 
 /* for writing, just pretend we care */

Reply via email to