Commit Graph
632 Commits
Author SHA1 Message Date
Shambhavi SrivastavaandgVisor bot 884e65cf41 Automated rollback of changelist 557871250
PiperOrigin-RevId: 560158129
2023-08-25 11:58:29 -07:00
Andrei VaginandgVisor bot f556917137 vfs: MountNamespace.Root() has to return a top mount of /
A few mounts can be mounted on top of `/`.

PiperOrigin-RevId: 558264274
2023-08-18 15:35:47 -07:00
Shambhavi SrivastavaandgVisor bot 76b2713c08 Adding /proc/[pid]/task/[tid]/children
PiperOrigin-RevId: 557888186
2023-08-17 11:41:48 -07:00
Nicolas LacasseandgVisor bot 5dc1f9fa34 Automated rollback of changelist 554554034
PiperOrigin-RevId: 557871250
2023-08-17 10:50:10 -07:00
Nicolas LacasseandgVisor bot 2ecc8d0f6e Create kernel.SendExternalSignalProcessGroup and use it in boot/loader.go
This will send a signal to all processes (ThreadGroups) in a ProcessGroup.

PiperOrigin-RevId: 555679773
2023-08-10 15:37:22 -07:00
Nayana BidariandgVisor bot eba9311640 Make changes for CgroupsReadControlFile method to get memory usage per cgroup.
- Adds methods to Enter, Leave and Migrate the tasks for memory controller.
- Update the memory cgroup id when the task enters and leaves the cgroups.

PiperOrigin-RevId: 555568875
2023-08-10 11:09:28 -07:00
Shambhavi SrivastavaandgVisor bot f75fcdfa83 Implementing clone3
Updates #8585

PiperOrigin-RevId: 554554034
2023-08-07 12:19:32 -07:00
Jing ChenandgVisor bot 906efa4976 Implement setns CLONE_NEWUTS namespace type.
PiperOrigin-RevId: 554306089
2023-08-06 15:33:25 -07:00
Andrei VaginandgVisor bot 988a2981dc kernel: GetMountNamespace has to check that mntns isn't nil
Reported-by: [email protected]
PiperOrigin-RevId: 553568085
2023-08-03 13:14:04 -07:00
Andrei VaginandgVisor bot 2d37d59eeb kernel: don't use atomic pointers for task.netns
task.netns is always changed from a task goroutine under task.mu.

It means that we can access it without any locks from a task goroutine
we don't need to increment a reference counter in such cases.

In all other cases, we need to take task.mu.

PiperOrigin-RevId: 552913323
2023-08-01 14:04:53 -07:00
Andrei VaginandgVisor bot 4af420d420 Implement setns for mount namespaces
PiperOrigin-RevId: 552859231
2023-08-01 11:12:29 -07:00
Jing ChenandgVisor bot 4e5d1c16a5 Add devices cgroups which is partially implemented. It could export the device cgroups to devices.deny and devices.allow, add/remove device cgroups rules will need to be implemented to fully support device cgroups.
PiperOrigin-RevId: 552673967
2023-07-31 21:22:07 -07:00
Andrei VaginandgVisor bot 4d39b66860 Implement mount namespaces
This change implements only the basic functions of mount namespaces.
All features that depends on user namespaces will be implemented separately.

PiperOrigin-RevId: 552673896
2023-07-31 21:12:21 -07:00
Fabricio VoznikaandgVisor bot f3980d4c38 Return correct number of PIDs with multi-container
Updates #172

PiperOrigin-RevId: 552620987
2023-07-31 16:20:47 -07:00
Jing ChenandgVisor bot a595c26bfe Implement setns CLONE_NEWIPC namespace type.
PiperOrigin-RevId: 552619565
2023-07-31 16:12:45 -07:00
Andrei VaginandgVisor bot c5493106c6 Implement the setns syscall
This change introduces the nsfs file system. Each new namespace allocates
a new nsfs inode.

