ref: 1f0e8358d456f48f0b00fbb63abea11bee1ce612
parent: 57fdb807f713ef11c66ee904eea35695f42071e8
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
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);