shithub: 9pro

Download patch

ref: 1f0e8358d456f48f0b00fbb63abea11bee1ce612
parent: 57fdb807f713ef11c66ee904eea35695f42071e8
author: Sigrid Haflínudóttir <[email protected]>
date: Tue Dec 24 09:30:06 EST 2019

handle permission bits

--- a/9pex.c
+++ b/9pex.c
@@ -306,6 +306,28 @@
 	return -1;
 }
 
+static int
+hasperm(struct stat *st, C9mode mode, char **err)
+{
+	int m, stm, fmt;
+
+	m = mode & 0xf;
+	stm = st->st_mode & 0777;
+	*err = Eperm;
+	if (((stm & 0111) == 0 || (stm & 0444) == 0) && m == C9exec) /* executing needs rx */
+		return 0;
+	if ((stm & 0222) == 0 && (m == C9write || m == C9rdwr)) /* writing needs w */
+		return 0;
+	if ((stm & 0444) == 0 && m != C9write) /* reading needs r */
+		return 0;
+	fmt = st->st_mode & S_IFMT;
+	if (fmt == S_IFDIR && ((stm & 0111) == 0 || (stm & 0444) == 0)) /* dirs need rx */
+		return 0;
+	*err = NULL;
+
+	return 1;
+}
+
 static Fid *
 walk(C9fid fid, C9fid nfid, char *el[], C9qid *qids[], char **err)
 {
@@ -352,6 +374,9 @@
 
 		if (statpath(p, &st, err) != 0)
 			break;
+		if (el[i+1] != NULL && !hasperm(&st, C9read, err))
+			break;
+
 		qids[i] = &walkqids[i];
 		stat2qid(&st, qids[i], NULL);
 	}
@@ -388,8 +413,9 @@
 		f->fd = open(f->path, omode);
 	}
 
-	if (f->fd < 0 || fstat(f->fd, &st) != 0) {
-		*err = strerror(errno);
+	if (f->fd < 0 || fstat(f->fd, &st) != 0 || !hasperm(&st, mode, err)) {
+		if (*err == NULL)
+			*err = strerror(errno);
 
 		if (f->dir != NULL)
 			closedir(f->dir);