Here are reasons why we need these inodes:
* each namespace has to have an unique id.
* proc/pid/ns/ contains one entry for each namespace. Bind mounting one of
  the files in this directory to somewhere else in the filesystem keeps the
  corresponding namespace alive even if all processes currently in
  the namespace terminate.
* setns() allows the calling process to join an existing namespace specified
  by a file descriptor.

PiperOrigin-RevId: 550694515
2023-07-24 15:45:08 -07:00
Ayush RanjanandgVisor bot 6f55461bf6 Impose default tmpfs size limits correctly.
Syzkaller came up with workloads that fallocate(2) 1 TB in /tmp. The host
mlock(2) or madvise(2) syscalls on memfd(2) files end up hanging for multiple
minutes in such situations causing the watchdog to mark the calling goroutine
as stuck. memfd(2) files have not size limits.

Linux fails such fallocate(2) attempts in /tmp with ENOSPC.
In Linux tmpfs (shmem), when size= mount option is not specified, the default
size limit for the mount is set to 50% of physical RAM size. But in gVisor, it
is set to MaxInt64. Which is why Linux fails with ENOSPC and gVisor doesn't.

In runsc, the physcial RAM size is already exposed to the containerized
application via `/proc/meminfo` which uses `usage.*TotalMemoryBytes`. These
fields are configured using the `MemTotal:` field from host `/proc/meminfo`.
So use that information to set the default size limit correctly.

Reported-by: [email protected]
PiperOrigin-RevId: 548252095
2023-07-14 16:44:25 -07:00
Nicolas LacasseandgVisor bot 6733665148 Implement PR_{S,G}ET_CHILD_SUBREAPER.
Closes #2323

PiperOrigin-RevId: 548205854
2023-07-14 13:19:25 -07:00
Nayana BidariandgVisor bot 14bd67edab Pass memory cgroup id in pgalloc.Allocate()
For memory accounting per task, the memory cgroup id of the task is required.
This CL retrieves the cgroup id from the task context and stores it in the
AllocOpts struct which will later be used to account for memory usage.

PiperOrigin-RevId: 546996195
2023-07-10 15:16:47 -07:00
Jamie LiuandgVisor bot fe546357e4 Pass context to kernel.TaskImage.release().
PiperOrigin-RevId: 543541608
2023-06-26 14:28:58 -07:00
Jamie LiuandgVisor bot a3a83a54fa Return consistent IDs for PID namespaces via procfs.
PiperOrigin-RevId: 543529000
2023-06-26 13:49:23 -07:00
Nayana BidariandgVisor bot cbe9f52e6d Release the lock after reading all the fields from FileAsync in NotifyEvent.
This CL makes changes to read all the fields from FAsync struct at once to
avoid inconsistent results when FileAsync is changed.

PiperOrigin-RevId: 543528321
2023-06-26 13:41:57 -07:00
Shambhavi SrivastavaandgVisor bot 71eba43999 Adding GetCPUUsage for multi-container mode
PiperOrigin-RevId: 542954812
2023-06-23 14:14:32 -07:00
Ayush RanjanandgVisor bot 83948f19a5 Log the PID/TID in root pidns and caller's pidns.
This is to aid debugging. The application logs make more sense wrt caller pidns
because the application uses PID numbers from its pidns.
Logs like `stat(/pid/PID/status)` are understandable.

PiperOrigin-RevId: 542884517
2023-06-23 09:50:29 -07:00
Andrei VaginandgVisor bot 7170fa06fb kernel: unshare a network namespace without taking Task.mu
t.netns is an atomic pointer so it should not be a problem for readers.
As for writers, only task can change its network namespace.

Reported-by: [email protected]
Reported-by: [email protected]
Reported-by: [email protected]
PiperOrigin-RevId: 542384765
2023-06-21 15:51:28 -07:00
Shambhavi SrivastavaandgVisor bot feda939749 Enabling container to be initialized to it's initial cgroups
Currently there's no implementation to enable the container to be
initialized to it's cgroups and hence the `EnterInitialCgroups` would
inherit all the root's cgroups when the container would start.

