Doesn't that create a security hole by making it possible to access to private ramdisks and factotum instances and the like which were previously not accessible to the process?

On 12/13/25 19:54, [email protected] wrote:
This patch makes it possible to enter a namespace through
/proc/$pid/ns, like so:

      auth/newns -n /proc/$pid/ns $cmd

or through procesing the namespace file any other way
that they want.

with the hope it'll be useful for things like fixing up
tab completion in rio, making the plumber responsive to
the local namespace that we are plumbing from, and other
things that we haven't figured out yet.

It works by making the chans for a proc's mounts available
via /proc/$pid/srv/$id, and changing /proc/$pid/ns to use
the channel name rather than files other procs can't access,
such as '#|'.

Hopefully folks will be able to experiment a bit with this,
and figure out some good uses for it.


diff 4341e26ac5d5cb86af2e1d88dd85365e7feb3a59 uncommitted
--- a/sys/man/3/proc
+++ b/sys/man/3/proc
@@ -22,6 +22,7 @@
  .BI /proc/ n /profile
  .BI /proc/ n /regs
  .BI /proc/ n /segment
+.BI /proc/ n /srv/ chan
  .BI /proc/ n /status
  .BI /proc/ n /text
  .BI /proc/ n /wait
@@ -127,6 +128,15 @@
  for read-only, if any;
  starting virtual address, in hexadecimal;
  ending virtual address, and reference count.
+.PP
+The
+.B srv
+directory provides a directory holding already-open channels
+to services in the style of
+.IR srv (3).
+This allows a process with appropriate permissions to execute the
+.I ns
+file and accurately reproduce the namespace of the process that is running.
  .PP
  The read-only
  .B status
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -28,6 +28,8 @@
      Qnoteid,
      Qnotepg,
      Qns,
+     Qsrv,
+     Qchan,
      Qppid,
      Qproc,
      Qregs,
@@ -100,6 +102,7 @@
      "noteid",       {Qnoteid},      0,                      0664,
      "notepg",       {Qnotepg},      0,                      0000,
      "ns",           {Qns},          0,                      0444,
+     "srv",          {Qsrv,0,QTDIR}, 0,                      0555,
      "ppid",         {Qppid},        0,                      0444,
      "proc",         {Qproc},        0,                      0400,
      "regs",         {Qregs},        sizeof(Ureg),           0000,
@@ -154,8 +157,8 @@
   *       in vers,
   *  32 bits of pid, for consistency checking
   */
-#define      QSHIFT  5       /* location in qid of proc slot # */
-
+#define      QSHIFT          5       /* location in qid of proc slot # */
+#define CSHIFT               (26+5)  /* location in qid of chan # */
  #define     QID(q)          ((((ulong)(q).path)&0x0000001F)>>0)
  #define     SLOTMAX         0x4000000
  #define     SLOT(q)         (((((ulong)(q).path)>>QSHIFT)&(SLOTMAX-1))-1)
@@ -175,6 +178,39 @@
static int lenwatchpt(Proc *); +static Chan*
+mntchan(Proc *p, Chan *c)
+{
+     char *s, *t, buf[32];
+     Chan *nc, *mc;
+     Pgrp *pg;
+     Mount *f;
+
+     s = c->path->s;
+     if((t = strrchr(s, '/')) != nil)
+             s = t+1;
+
+     pg = p->pgrp;
+     if(pg == nil)
+             error(Eprocdied);
+
+     nc = nil;
+     rlock(&pg->ns);
+     for(f = pg->mntorder; f != nil; f = f->order){
+             if(strcmp(f->to->path->s, "#M") != 0)
+                     continue;
+             mc = f->to->mchan;
+             snprint(buf, sizeof(buf), "%ld.%x.%llx", mc->dev, mc->type, 
mc->qid.path);
+             if(strcmp(s, buf) == 0){
+                     nc = f->to->mchan;
+                     incref(nc);
+                     break;
+             }
+     }
+     runlock(&pg->ns);
+     return nc;
+}
+
  static int
  procgen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp)
  {
@@ -182,7 +218,13 @@
      Proc *p;
      char *ename;
      Segment *q;
-     ulong pid, path, perm, len;
+     Mount *f;
+     Chan *mc;
+     Pgrp *pg;
+     ulong pid, perm, len;
+     uvlong path;
+     char *e, *t;
+     int i;
if(s == DEVDOTDOT){
              mkqid(&qid, Qdir, 0, QTDIR);
@@ -226,9 +268,46 @@
              devdir(c, qid, up->genbuf, 0, p->user, 0555, dp);
              return 1;
      }
+     if(QID(c->qid) == Qsrv){
+             i = 0;
+             p = proctab(SLOT(c->qid));
+             pg = p->pgrp;
+             if(pg == nil || p->dot == nil || p->pid != PID(c->qid))
+                     error(Eprocdied);
+             rlock(&pg->ns);
+             for(f = pg->mntorder; f != nil; f = f->order){
+                     if(strcmp(f->to->path->s, "#M") != 0)
+                             continue;
+                     if(i++ >= s)
+                             break;
+             }
+             if(f == nil){
+                     runlock(&pg->ns);
+                     return -1;
+             }
+             mc = f->to->mchan;
+             path = ((uvlong)i<<CSHIFT) | c->qid.path&~((1<<QSHIFT)-1);
+             snprint(up->genbuf, sizeof(up->genbuf), "%ld.%x.%llx", mc->dev, 
mc->type, mc->qid.path);
+             mkqid(&qid, path | Qchan, p->pid, QTFILE);
+             devdir(c, qid, up->genbuf, 0, p->user, 0400, dp);
+             runlock(&pg->ns);
+             return 1;
+     }
+     if(QID(c->qid) == Qchan){
+             p = proctab(SLOT(c->qid));
+             if(p->dot == nil || p->pid != PID(c->qid))
+                     error(Eprocdied);
+             e = c->path->s;
+             if((t = strrchr(e, '/')) != nil)
+                     e = t+1;
+             snprint(up->genbuf, sizeof(up->genbuf), "%s", e);
+             mkqid(&qid, c->qid.path, p->pid, QTFILE);
+             devdir(c, qid, up->genbuf, 0, eve, 0400, dp);
+             return 1;
+     }
      if(c->qid.path == Qtrace){
              strcpy(up->genbuf, "trace");
-             mkqid(&qid, Qtrace, -1, QTFILE);
+             mkqid(&qid, c->qid.path, -1, QTFILE);
              devdir(c, qid, up->genbuf, 0, eve, 0400, dp);
              return 1;
      }
@@ -265,7 +344,7 @@
              break;
      }
