ref: 6eed7a47863553bab31c7f9b1b5b314989efc640
parent: 40706d95cc2b75ab68033a14118e35d93eefc65d
author: Jacob Moody <moody@posixcafe.org>
date: Sat Jul 29 15:20:04 EDT 2023
kernel: make walk/open errors more consistent with userspace As is the error for an open would be in the form: 'filename' does not exist This changes it to be of the form: file does not exist: 'filename' This brings it more in line with what could be expected from a userspace filesystem. Existing code, perhaps due to this discrepancy, all uses strstr to check for this error. They can now instead check for explicitly the error as a prefix. This would avoid issues with potentially maliciously named files such as "does not exist". Likewise this also helps filesystems such as exportfs, which spit back the errstr from open(2) directly as Rerror to their clients.
--- a/sys/src/9/port/chan.c
+++ b/sys/src/9/port/chan.c
@@ -950,7 +950,6 @@
* Either walks all the way or not at all. No partial results in *cp.
* *nerror is the number of names to display in an error message.
*/
-static char Edoesnotexist[] = "does not exist";
int
walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
{
@@ -1066,7 +1065,7 @@
if(wq->nqid == 0 || (wq->qid[wq->nqid-1].type&QTDIR) != 0){
if(nerror)
*nerror = nhave+wq->nqid+1;
- kstrcpy(up->errstr, Edoesnotexist, ERRMAX);
+ kstrcpy(up->errstr, Enonexist, ERRMAX);
}else{
if(nerror)
*nerror = nhave+wq->nqid;
@@ -1204,7 +1203,7 @@
}
}
-static void
+void
namelenerror(char *aname, int len, char *err)
{
char *ename, *name, *next;
@@ -1247,14 +1246,8 @@
snprint(up->genbuf, sizeof up->genbuf, "...%.*s",
utfnlen(name, ename-name), name);
}
- snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, err);
+ snprint(up->errstr, ERRMAX, "%s: %#q", err, up->genbuf);
nexterror();
-}
-
-void
-nameerror(char *name, char *err)
-{
- namelenerror(name, strlen(name), err);
}
/*
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -206,7 +206,7 @@
void mul64fract(uvlong*, uvlong, uvlong);
void muxclose(Mnt*);
Chan* namec(char*, int, int, ulong);
-void nameerror(char*, char*);
+void namelenerror(char*, int, char*);
int needpages(void*);
Chan* newchan(void);
int newfd(Chan*, int);
--- a/sys/src/9/port/sysfile.c
+++ b/sys/src/9/port/sysfile.c
@@ -1233,6 +1233,7 @@
{
long l;
int namelen;
+ char *p;
if(waserror()){
cclose(c);
@@ -1244,8 +1245,10 @@
* (which should be renamed? the mount point or the mounted Chan?).
*/
dirname(d, &namelen);
- if(namelen)
- nameerror(chanpath(c), Eismtpt);
+ if(namelen){
+ p = chanpath(c);
+ namelenerror(p, strlen(p), Eismtpt);
+ }
}
l = devtab[c->type]->wstat(c, d, nd);
poperror();