With this implementation we make sure that when the container starts
it enter's into the cgroups that is passed down it to from the sandbox.

PiperOrigin-RevId: 540650868
2023-06-15 12:07:05 -07:00
Nayana BidariandgVisor bot 9e897942c7 Add a unique id per cgroup.
PiperOrigin-RevId: 540031470
2023-06-13 12:02:27 -07:00
Etienne PerotandgVisor bot e556411ac0 gVisor metric library: Verify path-style metric names.
The `unimplemented_syscalls` metric did not conform (whoops), so fix that one.

PiperOrigin-RevId: 539767799
2023-06-12 14:53:17 -07:00
Etienne PerotandgVisor bot a82b07a051 Unimplemented syscall counter: Pre-allocate 1-element slices of field values.
This is necessary in order to avoid a heap allocation when calling
`unimplementedSyscallCounter.Increment`. Prior to this CL, this code actually
allocated a 1-element slice, because the `Increment` method takes in a
variadic number of arguments.

Somehow this had not tripped up the `+checkescape` check at submission time,
but running `nogo` manually confirms the problem. This CL fixes it.

PiperOrigin-RevId: 539737956
2023-06-12 13:02:43 -07:00
Andrei VaginandgVisor bot 890a66acd4 fdtable: avoid large arrays
FDTable.descriptorTable is a slice of unsafe.Pointer-s and its maximum length
is MaxInt32. It requires up to 16GB of memory. A process can use just a few
descriptors but sets one or more of them to high numbers. In this case,
FDTable.descriptorTable is extended to the maximum size.

The problem here is that go-runtime zeros memory regions when they are reused.
In the case of fdtable, the memory region is 16GB, so it is a time consuming
operation. Second, it forces the kernel to allocate physical pages to
the entire region.

This change adds another level to descriptorTable, so the first level is
a slice of buckets where each bucket is a slice of descriptors. The bucket
size is fixed to 512 entries to fit one page.

Before:
BenchmarkFDLookupAndDecRef-12              	50834290	        23.70 ns/op
BenchmarkCreateWithMaxFD-12                	       2	7194873988 ns/op
BenchmarkFDLookupAndDecRefConcurrent-12    	23775555	        49.68 ns/op
BenchmarkTableLookup-12                    	412888780	         2.835 ns/op
BenchmarkTableMapLookup-12                 	87944782	        12.84 ns/op

After:
BenchmarkFDLookupAndDecRef-12              	46229940	        25.03 ns/op
BenchmarkCreateWithMaxFD-12                	      13	  82573899 ns/op
BenchmarkFDLookupAndDecRefConcurrent-12    	21889380	        54.13 ns/op
BenchmarkTableLookup-12                    	415851230	         2.821 ns/op
BenchmarkTableMapLookup-12                 	97236267	        11.89 ns/op

Reported-by: [email protected]
PiperOrigin-RevId: 539138632
2023-06-09 11:49:28 -07:00
Jamie LiuandgVisor bot d627289f13 Remove //pkg/sentry/device.
This package was used for VFS1 device number assignment.

PiperOrigin-RevId: 538918926
2023-06-08 16:21:04 -07:00
Andrei VaginandgVisor bot 1aa618a853 fasync: Unlock the FileAsync mutex before sending signal
This cl reverts cl/537942317 and cl/538645255. We need to lock the mutex once
and read all required fields of the FileAsync structure and then release it
right before calling SendSignal.

Right now, getPermAndSignal() and recipient() can return inconsistent results,
because FileAsync can be changed between them.

PiperOrigin-RevId: 538829847
2023-06-08 10:49:08 -07:00
Nayana BidariandgVisor bot 8154246d6d Fix data race by acquiring lock before accessing fields of FileAsync.
PiperOrigin-RevId: 538645255
2023-06-07 18:12:00 -07:00
Andrei VaginandgVisor bot eba5d245f8 fasync: release the FileAsync mutex before sending the signal
Reported-by: [email protected]
Reported-by: [email protected]
PiperOrigin-RevId: 537942317
2023-06-05 12:01:47 -07:00
Lucas ManningandgVisor bot 5e8ed38c2f Change FUSE so that is no longer dependent on kernel tasks.
Filesystem operations are sometimes performed outside of the context of
a kernel task.