- mkqid(&qid, path|tab->qid.path, c->qid.vers, QTFILE);
+     mkqid(&qid, path|tab->qid.path, c->qid.vers, tab->qid.type);
      devdir(c, qid, tab->name, len, p->user, perm, dp);
      return 1;
  }
@@ -398,6 +477,7 @@
              c->offset = 0;
              return c;
      }
+
p = proctab(SLOT(c->qid));
      eqlock(&p->debug);
@@ -436,7 +516,13 @@
              if(omode != OREAD)
                      error(Eperm);
              break;
-
+     case Qchan:
+             tc = mntchan(p, c);
+             if(tc == nil)
+                     error(Eshutdown);
+             devpermcheck(p->user, c->mode, omode);
+             nonone(p);
+             goto Found;
      case Qctl:
      case Qargs:
      case Qwait:
@@ -488,8 +574,8 @@
                      clearwatchpt(p);
              break;
      }
- poperror();
+Found:
      qunlock(&p->debug);
      poperror();
@@ -641,10 +727,11 @@
  static int
  readns1(Chan *c, Proc *p, char *buf, int nbuf)
  {
+     char flag[10], srv[32];
      Pgrp *pg;
      Mount *f;
-     char flag[10], *srv;
-     int i;
+     Chan *mc;
+     int i, n;
pg = p->pgrp;
      if(pg == nil || p->dot == nil || p->pid != PID(c->qid))
@@ -656,32 +743,33 @@
      rlock(&pg->ns);
i = 0;
-     for(f = pg->mntorder; f != nil; f = f->order) {
+     for(f = pg->mntorder; f != nil; f = f->order)
              if(i++ >= c->nrock)
                      break;
-     }
if(f == nil) {
              c->nrock = -1;
-             i = snprint(buf, nbuf, "cd %q\n", p->dot->path->s);
+             n = snprint(buf, nbuf, "cd %q\n", p->dot->path->s);
      } else {
              c->nrock = i;
              int2flag(f->mflag, flag);
              if(strcmp(f->to->path->s, "#M") == 0){
-                     srv = f->to->mchan->srvname;
-                     if(srv == nil)
-                             srv = f->to->mchan->path->s;
-                     i = snprint(buf, nbuf, *f->spec?
-                             "mount %s %q %q %q\n": "mount %s %q %q\n", flag,
-                             srv, f->umh->from->path->s, f->spec);
+                     mc = f->to->mchan;
+                     snprint(srv, sizeof(srv), "%ld.%x.%llx", mc->dev, mc->type, 
mc->qid.path);
+                     if(f->spec[0] != 0)
+                             n = snprint(buf, nbuf, "mount %s /proc/%lud/srv/%q %q 
%q\n",
+                                     flag, p->pid, srv, f->umh->from->path->s, 
f->spec);
+                     else
+                             n = snprint(buf, nbuf, "mount %s /proc/%lud/srv/%q 
%q\n",
+                                     flag, p->pid, srv, f->umh->from->path->s);
              }else{
-                     i = snprint(buf, nbuf, "bind %s %q %q\n", flag,
+                     n = snprint(buf, nbuf, "bind %s %q %q\n", flag,
                              f->to->path->s, f->umh->from->path->s);
              }
      }
      runlock(&pg->ns);
- return i;
+     return n;
  }
int


------------------------------------------
9fans: 9fans
Permalink: 
https://9fans.topicbox.com/groups/9fans/Tdf1407e79f217ea2-Ma80db8de7eb2ec3200ae6890
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

Reply via email to