shithub: drawcpu

Download patch

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
--