PiperOrigin-RevId: 533271322
2023-05-18 15:41:32 -07:00
Andrei VaginandgVisor bot 4a554c0583 Enable lockdep for more mutexes
PiperOrigin-RevId: 533162054
2023-05-18 09:59:15 -07:00
Etienne PerotandgVisor bot ba61bf6e93 gVisor metric library: Change interface for passing in field values.
This introduces a `metric.FieldValue` struct type that wraps a string.
All metric interfaces that deal with field values have been updated to use
pointers to this type instead of strings.

The intent of this change is to make it more obvious that field values must
be passed using references. Prior to this change, this was done using string
pointer comparisons. Now this must be done by using a pointer to the same
`metric.FieldValue` struct.

The struct type still externally exposes its string so that it can be referred
to in value function callbacks by "custom" metrics. (Though there are no
current uses of callback metrics with fields.)

PiperOrigin-RevId: 527030738
2023-04-25 11:49:02 -07:00
Etienne PerotandgVisor bot 3c9c5dd072 gVisor metrics: Re-introduce unimplemented syscall counter metric.
Performance optimizations have made this metric cheap to add: cl/524419594,
cl/524419591.

PiperOrigin-RevId: 526187318
2023-04-21 18:41:32 -07:00
Etienne PerotandgVisor bot 0de4e69d3b gVisor metric library: Optimize operations for large-cardinality metrics.
This optimizes both increments and lookup operations.

It does so using the following:

- For metrics of potential cardinality larger than 48, it will switch to using
  a map rather than linear search for mapping field value combinations to the
  index that combination corresponds to in the flattened list of values.
  For metrics of cardinality 48 or smaller, linear search is still used as it
  is still faster (and also still faster than binary search), as determined by
  benchmarks.
- All field values are checked for pointer uniqueness (i.e. the pointer to the
  start of each field value string must be unique). This is then used for
  faster matching: instead of comparing whole strings (and needing to hash
  them, in the case of doing map-based lookups), it compares pointer values.
  In the context of this metric library, because all field values must be
  pre-declared ahead of time, keeping references to these pre-declared strings
  should always be possible. This is enforced: it will `panic` if the metric
  user does not do this. In practice, this is easy to do by using `const`
  strings for all metric values. This change does just that for existing
  metrics with string fields.

From benchmarks, this speeds up the time to take a snapshot of existing
metrics by -8.35%. With the unimplemented syscall counter metric, this
optimization reduces the slowdown of adding this metric from +4,250% to
a still-large but much more manageable +290%. A further optimization
(cl/524419591) will reduce this overhead further before re-introducing the
unimplemented syscall counter metric.

PiperOrigin-RevId: 526134756
2023-04-21 14:21:18 -07:00
Etienne PerotandgVisor bot 4b976d196c runsc: Remove syscall number from the unimplemented syscall counter.
Doing so has performance implications which need to be fixed before this can
be added back.

PiperOrigin-RevId: 524125147
2023-04-13 15:55:14 -07:00
Etienne PerotandgVisor bot c6d19db4e4 Update unimpl.EmitUnimplementedEvent interface to add the syscall number.
This catches up the interface to the `EmitUnimplementedEvent` method signature
on `kernel.Kernel`.

Also add build-time test to verify that `kernel.Kernel` implements this
interface, in order to catch such breakages at build time in the future.

PiperOrigin-RevId: 519000411
2023-03-23 17:01:37 -07:00
Etienne PerotandgVisor bot 6ff46ccaa2 runsc: Add metric counting calls of unimplemented system calls.
This is useful to determine which syscalls users want but are unimplemented.

