M port/devip.c => port/devip.c +27 -8
@@ 212,9 212,9 @@ ipread(Chan *c, void *a, long n, ulong offset)
long
ipwrite(Chan *c, char *a, long n, ulong offset)
{
- int m, backlog, type;
+ int m, backlog, type, priv;
char *field[5], *ctlarg[5], buf[256];
- Port port, base;
+ Port port;
Ipconv *cp;
type = STREAMTYPE(c->qid.path);
@@ 248,12 248,12 @@ ipwrite(Chan *c, char *a, long n, ulong offset)
default:
error(Ebadarg);
case 2:
- base = PORTALLOC;
+ priv = 0;
break;
case 3:
if(strcmp(ctlarg[2], "r") != 0)
error(Eperm);
- base = PRIVPORTALLOC;
+ priv = 1;
break;
}
cp->dst = ipparse(ctlarg[0]);
@@ 262,7 262,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset)
/* If we have no local port assign one */
qlock(&ipalloc);
if(cp->psrc == 0)
- cp->psrc = nextport(ipconv[c->dev], base);
+ cp->psrc = nextport(ipconv[c->dev], priv);
qunlock(&ipalloc);
if(cp->stproto == &tcpinfo)
@@ 557,6 557,7 @@ tcpstopen(Queue *q, Stream *s)
ipc->readq = RD(q);
ipc->readq->rp = &tcpflowr;
+ ipc->err = 0;
RD(q)->ptr = (void *)ipc;
WR(q)->next->ptr = (void *)ipc->ipinterface;
@@ 852,14 853,32 @@ portused(Ipconv *ic, Port port)
return 0;
}
+static Port lastport[2] = { PORTALLOC-1, PRIVPORTALLOC-1 };
+
Port
-nextport(Ipconv *ic, Port base)
+nextport(Ipconv *ic, int priv)
{
+ Port base;
+ Port max;
+ Port *p;
Port i;
- for(i = base; i < PORTMAX; i++)
+ if(priv){
+ base = PRIVPORTALLOC;
+ max = PORTALLOC;
+ p = &lastport[1];
+ } else {
+ base = PORTALLOC;
+ max = PORTMAX;
+ p = &lastport[0];
+ }
+
+ for(i = *p + 1; i < max; i++)
+ if(!portused(ic, i))
+ return(*p = i);
+ for(i = base ; i <= *p; i++)
if(!portused(ic, i))
- return(i);
+ return(*p = i);
return(0);
}
M port/devproc.c => port/devproc.c +5 -0
@@ 264,6 264,11 @@ procread(Chan *c, void *va, long n, ulong offset)
}
if(offset >= KZERO) {
+ /* prevent users reading authentication crypt keys */
+ if(offset >= pgrpalloc.cryptbase)
+ if(offset < pgrpalloc.crypttop)
+ error(Eperm);
+ /* validate physical kernel addresses */
if(offset < KZERO+conf.npage0*BY2PG){
if(offset+n > KZERO+conf.npage0*BY2PG)
n = KZERO+conf.npage0*BY2PG - offset;
M port/ipdat.h => port/ipdat.h +7 -3
@@ 194,9 194,8 @@ struct Timer
void *arg;
};
-struct Tcpctl
+struct Tctl
{
- QLock;
uchar state; /* Connection state */
uchar type; /* Listening or active connection */
uchar code; /* Icmp code */
@@ 242,6 241,11 @@ struct Tcpctl
int srtt; /* Shortened round trip */
int mdev; /* Mean deviation of round trip */
};
+struct Tcpctl
+{
+ QLock;
+ struct Tctl;
+};
struct Tcp
{
@@ 435,7 439,7 @@ void udprcvmsg(Ipconv *, Block*);
Block *btrim(Block*, int, int);
Block *ip_reassemble(int, Block*, Etherhdr*);
Ipconv *portused(Ipconv *, Port);
-Port nextport(Ipconv *, Port);
+Port nextport(Ipconv *, int);
Fragq *ipfragallo(void);
void ipfragfree(Fragq*, int);
void iproute(uchar*, uchar*);
M port/pgrp.c => port/pgrp.c +5 -11
@@ 5,13 5,7 @@
#include "fns.h"
#include "../port/error.h"
-struct
-{
- Lock;
- Pgrp *arena;
- Pgrp *free;
- ulong pgrpid;
-}pgrpalloc;
+Pgrps pgrpalloc;
struct
{
@@ 43,10 37,10 @@ grpinit(void)
Mhead *hm, *hem;
Crypt *cr;
- /*
- * need to /dev/proc read protect crypt memory
- */
- cr = ialloc(conf.npgrp*sizeof(Crypt), 0);
+ i = conf.npgrp*sizeof(Crypt);
+ cr = ialloc(i, 0);
+ pgrpalloc.cryptbase = (ulong)cr;
+ pgrpalloc.crypttop = (ulong)cr + i;
pgrpalloc.arena = ialloc(conf.npgrp*sizeof(Pgrp), 0);
pgrpalloc.free = pgrpalloc.arena;
M port/portdat.h => port/portdat.h +12 -0
@@ 23,6 23,7 @@ typedef struct Network Network;
typedef struct Note Note;
typedef struct Page Page;
typedef struct Palloc Palloc;
+typedef struct Pgrps Pgrps;
typedef struct Pgrp Pgrp;
typedef struct Proc Proc;
typedef struct Pte Pte;
@@ 427,6 428,16 @@ struct Palloc
int wanted; /* Do the wakeup at free */
};
+struct Pgrps
+{
+ Lock;
+ Pgrp *arena;
+ Pgrp *free;
+ ulong pgrpid;
+ ulong cryptbase;
+ ulong crypttop;
+};
+
struct Waitq
{
Waitmsg w;
@@ 672,6 683,7 @@ extern char devchar[];
extern char *conffile;
extern char *statename[];
extern Palloc palloc;
+extern Pgrps pgrpalloc;
extern Image swapimage;
extern char eve[];
extern int nrdy;
M port/tcpinput.c => port/tcpinput.c +7 -1
@@ 824,13 824,19 @@ copyb(Block *bp, int count)
ushort tcp_mss = DEF_MSS; /* Maximum segment size to be sent with SYN */
int tcp_irtt = DEF_RTT; /* Initial guess at round trip time */
+static void
+cleartcp(struct Tctl *a)
+{
+ memset(a, 0, sizeof(struct Tctl));
+}
+
void
init_tcpctl(Ipconv *s)
{
Tcpctl *tcb = &s->tcpctl;
- memset(tcb, 0, sizeof(Tcpctl));
+ cleartcp(tcb);
tcb->cwind = tcb->mss = tcp_mss;
tcb->ssthresh = 65535;
M port/tcptimer.c => port/tcptimer.c +1 -1
@@ 1,4 1,4 @@
-
#include "u.h"
+#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"