ref: 746e0c9217ab9ee1884b721a955b712d59b13549
parent: fe54357c8428219c5a27c4cbbebc8d49cc29bdf7
author: halfwit <michaelmisch1985@gmail.com>
date: Sun Nov 23 21:24:58 EST 2025
Some larger changes to get factotum at least spinning up
--- a/TODO
+++ b/TODO
@@ -7,6 +7,7 @@
- [ ] define the gui interface
- [ ] Fully fledged note handling
- [x] up->parent integration into /proc
+ - [ ] Un-stub stub.c things
Kernel space needs:
- [x] devcmd - #C: OS(1) commands, we already run on host
@@ -14,6 +15,7 @@
- [x] devenv - #e:/env
- [x] devfs - #U: needed, local files
- [x] devip - #I: needed, networking
+ - [ ] /net/icmpv6 and friends
- [x] devlfd - #L: needed, local fd
- [x] devmnt - #M: needed, client shares
- [x] devpipe - #|: needed, for pipes
@@ -22,3 +24,4 @@
- [x] devtls - #a: needed, tls
- [ ] devproc - #p: needed, /proc, overlay any existing
- [x] devtab - # meta: needed add/remove any devices that we add/remove, from here as well
+ - [ ] devcap - #¤: needed, caphash/capuse for factotum
--- a/kern/Makefile
+++ b/kern/Makefile
@@ -10,6 +10,7 @@
chan.$O\
data.$O\
dev.$O\
+ devcap.$O\
devcmd.$O\
devcons.$O\
devenv.$O\
--- a/kern/dat.h
+++ b/kern/dat.h
@@ -1,6 +1,6 @@
#define KNAMELEN 28 /* max length of name held in kernel */
-//#define BLOCKALIGN 8
+#define BLOCKALIGN 8
typedef struct Block Block;
typedef struct Chan Chan;
typedef struct Cmdbuf Cmdbuf;
--- /dev/null
+++ b/kern/devcap.c
@@ -1,0 +1,287 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+
+#include <libsec.h>
+
+enum
+{+ Hashlen= SHA1dlen,
+ Maxhash= 256,
+ Timeout= 60, /* seconds */
+};
+
+/*
+ * if a process knows cap->cap, it can change user
+ * to capabilty->user.
+ */
+typedef struct Caphash Caphash;
+struct Caphash
+{+ Caphash *next;
+ ulong ticks;
+ char hash[Hashlen];
+};
+
+static struct
+{+ QLock lk;
+ Caphash *first;
+ int nhash;
+} capalloc;
+
+enum
+{+ Qdir,
+ Qhash,
+ Quse,
+};
+
+/* caphash must be last */
+Dirtab capdir[] =
+{+ ".", {Qdir,0,QTDIR}, 0, DMDIR|0500,+ "capuse", {Quse}, 0, 0222,+ "caphash", {Qhash}, 0, 0200,+};
+int ncapdir = nelem(capdir);
+
+static Chan*
+capattach(char *spec)
+{+ return devattach(L'¤', spec);
+}
+
+static Walkqid*
+capwalk(Chan *c, Chan *nc, char **name, int nname)
+{+ return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
+}
+
+static void
+capremove(Chan *c)
+{+ if(iseve() && c->qid.path == Qhash)
+ ncapdir = nelem(capdir)-1;
+ else
+ error(Eperm);
+}
+
+
+static int
+capstat(Chan *c, uchar *db, int n)
+{+ return devstat(c, db, n, capdir, ncapdir, devgen);
+}
+
+/*
+ * if the stream doesn't exist, create it
+ */
+static Chan*
+capopen(Chan *c, int omode)
+{+ if(c->qid.type & QTDIR){+ if(omode != OREAD)
+ error(Ebadarg);
+ c->mode = omode;
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+ }
+
+ switch((ulong)c->qid.path){+ case Qhash:
+ if(!iseve())
+ error(Eperm);
+ break;
+ }
+
+ c->mode = openmode(omode);
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+}
+
+static void
+trimcaps(void)
+{+ Caphash *t;
+ return;
+ while((t = capalloc.first) != nil){+ //if(capalloc.nhash < Maxhash && TK2SEC(MACHP(0)->ticks - t->ticks) < Timeout)
+ // break;
+ capalloc.nhash--;
+ capalloc.first = t->next;
+ secfree(t);
+ }
+}
+
+static Caphash*
+remcap(uchar *hash)
+{+ Caphash *t, **l;
+
+ qlock(&capalloc.lk);
+
+ /* timeout old caps */
+ trimcaps();
+
+ /* find the matching capability */
+ for(l = &capalloc.first; *l != nil;){+ t = *l;
+ if(tsmemcmp(hash, t->hash, Hashlen) == 0)
+ break;
+ l = &t->next;
+ }
+ t = *l;
+ if(t != nil){+ capalloc.nhash--;
+ *l = t->next;
+ }
+ qunlock(&capalloc.lk);
+
+ return t;
+}
+
+/* add a capability, throwing out any old ones */
+static void
+addcap(uchar *hash)
+{+ Caphash *p, **l;
+
+ p = secalloc(sizeof *p);
+ memmove(p->hash, hash, Hashlen);
+ p->next = nil;
+ //p->ticks = MACHP(0)->ticks;
+
+ qlock(&capalloc.lk);
+
+ /* make room for one extra */
+ trimcaps();
+
+ /* add new one */
+ for(l = &capalloc.first; *l != nil; l = &(*l)->next)
+ ;
+ *l = p;
+ capalloc.nhash++;
+
+ qunlock(&capalloc.lk);
+}
+
+static void
+capclose(Chan* c)
+{+ USED(c);
+}
+
+static long
+capread(Chan *c, void *va, long n, vlong d)
+{+ USED(d);
+
+ switch((ulong)c->qid.path){+ case Qdir:
+ return devdirread(c, va, n, capdir, ncapdir, devgen);
+
+ default:
+ error(Eperm);
+ break;
+ }
+ return -1;
+}
+
+static long
+capwrite(Chan *c, void *va, long n, vlong d)
+{+ USED(d);
+ Caphash *p;
+ char *cp;
+ uchar hash[Hashlen];
+ char *key, *from, *to;
+ char err[256];
+
+ switch((ulong)c->qid.path){+ case Qhash:
+ if(!iseve())
+ error(Eperm);
+ if(n < Hashlen)
+ error(Eshort);
+ memmove(hash, va, Hashlen);
+ addcap(hash);
+ break;
+
+ case Quse:
+ if((ulong)n >= 1024)
+ error(Etoobig);
+ /* copy key to avoid a fault in hmac_xx */
+ cp = secalloc(n+1);
+ if(waserror()){+ secfree(cp);
+ nexterror();
+ }
+ memmove(cp, va, n);
+ cp[n] = 0;
+
+ from = cp;
+ key = strrchr(cp, '@');
+ if(key == nil)
+ error(Eshort);
+ *key++ = 0;
+
+ hmac_sha1((uchar*)from, strlen(from), (uchar*)key, strlen(key), hash, nil);
+
+ /* if a from user is supplied, make sure it matches */
+ to = strchr(from, '@');
+ if(to == nil){+ to = from;
+ } else {+ *to++ = 0;
+ if(strcmp(from, up->user) != 0)
+ error("capability must match user");+ }
+
+ p = remcap(hash);
+ if(p == nil){+ snprint(err, sizeof err, "invalid capability %s@%s", from, key);
+ error(err);
+ }
+ secfree(p);
+ strcpy(up->user, to);
+ //procsetuser(to);
+
+ secfree(cp);
+ poperror();
+ break;
+
+ default:
+ error(Eperm);
+ break;
+ }
+ memset(hash, 0, Hashlen);
+
+ return n;
+}
+
+Dev capdevtab = {+ L'¤',
+ "cap",
+
+ devreset,
+ devinit,
+ devshutdown,
+ capattach,
+ capwalk,
+ capstat,
+ capopen,
+ devcreate,
+ capclose,
+ capread,
+ devbread,
+ capwrite,
+ devbwrite,
+ capremove,
+ devwstat
+};
\ No newline at end of file
--- a/kern/devproc.c
+++ b/kern/devproc.c
@@ -77,7 +77,7 @@
Dirtab procdir[] =
{ "args", {Qargs}, 0, 0660,- "ctl", {Qctl}, 0, 0000,+ "ctl", {Qctl}, 0, 0660, // So, this is not ideal but it will let us at least spin up our factotum "fd", {Qfd}, 0, 0444, "note", {Qnote}, 0, 0000, "noteid", {Qnoteid}, 0, 0664,@@ -467,8 +467,8 @@
break;
case Qnotepg:
- //if(p->kp || omode != OWRITE)
- // error(Eperm);
+ if(p->kp || omode != OWRITE)
+ error(Eperm);
//pid = p->noteid;
break;
@@ -935,7 +935,6 @@
}
ct = lookupcmd(cb, proccmd, nelem(proccmd));
-
switch(ct->index){case CMclose:
procctlclosefiles(p, 0, atoi(cb->f[1]));
--- a/kern/devtab.c
+++ b/kern/devtab.c
@@ -17,6 +17,7 @@
extern Dev cmddevtab;
extern Dev envdevtab;
extern Dev procdevtab;
+extern Dev capdevtab;
Dev *devtab[] = {&rootdevtab,
@@ -32,6 +33,7 @@
&cmddevtab,
&envdevtab,
&procdevtab,
+ &capdevtab,
0
};
--- a/main.c
+++ b/main.c
@@ -63,6 +63,37 @@
return;
}
+static void
+envinit(char *nvram)
+{+ int fd, nvrlen;
+
+ /* We want to set up our env based on some details here
+ * nvram, nvroff, nvrlen, cputype
+ */
+ if((fd = create("/env/nvram", ORDWR, 0666)) < 0)+ panic("open env/nvram: %r");+ fprint(fd, "%s", nvram);
+ nvrlen = seek(fd, 0, SEEK_END);
+ close(fd);
+
+ if((fd = create("/env/nvroff", ORDWR, 0666)) < 0)+ panic("open env/nvroff: %r");+ fprint(fd, "0");
+ close(fd);
+
+ if((fd = create("/env/nvrlen", ORDWR, 0666)) < 0)+ panic("open env/nvrlen: %r");+ fprint(fd, "%d", nvrlen);
+ close(fd);
+
+
+ if((fd = create("/env/cputype", ORDWR, 0666)) < 0)+ panic("open env/cputype: %r");+ fprint(fd, "arm");
+ close(fd);
+}
+
void
dump(void)
{@@ -78,13 +109,12 @@
main(int argc, char **argv)
{extern ulong kerndate;
- char *file;
+ char *file, *nvram;
debug = 0;
kerndate = seconds();
eve = getuser();
- if(eve == nil)
- eve = "drawcpu";
+ nvram = "/tmp/nvram";
ARGBEGIN {case 'p':
@@ -93,6 +123,12 @@
case 'd':
debug++;
break;
+ case 'n':
+ nvram = EARGF(usage());
+ break;
+ case 'u':
+ eve = EARGF(usage());
+ break;
default:
usage();
} ARGEND;
@@ -122,6 +158,7 @@
panic("bind #U: %r"); if(bind("#p", "/proc", MBEFORE) < 0) panic("bind #p: %r");+
if(bind(smprint("/root/%s/arm", ninepath), "/arm", MREPL|MCREATE) < 0) panic("bind arm: %r"); if(bind(smprint("/root/%s/rc", ninepath), "/rc", MREPL|MCREATE) < 0)@@ -129,6 +166,7 @@
bind("#A", "/dev", MAFTER); bind("#N", "/dev", MAFTER);+ bind("#¤", "/dev", MAFTER); bind("#C", "/", MAFTER); if(bind("/root", "/", MAFTER) < 0)@@ -147,6 +185,11 @@
panic("loadtext: %r");free(file);
}
+
+ envinit(nvram);
+ //if(authsrv){+ // if((fd = create("")))+ //}
if(open("/dev/cons", OREAD) != 0) panic("open0: %r");--- a/posix-386/mem.h
+++ b/posix-386/mem.h
@@ -18,7 +18,6 @@
#define PGSHIFT 12 /* log(BY2PG) */
#define ROUND(s, sz) (((s)+((sz)-1))&~((sz)-1))
#define PGROUND(s) ROUND(s, BY2PG)
-#define BLOCKALIGN 8
#define FPalign 16
#define MAXMACH 32 /* max # cpus system can run */
--- a/posix-amd64/mem.h
+++ b/posix-amd64/mem.h
@@ -25,7 +25,6 @@
#define PGSHIFT 12 /* log(BY2PG) */
#define ROUND(s, sz) (((s)+((sz)-1))&~((sz)-1))
#define PGROUND(s) ROUND(s, BY2PG)
-#define BLOCKALIGN 8
#define FPalign 64
#define MAXMACH 128 /* max # cpus system can run */
--- a/posix-arm/mem.h
+++ b/posix-arm/mem.h
@@ -55,11 +55,6 @@
#define FRAMEBUFFER 0xC0000000 /* video framebuffer */
/*
- * Legacy...
- */
-#define BLOCKALIGN 64 /* only used in allocb.c */
-
-/*
* Sizes
*/
#define BI2BY 8 /* bits per byte */
--- a/posix-arm64/mem.h
+++ b/posix-arm64/mem.h
@@ -78,7 +78,6 @@
#define REBOOTADDR (VDRAM-KZERO + 0x20000) /* 0x40020000 */
#define _NSYS 53
-#define BLOCKALIGN 64 /* only used in allocb.c */
#define TRAMPSIZE 232 /* Size of the trampoline, padded */
/*
* Sizes
--
⑨