PiperOrigin-RevId: 518962607
2023-03-23 14:24:56 -07:00
Etienne PerotandgVisor bot da6948a692 gVisor: Refactor SyscallFn to take in the syscall number as argument.
This will be used to plumb the syscall number through to a counter metric that
exports the number of times an unimplemented syscall has been called.

Plenty of syscall implementations call `EmitUnimplementedEvent` for flags and
settings that are not implemented. With `sysno` available, they will be able
to plumb that bit of information through.

PiperOrigin-RevId: 518635831
2023-03-22 12:06:26 -07:00
Fabricio VoznikaandgVisor bot 11154ce7f1 Fix crash with large FD value
There were 2 problems when trying to allocate a high FD value:
- Rlimit is stored as uint64 and could be truncated when converting to int32
  to calculate the max value allowed for the FD.
- While trying to double the FD table size, the new length for the table could
  end up short due to invalid type convertion again.

Reported-by: [email protected]
PiperOrigin-RevId: 518362257
2023-03-21 13:21:27 -07:00
Andrei Vagin 2c35bc8656 kernel: release kernel.taskSetRWMutex before calling TaskImage.Release
Reported-by: [email protected]
2023-03-16 10:25:46 -07:00
Konstantin BogomolovandgVisor bot 82afd55e7a Fix data race in subprocess pool.
This is a relatively benign data race that's possible when two of the last
remaining contexts are calling s.unregisterContext at the same time, and both
decrement s.numContexts. One continues to release() the subprocess which puts it
into the available pool, but the other one has yet to read s.released. Then,
since the subprocess is in the available pool it can be retrieved with
fetchAvailable, which did not lock s.mu, which is where the data race happens,
because fetchAvailable flips s.released but one of the exiting contexts has yet
to read it.

The proper fix for this is to start holding references onto the subprocess. We
cannot reuse the subprocess while any systrap.contexts are still holding onto
sysmsg.ThreadContexts, so each context get's a reference. Each subprocess is
held by a MemoryManager as an AddressSpace interface, which calls Release on the
subprocess once.

This CL also removes subprocessPool.active because it is unnecessary at this
moment.

PiperOrigin-RevId: 516272892
2023-03-13 11:41:45 -07:00
Fabricio VoznikaandgVisor bot 6e78243569 Remove uncaught signal message
This message was supposed to help troubleshoot application that are
killed inside a container. But it can be noisy and doesn't really
help in most cases, e.g. it's expected in many cases that processes
are killed, message refers to PIDs/TIDs which are not actionable
outside the container execution.

PiperOrigin-RevId: 513627281
2023-03-02 13:42:09 -08:00
Adin ScannellandgVisor bot 2911d8c3b8 Add default_applicable_licenses rules to packages.
PiperOrigin-RevId: 513581243
2023-03-02 10:50:04 -08:00
Nicolas LacasseandgVisor bot c6efda6497 Don't send a signal to a controlling thread group if one has not been set.
Reported-by: [email protected]
PiperOrigin-RevId: 512678427
2023-02-27 11:21:34 -08:00
Nicolas LacasseandgVisor bot 9c40de70bc Clean up devpts code, and deduplicate the foreground process state.
We no longer store the foreground process directly in the terminal. Instead, we
get it from the terminal TTY's ThreadGroup. Added a new method:
tty.SignalForegroundProcessGroup to simplify this.

Cleaned up some things along the way:
* Terminal had a bunch of methods to get/set foreground process group and
  controlling TTY, but those methods were only usable by Ioctl, since they
  read/wrote to syscall arguments. I moved that logic to Ioctl, and deleted the
  methods from Terminal, which is now a very simple type.
* Fixed a bug in ThreadGroud.SetForegroundProcessGroup where we were
  overwriting the ID of an existing process group, rather than setting a new
  process group on the session.
* Simplified the construction of lineDiscipline type.

Reported-by: [email protected]
PiperOrigin-RevId: 512330758
2023-02-25 14:08:58 -08:00