summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/sentry/fs/proc/proc.go34
1 files changed, 32 insertions, 2 deletions
diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go
index d727e1bc9..b2a8d639c 100644
--- a/pkg/sentry/fs/proc/proc.go
+++ b/pkg/sentry/fs/proc/proc.go
@@ -111,6 +111,13 @@ func (p *proc) newSelf(ctx context.Context, msrc *fs.MountSource) *fs.Inode {
return newFile(s, msrc, fs.Symlink, nil)
}
+// newThreadSelf returns a new "threadSelf" node.
+func (p *proc) newThreadSelf(ctx context.Context, msrc *fs.MountSource) *fs.Inode {
+ s := &threadSelf{pidns: p.pidns}
+ s.InitSymlink(ctx, fs.RootOwner, "")
+ return newFile(s, msrc, fs.Symlink, nil)
+}
+
// newStubProcFsFile returns a procfs file with constant contents.
func (p *proc) newStubProcFSFile(ctx context.Context, msrc *fs.MountSource, c []byte) *fs.Inode {
u := &stubProcFSFile{
@@ -134,6 +141,28 @@ func (s *self) Readlink(ctx context.Context, inode *fs.Inode) (string, error) {
return "", ramfs.ErrInvalidOp
}
+// threadSelf is more magical than "self" link.
+type threadSelf struct {
+ ramfs.Symlink
+
+ pidns *kernel.PIDNamespace
+}
+
+// Readlink implements fs.InodeOperations.Readlink.
+func (s *threadSelf) Readlink(ctx context.Context, inode *fs.Inode) (string, error) {
+ if t := kernel.TaskFromContext(ctx); t != nil {
+ tgid := s.pidns.IDOfThreadGroup(t.ThreadGroup())
+ tid := s.pidns.IDOfTask(t)
+ if tid == 0 || tgid == 0 {
+ return "", ramfs.ErrNotFound
+ }
+ return fmt.Sprintf("%d/task/%d", tgid, tid), nil
+ }
+
+ // Who is reading this link?
+ return "", ramfs.ErrInvalidOp
+}
+
// Lookup loads an Inode at name into a Dirent.
func (p *proc) Lookup(ctx context.Context, dir *fs.Inode, name string) (*fs.Dirent, error) {
// Is it one of the static ones?
@@ -151,8 +180,9 @@ func (p *proc) Lookup(ctx context.Context, dir *fs.Inode, name string) (*fs.Dire
}
return p.newNetDir(ctx, dir.MountSource)
},
- "self": func() *fs.Inode { return p.newSelf(ctx, dir.MountSource) },
- "sys": func() *fs.Inode { return p.newSysDir(ctx, dir.MountSource) },
+ "self": func() *fs.Inode { return p.newSelf(ctx, dir.MountSource) },
+ "sys": func() *fs.Inode { return p.newSysDir(ctx, dir.MountSource) },
+ "thread-self": func() *fs.Inode { return p.newThreadSelf(ctx, dir.MountSource) },
}
if nf, ok := nfs[name]; ok {
return fs.NewDirent(nf(), name), nil