Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <AK/Demangle.h>
28#include <AK/FileSystemPath.h>
29#include <AK/ScopeGuard.h>
30#include <AK/StdLibExtras.h>
31#include <AK/StringBuilder.h>
32#include <AK/Time.h>
33#include <AK/Types.h>
34#include <Kernel/ACPI/Parser.h>
35#include <Kernel/Arch/i386/CPU.h>
36#include <Kernel/Devices/BlockDevice.h>
37#include <Kernel/Devices/KeyboardDevice.h>
38#include <Kernel/Devices/NullDevice.h>
39#include <Kernel/Devices/PCSpeaker.h>
40#include <Kernel/Devices/RandomDevice.h>
41#include <Kernel/FileSystem/Custody.h>
42#include <Kernel/FileSystem/DevPtsFS.h>
43#include <Kernel/FileSystem/Ext2FileSystem.h>
44#include <Kernel/FileSystem/FIFO.h>
45#include <Kernel/FileSystem/FileDescription.h>
46#include <Kernel/FileSystem/InodeWatcher.h>
47#include <Kernel/FileSystem/ProcFS.h>
48#include <Kernel/FileSystem/TmpFS.h>
49#include <Kernel/FileSystem/VirtualFileSystem.h>
50#include <Kernel/Heap/kmalloc.h>
51#include <Kernel/KBufferBuilder.h>
52#include <Kernel/KSyms.h>
53#include <Kernel/KernelInfoPage.h>
54#include <Kernel/Module.h>
55#include <Kernel/Multiboot.h>
56#include <Kernel/Net/Socket.h>
57#include <Kernel/PerformanceEventBuffer.h>
58#include <Kernel/Process.h>
59#include <Kernel/Profiling.h>
60#include <Kernel/RTC.h>
61#include <Kernel/Random.h>
62#include <Kernel/Scheduler.h>
63#include <Kernel/SharedBuffer.h>
64#include <Kernel/Syscall.h>
65#include <Kernel/TTY/MasterPTY.h>
66#include <Kernel/TTY/TTY.h>
67#include <Kernel/Thread.h>
68#include <Kernel/ThreadTracer.h>
69#include <Kernel/Time/TimeManagement.h>
70#include <Kernel/VM/PageDirectory.h>
71#include <Kernel/VM/PrivateInodeVMObject.h>
72#include <Kernel/VM/PurgeableVMObject.h>
73#include <Kernel/VM/SharedInodeVMObject.h>
74#include <LibBareMetal/IO.h>
75#include <LibBareMetal/Output/Console.h>
76#include <LibBareMetal/StdLib.h>
77#include <LibC/errno_numbers.h>
78#include <LibC/limits.h>
79#include <LibC/signal_numbers.h>
80#include <LibELF/ELFLoader.h>
81
82//#define PROCESS_DEBUG
83//#define DEBUG_POLL_SELECT
84//#define DEBUG_IO
85//#define TASK_DEBUG
86//#define FORK_DEBUG
87//#define EXEC_DEBUG
88//#define SIGNAL_DEBUG
89//#define SHARED_BUFFER_DEBUG
90
91namespace Kernel {
92
93static void create_signal_trampolines();
94static void create_kernel_info_page();
95
96Process* Process::current;
97
98static pid_t next_pid;
99InlineLinkedList<Process>* g_processes;
100static String* s_hostname;
101static Lock* s_hostname_lock;
102static VirtualAddress s_info_page_address_for_userspace;
103static VirtualAddress s_info_page_address_for_kernel;
104VirtualAddress g_return_to_ring3_from_signal_trampoline;
105HashMap<String, OwnPtr<Module>>* g_modules;
106
107pid_t Process::allocate_pid()
108{
109 InterruptDisabler disabler;
110 return next_pid++;
111}
112
113void Process::initialize()
114{
115 g_modules = new HashMap<String, OwnPtr<Module>>;
116
117 next_pid = 0;
118 g_processes = new InlineLinkedList<Process>;
119 s_hostname = new String("courage");
120 s_hostname_lock = new Lock;
121
122 create_signal_trampolines();
123 create_kernel_info_page();
124}
125
126void Process::update_info_page_timestamp(const timeval& tv)
127{
128 auto* info_page = (KernelInfoPage*)s_info_page_address_for_kernel.as_ptr();
129 info_page->serial++;
130 const_cast<timeval&>(info_page->now) = tv;
131}
132
133Vector<pid_t> Process::all_pids()
134{
135 Vector<pid_t> pids;
136 InterruptDisabler disabler;
137 pids.ensure_capacity((int)g_processes->size_slow());
138 for (auto& process : *g_processes)
139 pids.append(process.pid());
140 return pids;
141}
142
143Vector<Process*> Process::all_processes()
144{
145 Vector<Process*> processes;
146 InterruptDisabler disabler;
147 processes.ensure_capacity((int)g_processes->size_slow());
148 for (auto& process : *g_processes)
149 processes.append(&process);
150 return processes;
151}
152
153bool Process::in_group(gid_t gid) const
154{
155 return m_gid == gid || m_extra_gids.contains(gid);
156}
157
158Range Process::allocate_range(VirtualAddress vaddr, size_t size, size_t alignment)
159{
160 vaddr.mask(PAGE_MASK);
161 size = PAGE_ROUND_UP(size);
162 if (vaddr.is_null())
163 return page_directory().range_allocator().allocate_anywhere(size, alignment);
164 return page_directory().range_allocator().allocate_specific(vaddr, size);
165}
166
167static unsigned prot_to_region_access_flags(int prot)
168{
169 unsigned access = 0;
170 if (prot & PROT_READ)
171 access |= Region::Access::Read;
172 if (prot & PROT_WRITE)
173 access |= Region::Access::Write;
174 if (prot & PROT_EXEC)
175 access |= Region::Access::Execute;
176 return access;
177}
178
179Region& Process::allocate_split_region(const Region& source_region, const Range& range, size_t offset_in_vmobject)
180{
181 auto& region = add_region(Region::create_user_accessible(range, source_region.vmobject(), offset_in_vmobject, source_region.name(), source_region.access()));
182 region.set_mmap(source_region.is_mmap());
183 region.set_stack(source_region.is_stack());
184 size_t page_offset_in_source_region = (offset_in_vmobject - source_region.offset_in_vmobject()) / PAGE_SIZE;
185 for (size_t i = 0; i < region.page_count(); ++i) {
186 if (source_region.should_cow(page_offset_in_source_region + i))
187 region.set_should_cow(i, true);
188 }
189 return region;
190}
191
192Region* Process::allocate_region(const Range& range, const String& name, int prot, bool commit)
193{
194 ASSERT(range.is_valid());
195 auto vmobject = AnonymousVMObject::create_with_size(range.size());
196 auto& region = add_region(Region::create_user_accessible(range, vmobject, 0, name, prot_to_region_access_flags(prot)));
197 region.map(page_directory());
198 if (commit)
199 region.commit();
200 return ®ion;
201}
202
203Region* Process::allocate_region(VirtualAddress vaddr, size_t size, const String& name, int prot, bool commit)
204{
205 auto range = allocate_range(vaddr, size);
206 if (!range.is_valid())
207 return nullptr;
208 return allocate_region(range, name, prot, commit);
209}
210
211Region* Process::allocate_region_with_vmobject(const Range& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, const String& name, int prot)
212{
213 ASSERT(range.is_valid());
214 size_t end_in_vmobject = offset_in_vmobject + range.size();
215 if (end_in_vmobject <= offset_in_vmobject) {
216 dbg() << "allocate_region_with_vmobject: Overflow (offset + size)";
217 return nullptr;
218 }
219 if (offset_in_vmobject >= vmobject->size()) {
220 dbg() << "allocate_region_with_vmobject: Attempt to allocate a region with an offset past the end of its VMObject.";
221 return nullptr;
222 }
223 if (end_in_vmobject > vmobject->size()) {
224 dbg() << "allocate_region_with_vmobject: Attempt to allocate a region with an end past the end of its VMObject.";
225 return nullptr;
226 }
227 offset_in_vmobject &= PAGE_MASK;
228 auto& region = add_region(Region::create_user_accessible(range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot)));
229 region.map(page_directory());
230 return ®ion;
231}
232
233Region* Process::allocate_region_with_vmobject(VirtualAddress vaddr, size_t size, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, const String& name, int prot)
234{
235 auto range = allocate_range(vaddr, size);
236 if (!range.is_valid())
237 return nullptr;
238 return allocate_region_with_vmobject(range, move(vmobject), offset_in_vmobject, name, prot);
239}
240
241bool Process::deallocate_region(Region& region)
242{
243 InterruptDisabler disabler;
244 if (m_region_lookup_cache.region == ®ion)
245 m_region_lookup_cache.region = nullptr;
246 for (size_t i = 0; i < m_regions.size(); ++i) {
247 if (&m_regions[i] == ®ion) {
248 m_regions.unstable_remove(i);
249 return true;
250 }
251 }
252 return false;
253}
254
255Region* Process::region_from_range(const Range& range)
256{
257 if (m_region_lookup_cache.range == range && m_region_lookup_cache.region)
258 return m_region_lookup_cache.region;
259
260 size_t size = PAGE_ROUND_UP(range.size());
261 for (auto& region : m_regions) {
262 if (region.vaddr() == range.base() && region.size() == size) {
263 m_region_lookup_cache.range = range;
264 m_region_lookup_cache.region = region.make_weak_ptr();
265 return ®ion;
266 }
267 }
268 return nullptr;
269}
270
271Region* Process::region_containing(const Range& range)
272{
273 for (auto& region : m_regions) {
274 if (region.contains(range))
275 return ®ion;
276 }
277 return nullptr;
278}
279
280int Process::sys$set_mmap_name(const Syscall::SC_set_mmap_name_params* user_params)
281{
282 REQUIRE_PROMISE(stdio);
283
284 Syscall::SC_set_mmap_name_params params;
285 if (!validate_read_and_copy_typed(¶ms, user_params))
286 return -EFAULT;
287
288 if (params.name.length > PATH_MAX)
289 return -ENAMETOOLONG;
290
291 auto name = validate_and_copy_string_from_user(params.name);
292 if (name.is_null())
293 return -EFAULT;
294
295 auto* region = region_from_range({ VirtualAddress(params.addr), params.size });
296 if (!region)
297 return -EINVAL;
298 if (!region->is_mmap())
299 return -EPERM;
300 region->set_name(name);
301 return 0;
302}
303
304static bool validate_mmap_prot(int prot, bool map_stack)
305{
306 bool readable = prot & PROT_READ;
307 bool writable = prot & PROT_WRITE;
308 bool executable = prot & PROT_EXEC;
309
310 if (writable && executable)
311 return false;
312
313 if (map_stack) {
314 if (executable)
315 return false;
316 if (!readable || !writable)
317 return false;
318 }
319
320 return true;
321}
322
323static bool validate_inode_mmap_prot(const Process& process, int prot, const Inode& inode, bool map_shared)
324{
325 auto metadata = inode.metadata();
326 if ((prot & PROT_READ) && !metadata.may_read(process))
327 return false;
328
329 if (map_shared) {
330 if ((prot & PROT_WRITE) && !metadata.may_write(process))
331 return false;
332 InterruptDisabler disabler;
333 if (inode.shared_vmobject()) {
334 if ((prot & PROT_EXEC) && inode.shared_vmobject()->writable_mappings())
335 return false;
336 if ((prot & PROT_WRITE) && inode.shared_vmobject()->executable_mappings())
337 return false;
338 }
339 }
340 return true;
341}
342
343// Carve out a virtual address range from a region and return the two regions on either side
344Vector<Region*, 2> Process::split_region_around_range(const Region& source_region, const Range& desired_range)
345{
346 Range old_region_range = source_region.range();
347 auto remaining_ranges_after_unmap = old_region_range.carve(desired_range);
348
349 ASSERT(!remaining_ranges_after_unmap.is_empty());
350 auto make_replacement_region = [&](const Range& new_range) -> Region& {
351 ASSERT(old_region_range.contains(new_range));
352 size_t new_range_offset_in_vmobject = source_region.offset_in_vmobject() + (new_range.base().get() - old_region_range.base().get());
353 return allocate_split_region(source_region, new_range, new_range_offset_in_vmobject);
354 };
355 Vector<Region*, 2> new_regions;
356 for (auto& new_range : remaining_ranges_after_unmap) {
357 new_regions.unchecked_append(&make_replacement_region(new_range));
358 }
359 return new_regions;
360}
361
362void* Process::sys$mmap(const Syscall::SC_mmap_params* user_params)
363{
364 REQUIRE_PROMISE(stdio);
365
366 Syscall::SC_mmap_params params;
367 if (!validate_read_and_copy_typed(¶ms, user_params))
368 return (void*)-EFAULT;
369
370 void* addr = (void*)params.addr;
371 size_t size = params.size;
372 size_t alignment = params.alignment;
373 int prot = params.prot;
374 int flags = params.flags;
375 int fd = params.fd;
376 int offset = params.offset;
377
378 if (alignment & ~PAGE_MASK)
379 return (void*)-EINVAL;
380
381 if (!is_user_range(VirtualAddress(addr), size))
382 return (void*)-EFAULT;
383
384 String name;
385 if (params.name.characters) {
386 if (params.name.length > PATH_MAX)
387 return (void*)-ENAMETOOLONG;
388 name = validate_and_copy_string_from_user(params.name);
389 if (name.is_null())
390 return (void*)-EFAULT;
391 }
392
393 if (size == 0)
394 return (void*)-EINVAL;
395 if ((FlatPtr)addr & ~PAGE_MASK)
396 return (void*)-EINVAL;
397
398 bool map_shared = flags & MAP_SHARED;
399 bool map_anonymous = flags & MAP_ANONYMOUS;
400 bool map_purgeable = flags & MAP_PURGEABLE;
401 bool map_private = flags & MAP_PRIVATE;
402 bool map_stack = flags & MAP_STACK;
403 bool map_fixed = flags & MAP_FIXED;
404
405 if (map_shared && map_private)
406 return (void*)-EINVAL;
407
408 if (!map_shared && !map_private)
409 return (void*)-EINVAL;
410
411 if (!validate_mmap_prot(prot, map_stack))
412 return (void*)-EINVAL;
413
414 if (map_stack && (!map_private || !map_anonymous))
415 return (void*)-EINVAL;
416
417 Region* region = nullptr;
418
419 auto range = allocate_range(VirtualAddress(addr), size, alignment);
420 if (!range.is_valid())
421 return (void*)-ENOMEM;
422
423 if (map_purgeable) {
424 auto vmobject = PurgeableVMObject::create_with_size(size);
425 region = allocate_region_with_vmobject(range, vmobject, 0, !name.is_null() ? name : "mmap (purgeable)", prot);
426 if (!region && (!map_fixed && addr != 0))
427 region = allocate_region_with_vmobject({}, size, vmobject, 0, !name.is_null() ? name : "mmap (purgeable)", prot);
428 } else if (map_anonymous) {
429 region = allocate_region(range, !name.is_null() ? name : "mmap", prot, false);
430 if (!region && (!map_fixed && addr != 0))
431 region = allocate_region(allocate_range({}, size), !name.is_null() ? name : "mmap", prot, false);
432 } else {
433 if (offset < 0)
434 return (void*)-EINVAL;
435 if (static_cast<size_t>(offset) & ~PAGE_MASK)
436 return (void*)-EINVAL;
437 auto description = file_description(fd);
438 if (!description)
439 return (void*)-EBADF;
440 if (description->is_directory())
441 return (void*)-ENODEV;
442 if ((prot & PROT_READ) && !description->is_readable())
443 return (void*)-EACCES;
444 if (map_shared) {
445 if ((prot & PROT_WRITE) && !description->is_writable())
446 return (void*)-EACCES;
447 }
448 if (description->inode()) {
449 if (!validate_inode_mmap_prot(*this, prot, *description->inode(), map_shared))
450 return (void*)-EACCES;
451 }
452 auto region_or_error = description->mmap(*this, VirtualAddress(addr), static_cast<size_t>(offset), size, prot, map_shared);
453 if (region_or_error.is_error()) {
454 // Fail if MAP_FIXED or address is 0, retry otherwise
455 if (map_fixed || addr == 0)
456 return (void*)(int)region_or_error.error();
457 region_or_error = description->mmap(*this, {}, static_cast<size_t>(offset), size, prot, map_shared);
458 }
459 if (region_or_error.is_error())
460 return (void*)(int)region_or_error.error();
461 region = region_or_error.value();
462 }
463
464 if (!region)
465 return (void*)-ENOMEM;
466 region->set_mmap(true);
467 if (map_shared)
468 region->set_shared(true);
469 if (map_stack)
470 region->set_stack(true);
471 if (!name.is_null())
472 region->set_name(name);
473 return region->vaddr().as_ptr();
474}
475
476int Process::sys$munmap(void* addr, size_t size)
477{
478 REQUIRE_PROMISE(stdio);
479
480 if (!size)
481 return -EINVAL;
482
483 if (!is_user_range(VirtualAddress(addr), size))
484 return -EFAULT;
485
486 Range range_to_unmap { VirtualAddress(addr), size };
487 if (auto* whole_region = region_from_range(range_to_unmap)) {
488 if (!whole_region->is_mmap())
489 return -EPERM;
490 bool success = deallocate_region(*whole_region);
491 ASSERT(success);
492 return 0;
493 }
494
495 if (auto* old_region = region_containing(range_to_unmap)) {
496 if (!old_region->is_mmap())
497 return -EPERM;
498
499 auto new_regions = split_region_around_range(*old_region, range_to_unmap);
500
501 // We manually unmap the old region here, specifying that we *don't* want the VM deallocated.
502 old_region->unmap(Region::ShouldDeallocateVirtualMemoryRange::No);
503 deallocate_region(*old_region);
504
505 // Instead we give back the unwanted VM manually.
506 page_directory().range_allocator().deallocate(range_to_unmap);
507
508 // And finally we map the new region(s) using our page directory (they were just allocated and don't have one).
509 for (auto* new_region : new_regions) {
510 new_region->map(page_directory());
511 }
512 return 0;
513 }
514
515 // FIXME: We should also support munmap() across multiple regions. (#175)
516
517 return -EINVAL;
518}
519
520int Process::sys$mprotect(void* addr, size_t size, int prot)
521{
522 REQUIRE_PROMISE(stdio);
523
524 if (!size)
525 return -EINVAL;
526
527 if (!is_user_range(VirtualAddress(addr), size))
528 return -EFAULT;
529
530 Range range_to_mprotect = { VirtualAddress(addr), size };
531
532 if (auto* whole_region = region_from_range(range_to_mprotect)) {
533 if (!whole_region->is_mmap())
534 return -EPERM;
535 if (!validate_mmap_prot(prot, whole_region->is_stack()))
536 return -EINVAL;
537 if (whole_region->access() == prot_to_region_access_flags(prot))
538 return 0;
539 if (whole_region->vmobject().is_inode()
540 && !validate_inode_mmap_prot(*this, prot, static_cast<const InodeVMObject&>(whole_region->vmobject()).inode(), whole_region->is_shared())) {
541 return -EACCES;
542 }
543 whole_region->set_readable(prot & PROT_READ);
544 whole_region->set_writable(prot & PROT_WRITE);
545 whole_region->set_executable(prot & PROT_EXEC);
546 whole_region->remap();
547 return 0;
548 }
549
550 // Check if we can carve out the desired range from an existing region
551 if (auto* old_region = region_containing(range_to_mprotect)) {
552 if (!old_region->is_mmap())
553 return -EPERM;
554 if (!validate_mmap_prot(prot, old_region->is_stack()))
555 return -EINVAL;
556 if (old_region->access() == prot_to_region_access_flags(prot))
557 return 0;
558 if (old_region->vmobject().is_inode()
559 && !validate_inode_mmap_prot(*this, prot, static_cast<const InodeVMObject&>(old_region->vmobject()).inode(), old_region->is_shared())) {
560 return -EACCES;
561 }
562
563 // This vector is the region(s) adjacent to our range.
564 // We need to allocate a new region for the range we wanted to change permission bits on.
565 auto adjacent_regions = split_region_around_range(*old_region, range_to_mprotect);
566
567 size_t new_range_offset_in_vmobject = old_region->offset_in_vmobject() + (range_to_mprotect.base().get() - old_region->range().base().get());
568 auto& new_region = allocate_split_region(*old_region, range_to_mprotect, new_range_offset_in_vmobject);
569 new_region.set_readable(prot & PROT_READ);
570 new_region.set_writable(prot & PROT_WRITE);
571 new_region.set_executable(prot & PROT_EXEC);
572
573 // Unmap the old region here, specifying that we *don't* want the VM deallocated.
574 old_region->unmap(Region::ShouldDeallocateVirtualMemoryRange::No);
575 deallocate_region(*old_region);
576
577 // Map the new regions using our page directory (they were just allocated and don't have one).
578 for (auto* adjacent_region : adjacent_regions) {
579 adjacent_region->map(page_directory());
580 }
581 new_region.map(page_directory());
582 return 0;
583 }
584
585 // FIXME: We should also support mprotect() across multiple regions. (#175) (#964)
586
587 return -EINVAL;
588}
589
590int Process::sys$madvise(void* address, size_t size, int advice)
591{
592 REQUIRE_PROMISE(stdio);
593
594 if (!size)
595 return -EINVAL;
596
597 if (!is_user_range(VirtualAddress(address), size))
598 return -EFAULT;
599
600 auto* region = region_from_range({ VirtualAddress(address), size });
601 if (!region)
602 return -EINVAL;
603 if (!region->is_mmap())
604 return -EPERM;
605 if ((advice & MADV_SET_VOLATILE) && (advice & MADV_SET_NONVOLATILE))
606 return -EINVAL;
607 if (advice & MADV_SET_VOLATILE) {
608 if (!region->vmobject().is_purgeable())
609 return -EPERM;
610 auto& vmobject = static_cast<PurgeableVMObject&>(region->vmobject());
611 vmobject.set_volatile(true);
612 return 0;
613 }
614 if (advice & MADV_SET_NONVOLATILE) {
615 if (!region->vmobject().is_purgeable())
616 return -EPERM;
617 auto& vmobject = static_cast<PurgeableVMObject&>(region->vmobject());
618 if (!vmobject.is_volatile())
619 return 0;
620 vmobject.set_volatile(false);
621 bool was_purged = vmobject.was_purged();
622 vmobject.set_was_purged(false);
623 return was_purged ? 1 : 0;
624 }
625 if (advice & MADV_GET_VOLATILE) {
626 if (!region->vmobject().is_purgeable())
627 return -EPERM;
628 auto& vmobject = static_cast<PurgeableVMObject&>(region->vmobject());
629 return vmobject.is_volatile() ? 0 : 1;
630 }
631 return -EINVAL;
632}
633
634int Process::sys$purge(int mode)
635{
636 REQUIRE_NO_PROMISES;
637 if (!is_superuser())
638 return -EPERM;
639 int purged_page_count = 0;
640 if (mode & PURGE_ALL_VOLATILE) {
641 NonnullRefPtrVector<PurgeableVMObject> vmobjects;
642 {
643 InterruptDisabler disabler;
644 MM.for_each_vmobject([&](auto& vmobject) {
645 if (vmobject.is_purgeable())
646 vmobjects.append(static_cast<PurgeableVMObject&>(vmobject));
647 return IterationDecision::Continue;
648 });
649 }
650 for (auto& vmobject : vmobjects) {
651 purged_page_count += vmobject.purge();
652 }
653 }
654 if (mode & PURGE_ALL_CLEAN_INODE) {
655 NonnullRefPtrVector<InodeVMObject> vmobjects;
656 {
657 InterruptDisabler disabler;
658 MM.for_each_vmobject([&](auto& vmobject) {
659 if (vmobject.is_inode())
660 vmobjects.append(static_cast<InodeVMObject&>(vmobject));
661 return IterationDecision::Continue;
662 });
663 }
664 for (auto& vmobject : vmobjects) {
665 purged_page_count += vmobject.release_all_clean_pages();
666 }
667 }
668 return purged_page_count;
669}
670
671int Process::sys$gethostname(char* buffer, ssize_t size)
672{
673 REQUIRE_PROMISE(stdio);
674 if (size < 0)
675 return -EINVAL;
676 if (!validate_write(buffer, size))
677 return -EFAULT;
678 LOCKER(*s_hostname_lock);
679 if ((size_t)size < (s_hostname->length() + 1))
680 return -ENAMETOOLONG;
681 copy_to_user(buffer, s_hostname->characters(), s_hostname->length() + 1);
682 return 0;
683}
684
685pid_t Process::sys$fork(RegisterState& regs)
686{
687 REQUIRE_PROMISE(proc);
688 Thread* child_first_thread = nullptr;
689 auto* child = new Process(child_first_thread, m_name, m_uid, m_gid, m_pid, m_ring, m_cwd, m_executable, m_tty, this);
690 child->m_root_directory = m_root_directory;
691 child->m_root_directory_relative_to_global_root = m_root_directory_relative_to_global_root;
692 child->m_promises = m_promises;
693 child->m_execpromises = m_execpromises;
694 child->m_veil_state = m_veil_state;
695 child->m_unveiled_paths = m_unveiled_paths;
696 child->m_fds = m_fds;
697 child->m_sid = m_sid;
698 child->m_pgid = m_pgid;
699 child->m_umask = m_umask;
700
701#ifdef FORK_DEBUG
702 dbg() << "fork: child=" << child;
703#endif
704
705 for (auto& region : m_regions) {
706#ifdef FORK_DEBUG
707 dbg() << "fork: cloning Region{" << ®ion << "} '" << region.name() << "' @ " << region.vaddr();
708#endif
709 auto& child_region = child->add_region(region.clone());
710 child_region.map(child->page_directory());
711
712 if (®ion == m_master_tls_region)
713 child->m_master_tls_region = child_region.make_weak_ptr();
714 }
715
716 child->m_extra_gids = m_extra_gids;
717
718 auto& child_tss = child_first_thread->m_tss;
719 child_tss.eax = 0; // fork() returns 0 in the child :^)
720 child_tss.ebx = regs.ebx;
721 child_tss.ecx = regs.ecx;
722 child_tss.edx = regs.edx;
723 child_tss.ebp = regs.ebp;
724 child_tss.esp = regs.userspace_esp;
725 child_tss.esi = regs.esi;
726 child_tss.edi = regs.edi;
727 child_tss.eflags = regs.eflags;
728 child_tss.eip = regs.eip;
729 child_tss.cs = regs.cs;
730 child_tss.ds = regs.ds;
731 child_tss.es = regs.es;
732 child_tss.fs = regs.fs;
733 child_tss.gs = regs.gs;
734 child_tss.ss = regs.userspace_ss;
735
736#ifdef FORK_DEBUG
737 dbg() << "fork: child will begin executing at " << String::format("%w", child_tss.cs) << ":" << String::format("%x", child_tss.eip) << " with stack " << String::format("%w", child_tss.ss) << ":" << String::format("%x", child_tss.esp) << ", kstack " << String::format("%w", child_tss.ss0) << ":" << String::format("%x", child_tss.esp0);
738#endif
739
740 {
741 InterruptDisabler disabler;
742 g_processes->prepend(child);
743 }
744#ifdef TASK_DEBUG
745 klog() << "Process " << child->pid() << " (" << child->name().characters() << ") forked from " << m_pid << " @ " << String::format("%p", child_tss.eip);
746#endif
747
748 child_first_thread->set_state(Thread::State::Skip1SchedulerPass);
749 return child->pid();
750}
751
752void Process::kill_threads_except_self()
753{
754 InterruptDisabler disabler;
755
756 if (m_thread_count <= 1)
757 return;
758
759 for_each_thread([&](Thread& thread) {
760 if (&thread == Thread::current
761 || thread.state() == Thread::State::Dead
762 || thread.state() == Thread::State::Dying)
763 return IterationDecision::Continue;
764
765 // At this point, we have no joiner anymore
766 thread.m_joiner = nullptr;
767 thread.set_should_die();
768
769 if (thread.state() != Thread::State::Dead)
770 thread.set_state(Thread::State::Dying);
771
772 return IterationDecision::Continue;
773 });
774
775 big_lock().clear_waiters();
776}
777
778void Process::kill_all_threads()
779{
780 for_each_thread([&](Thread& thread) {
781 thread.set_should_die();
782 return IterationDecision::Continue;
783 });
784}
785
786int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Vector<String> arguments, Vector<String> environment, RefPtr<FileDescription> interpreter_description)
787{
788 ASSERT(is_ring3());
789 auto path = main_program_description->absolute_path();
790 dbg() << "do_exec(" << path << ")";
791
792 size_t total_blob_size = 0;
793 for (auto& a : arguments)
794 total_blob_size += a.length() + 1;
795 for (auto& e : environment)
796 total_blob_size += e.length() + 1;
797
798 size_t total_meta_size = sizeof(char*) * (arguments.size() + 1) + sizeof(char*) * (environment.size() + 1);
799
800 // FIXME: How much stack space does process startup need?
801 if ((total_blob_size + total_meta_size) >= Thread::default_userspace_stack_size)
802 return -E2BIG;
803
804 auto parts = path.split('/');
805 if (parts.is_empty())
806 return -ENOENT;
807
808 auto& inode = interpreter_description ? *interpreter_description->inode() : *main_program_description->inode();
809 auto vmobject = SharedInodeVMObject::create_with_inode(inode);
810
811 if (static_cast<const SharedInodeVMObject&>(*vmobject).writable_mappings()) {
812 dbg() << "Refusing to execute a write-mapped program";
813 return -ETXTBSY;
814 }
815
816 // Disable profiling temporarily in case it's running on this process.
817 bool was_profiling = is_profiling();
818 TemporaryChange profiling_disabler(m_profiling, false);
819
820 // Mark this thread as the current thread that does exec
821 // No other thread from this process will be scheduled to run
822 m_exec_tid = Thread::current->tid();
823
824 auto old_page_directory = move(m_page_directory);
825 auto old_regions = move(m_regions);
826 m_page_directory = PageDirectory::create_for_userspace(*this);
827#ifdef MM_DEBUG
828 dbg() << "Process " << pid() << " exec: PD=" << m_page_directory.ptr() << " created";
829#endif
830
831 InodeMetadata loader_metadata;
832
833 // FIXME: Hoooo boy this is a hack if I ever saw one.
834 // This is the 'random' offset we're giving to our ET_DYN exectuables to start as.
835 // It also happens to be the static Virtual Addresss offset every static exectuable gets :)
836 // Without this, some assumptions by the ELF loading hooks below are severely broken.
837 // 0x08000000 is a verified random number chosen by random dice roll https://xkcd.com/221/
838 u32 totally_random_offset = interpreter_description ? 0x08000000 : 0;
839
840 // FIXME: We should be able to load both the PT_INTERP interpreter and the main program... once the RTLD is smart enough
841 if (interpreter_description) {
842 loader_metadata = interpreter_description->metadata();
843 // we don't need the interpreter file desciption after we've loaded (or not) it into memory
844 interpreter_description = nullptr;
845 } else {
846 loader_metadata = main_program_description->metadata();
847 }
848
849 auto region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_ROUND_UP(loader_metadata.size), "ELF loading", Region::Access::Read);
850 if (!region)
851 return -ENOMEM;
852
853 Region* master_tls_region { nullptr };
854 size_t master_tls_size = 0;
855 size_t master_tls_alignment = 0;
856 u32 entry_eip = 0;
857
858 MM.enter_process_paging_scope(*this);
859 OwnPtr<ELFLoader> loader;
860 {
861 ArmedScopeGuard rollback_regions_guard([&]() {
862 ASSERT(Process::current == this);
863 m_page_directory = move(old_page_directory);
864 m_regions = move(old_regions);
865 MM.enter_process_paging_scope(*this);
866 });
867 loader = make<ELFLoader>(region->vaddr().as_ptr(), loader_metadata.size);
868 // Load the correct executable -- either interp or main program.
869 // FIXME: Once we actually load both interp and main, we'll need to be more clever about this.
870 // In that case, both will be ET_DYN objects, so they'll both be completely relocatable.
871 // That means, we can put them literally anywhere in User VM space (ASLR anyone?).
872 // ALSO FIXME: Reminder to really really fix that 'totally random offset' business.
873 loader->map_section_hook = [&](VirtualAddress vaddr, size_t size, size_t alignment, size_t offset_in_image, bool is_readable, bool is_writable, bool is_executable, const String& name) -> u8* {
874 ASSERT(size);
875 ASSERT(alignment == PAGE_SIZE);
876 int prot = 0;
877 if (is_readable)
878 prot |= PROT_READ;
879 if (is_writable)
880 prot |= PROT_WRITE;
881 if (is_executable)
882 prot |= PROT_EXEC;
883 if (auto* region = allocate_region_with_vmobject(vaddr.offset(totally_random_offset), size, *vmobject, offset_in_image, String(name), prot)) {
884 region->set_shared(true);
885 return region->vaddr().as_ptr();
886 }
887 return nullptr;
888 };
889 loader->alloc_section_hook = [&](VirtualAddress vaddr, size_t size, size_t alignment, bool is_readable, bool is_writable, const String& name) -> u8* {
890 ASSERT(size);
891 ASSERT(alignment == PAGE_SIZE);
892 int prot = 0;
893 if (is_readable)
894 prot |= PROT_READ;
895 if (is_writable)
896 prot |= PROT_WRITE;
897 if (auto* region = allocate_region(vaddr.offset(totally_random_offset), size, String(name), prot))
898 return region->vaddr().as_ptr();
899 return nullptr;
900 };
901
902 // FIXME: Move TLS region allocation to userspace: LibC and the dynamic loader.
903 // LibC if we end up with a statically linked executable, and the
904 // dynamic loader so that it can create new TLS blocks for each shared libarary
905 // that gets loaded as part of DT_NEEDED processing, and via dlopen()
906 // If that doesn't happen quickly, at least pass the location of the TLS region
907 // some ELF Auxilliary Vector so the loader can use it/create new ones as necessary.
908 loader->tls_section_hook = [&](size_t size, size_t alignment) {
909 ASSERT(size);
910 master_tls_region = allocate_region({}, size, String(), PROT_READ | PROT_WRITE);
911 master_tls_size = size;
912 master_tls_alignment = alignment;
913 return master_tls_region->vaddr().as_ptr();
914 };
915 bool success = loader->load();
916 if (!success) {
917 klog() << "do_exec: Failure loading " << path.characters();
918 return -ENOEXEC;
919 }
920 // FIXME: Validate that this virtual address is within executable region,
921 // instead of just non-null. You could totally have a DSO with entry point of
922 // the beginning of the text segement.
923 if (!loader->entry().offset(totally_random_offset).get()) {
924 klog() << "do_exec: Failure loading " << path.characters() << ", entry pointer is invalid! (" << loader->entry().offset(totally_random_offset) << ")";
925 return -ENOEXEC;
926 }
927
928 rollback_regions_guard.disarm();
929
930 // NOTE: At this point, we've committed to the new executable.
931 entry_eip = loader->entry().offset(totally_random_offset).get();
932
933 kill_threads_except_self();
934
935#ifdef EXEC_DEBUG
936 klog() << "Memory layout after ELF load:";
937 dump_regions();
938#endif
939 }
940
941 m_executable = main_program_description->custody();
942
943 m_promises = m_execpromises;
944
945 m_veil_state = VeilState::None;
946 m_unveiled_paths.clear();
947
948 // Copy of the master TLS region that we will clone for new threads
949 m_master_tls_region = master_tls_region->make_weak_ptr();
950
951 auto main_program_metadata = main_program_description->metadata();
952
953 if (!(main_program_description->custody()->mount_flags() & MS_NOSUID)) {
954 if (main_program_metadata.is_setuid())
955 m_euid = main_program_metadata.uid;
956 if (main_program_metadata.is_setgid())
957 m_egid = main_program_metadata.gid;
958 }
959
960 Thread::current->set_default_signal_dispositions();
961 Thread::current->m_signal_mask = 0;
962 Thread::current->m_pending_signals = 0;
963
964 m_futex_queues.clear();
965
966 m_region_lookup_cache = {};
967
968 disown_all_shared_buffers();
969
970 for (size_t i = 0; i < m_fds.size(); ++i) {
971 auto& daf = m_fds[i];
972 if (daf.description && daf.flags & FD_CLOEXEC) {
973 daf.description->close();
974 daf = {};
975 }
976 }
977
978 Thread* new_main_thread = nullptr;
979 if (Process::current == this) {
980 new_main_thread = Thread::current;
981 } else {
982 for_each_thread([&](auto& thread) {
983 new_main_thread = &thread;
984 return IterationDecision::Break;
985 });
986 }
987 ASSERT(new_main_thread);
988
989 // NOTE: We create the new stack before disabling interrupts since it will zero-fault
990 // and we don't want to deal with faults after this point.
991 u32 new_userspace_esp = new_main_thread->make_userspace_stack_for_main_thread(move(arguments), move(environment));
992
993 // We cli() manually here because we don't want to get interrupted between do_exec() and Schedule::yield().
994 // The reason is that the task redirection we've set up above will be clobbered by the timer IRQ.
995 // If we used an InterruptDisabler that sti()'d on exit, we might timer tick'd too soon in exec().
996 if (Process::current == this)
997 cli();
998
999 // NOTE: Be careful to not trigger any page faults below!
1000
1001 Scheduler::prepare_to_modify_tss(*new_main_thread);
1002
1003 m_name = parts.take_last();
1004 new_main_thread->set_name(m_name);
1005
1006 auto& tss = new_main_thread->m_tss;
1007
1008 u32 old_esp0 = tss.esp0;
1009
1010 m_master_tls_size = master_tls_size;
1011 m_master_tls_alignment = master_tls_alignment;
1012
1013 m_pid = new_main_thread->tid();
1014 new_main_thread->make_thread_specific_region({});
1015 new_main_thread->reset_fpu_state();
1016
1017 memset(&tss, 0, sizeof(TSS32));
1018 tss.iomapbase = sizeof(TSS32);
1019
1020 tss.eflags = 0x0202;
1021 tss.eip = entry_eip;
1022 tss.cs = 0x1b;
1023 tss.ds = 0x23;
1024 tss.es = 0x23;
1025 tss.fs = 0x23;
1026 tss.gs = thread_specific_selector() | 3;
1027 tss.ss = 0x23;
1028 tss.cr3 = page_directory().cr3();
1029 tss.esp = new_userspace_esp;
1030 tss.ss0 = 0x10;
1031 tss.esp0 = old_esp0;
1032 tss.ss2 = m_pid;
1033
1034#ifdef TASK_DEBUG
1035 klog() << "Process exec'd " << path.characters() << " @ " << String::format("%p", tss.eip);
1036#endif
1037
1038 if (was_profiling)
1039 Profiling::did_exec(path);
1040
1041 new_main_thread->set_state(Thread::State::Skip1SchedulerPass);
1042 big_lock().force_unlock_if_locked();
1043 return 0;
1044}
1045
1046static KResultOr<Vector<String>> find_shebang_interpreter_for_executable(const char first_page[], int nread)
1047{
1048 int word_start = 2;
1049 int word_length = 0;
1050 if (nread > 2 && first_page[0] == '#' && first_page[1] == '!') {
1051 Vector<String> interpreter_words;
1052
1053 for (int i = 2; i < nread; ++i) {
1054 if (first_page[i] == '\n') {
1055 break;
1056 }
1057
1058 if (first_page[i] != ' ') {
1059 ++word_length;
1060 }
1061
1062 if (first_page[i] == ' ') {
1063 if (word_length > 0) {
1064 interpreter_words.append(String(&first_page[word_start], word_length));
1065 }
1066 word_length = 0;
1067 word_start = i + 1;
1068 }
1069 }
1070
1071 if (word_length > 0)
1072 interpreter_words.append(String(&first_page[word_start], word_length));
1073
1074 if (!interpreter_words.is_empty())
1075 return interpreter_words;
1076 }
1077
1078 return KResult(-ENOEXEC);
1079}
1080
1081KResultOr<NonnullRefPtr<FileDescription>> Process::find_elf_interpreter_for_executable(const String& path, char (&first_page)[PAGE_SIZE], int nread, size_t file_size)
1082{
1083 if (nread < (int)sizeof(Elf32_Ehdr))
1084 return KResult(-ENOEXEC);
1085
1086 auto elf_header = (Elf32_Ehdr*)first_page;
1087 if (!ELFImage::validate_elf_header(*elf_header, file_size)) {
1088 dbg() << "exec(" << path << "): File has invalid ELF header";
1089 return KResult(-ENOEXEC);
1090 }
1091
1092 // Not using KResultOr here because we'll want to do the same thing in userspace in the RTLD
1093 String interpreter_path;
1094 if (!ELFImage::validate_program_headers(*elf_header, file_size, (u8*)first_page, nread, interpreter_path)) {
1095 dbg() << "exec(" << path << "): File has invalid ELF Program headers";
1096 return KResult(-ENOEXEC);
1097 }
1098
1099 if (!interpreter_path.is_empty()) {
1100 // Programs with an interpreter better be relocatable executables or we don't know what to do...
1101 if (elf_header->e_type != ET_DYN)
1102 return KResult(-ENOEXEC);
1103
1104 dbg() << "exec(" << path << "): Using program interpreter " << interpreter_path;
1105 auto interp_result = VFS::the().open(interpreter_path, O_EXEC, 0, current_directory());
1106 if (interp_result.is_error()) {
1107 dbg() << "exec(" << path << "): Unable to open program interpreter " << interpreter_path;
1108 return interp_result.error();
1109 }
1110 auto interpreter_description = interp_result.value();
1111 auto interp_metadata = interpreter_description->metadata();
1112
1113 ASSERT(interpreter_description->inode());
1114
1115 // Validate the program interpreter as a valid elf binary.
1116 // If your program interpreter is a #! file or something, it's time to stop playing games :)
1117 if (interp_metadata.size < (int)sizeof(Elf32_Ehdr))
1118 return KResult(-ENOEXEC);
1119
1120 memset(first_page, 0, sizeof(first_page));
1121 nread = interpreter_description->read((u8*)&first_page, sizeof(first_page));
1122
1123 if (nread < (int)sizeof(Elf32_Ehdr))
1124 return KResult(-ENOEXEC);
1125
1126 elf_header = (Elf32_Ehdr*)first_page;
1127 if (!ELFImage::validate_elf_header(*elf_header, interp_metadata.size)) {
1128 dbg() << "exec(" << path << "): Interpreter (" << interpreter_description->absolute_path() << ") has invalid ELF header";
1129 return KResult(-ENOEXEC);
1130 }
1131
1132 // Not using KResultOr here because we'll want to do the same thing in userspace in the RTLD
1133 String interpreter_interpreter_path;
1134 if (!ELFImage::validate_program_headers(*elf_header, interp_metadata.size, (u8*)first_page, nread, interpreter_interpreter_path)) {
1135 dbg() << "exec(" << path << "): Interpreter (" << interpreter_description->absolute_path() << ") has invalid ELF Program headers";
1136 return KResult(-ENOEXEC);
1137 }
1138
1139 if (!interpreter_interpreter_path.is_empty()) {
1140 dbg() << "exec(" << path << "): Interpreter (" << interpreter_description->absolute_path() << ") has its own interpreter (" << interpreter_interpreter_path << ")! No thank you!";
1141 return KResult(-ELOOP);
1142 }
1143
1144 return interpreter_description;
1145 }
1146
1147 if (elf_header->e_type != ET_EXEC) {
1148 // We can't exec an ET_REL, that's just an object file from the compiler
1149 // If it's ET_DYN with no PT_INTERP, then we can't load it properly either
1150 return KResult(-ENOEXEC);
1151 }
1152
1153 // No interpreter, but, path refers to a valid elf image
1154 return KResult(KSuccess);
1155}
1156
1157int Process::exec(String path, Vector<String> arguments, Vector<String> environment, int recursion_depth)
1158{
1159 if (recursion_depth > 2) {
1160 dbg() << "exec(" << path << "): SHENANIGANS! recursed too far trying to find #! interpreter";
1161 return -ELOOP;
1162 }
1163
1164 // Open the file to check what kind of binary format it is
1165 // Currently supported formats:
1166 // - #! interpreted file
1167 // - ELF32
1168 // * ET_EXEC binary that just gets loaded
1169 // * ET_DYN binary that requires a program interpreter
1170 //
1171 auto result = VFS::the().open(path, O_EXEC, 0, current_directory());
1172 if (result.is_error())
1173 return result.error();
1174 auto description = result.value();
1175 auto metadata = description->metadata();
1176
1177 // Always gonna need at least 3 bytes. these are for #!X
1178 if (metadata.size < 3)
1179 return -ENOEXEC;
1180
1181 ASSERT(description->inode());
1182
1183 // Read the first page of the program into memory so we can validate the binfmt of it
1184 char first_page[PAGE_SIZE];
1185 int nread = description->read((u8*)&first_page, sizeof(first_page));
1186
1187 // 1) #! interpreted file
1188 auto shebang_result = find_shebang_interpreter_for_executable(first_page, nread);
1189 if (!shebang_result.is_error()) {
1190 Vector<String> new_arguments(shebang_result.value());
1191
1192 new_arguments.append(path);
1193
1194 arguments.remove(0);
1195 new_arguments.append(move(arguments));
1196
1197 return exec(shebang_result.value().first(), move(new_arguments), move(environment), ++recursion_depth);
1198 }
1199
1200 // #2) ELF32 for i386
1201 auto elf_result = find_elf_interpreter_for_executable(path, first_page, nread, metadata.size);
1202 RefPtr<FileDescription> interpreter_description;
1203 // We're getting either an interpreter, an error, or KSuccess (i.e. no interpreter but file checks out)
1204 if (!elf_result.is_error())
1205 interpreter_description = elf_result.value();
1206 else if (elf_result.error().is_error())
1207 return elf_result.error();
1208
1209 // The bulk of exec() is done by do_exec(), which ensures that all locals
1210 // are cleaned up by the time we yield-teleport below.
1211 int rc = do_exec(move(description), move(arguments), move(environment), move(interpreter_description));
1212
1213 m_exec_tid = 0;
1214
1215 if (rc < 0)
1216 return rc;
1217
1218 if (Process::current == this) {
1219 Scheduler::yield();
1220 ASSERT_NOT_REACHED();
1221 }
1222 return 0;
1223}
1224
1225int Process::sys$execve(const Syscall::SC_execve_params* user_params)
1226{
1227 REQUIRE_PROMISE(exec);
1228
1229 // NOTE: Be extremely careful with allocating any kernel memory in exec().
1230 // On success, the kernel stack will be lost.
1231 Syscall::SC_execve_params params;
1232 if (!validate_read_and_copy_typed(¶ms, user_params))
1233 return -EFAULT;
1234
1235 if (params.arguments.length > ARG_MAX || params.environment.length > ARG_MAX)
1236 return -E2BIG;
1237
1238 if (m_wait_for_tracer_at_next_execve)
1239 Thread::current->send_urgent_signal_to_self(SIGSTOP);
1240
1241 String path;
1242 {
1243 auto path_arg = get_syscall_path_argument(params.path);
1244 if (path_arg.is_error())
1245 return path_arg.error();
1246 path = path_arg.value();
1247 }
1248
1249 auto copy_user_strings = [&](const auto& list, auto& output) {
1250 if (!list.length)
1251 return true;
1252 if (!validate_read_typed(list.strings, list.length))
1253 return false;
1254 Vector<Syscall::StringArgument, 32> strings;
1255 strings.resize(list.length);
1256 copy_from_user(strings.data(), list.strings, list.length * sizeof(Syscall::StringArgument));
1257 for (size_t i = 0; i < list.length; ++i) {
1258 auto string = validate_and_copy_string_from_user(strings[i]);
1259 if (string.is_null())
1260 return false;
1261 output.append(move(string));
1262 }
1263 return true;
1264 };
1265
1266 Vector<String> arguments;
1267 if (!copy_user_strings(params.arguments, arguments))
1268 return -EFAULT;
1269
1270 Vector<String> environment;
1271 if (!copy_user_strings(params.environment, environment))
1272 return -EFAULT;
1273
1274 int rc = exec(move(path), move(arguments), move(environment));
1275 ASSERT(rc < 0); // We should never continue after a successful exec!
1276 return rc;
1277}
1278
1279Process* Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, pid_t parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
1280{
1281 auto parts = path.split('/');
1282 if (arguments.is_empty()) {
1283 arguments.append(parts.last());
1284 }
1285 RefPtr<Custody> cwd;
1286 RefPtr<Custody> root;
1287 {
1288 InterruptDisabler disabler;
1289 if (auto* parent = Process::from_pid(parent_pid)) {
1290 cwd = parent->m_cwd;
1291 root = parent->m_root_directory;
1292 }
1293 }
1294
1295 if (!cwd)
1296 cwd = VFS::the().root_custody();
1297
1298 if (!root)
1299 root = VFS::the().root_custody();
1300
1301 auto* process = new Process(first_thread, parts.take_last(), uid, gid, parent_pid, Ring3, move(cwd), nullptr, tty);
1302 process->m_fds.resize(m_max_open_file_descriptors);
1303 auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : NullDevice::the();
1304 auto description = device_to_use_as_tty.open(O_RDWR).value();
1305 process->m_fds[0].set(*description);
1306 process->m_fds[1].set(*description);
1307 process->m_fds[2].set(*description);
1308
1309 error = process->exec(path, move(arguments), move(environment));
1310 if (error != 0) {
1311 delete process;
1312 return nullptr;
1313 }
1314
1315 {
1316 InterruptDisabler disabler;
1317 g_processes->prepend(process);
1318 }
1319#ifdef TASK_DEBUG
1320 klog() << "Process " << process->pid() << " (" << process->name().characters() << ") spawned @ " << String::format("%p", first_thread->tss().eip);
1321#endif
1322 error = 0;
1323 return process;
1324}
1325
1326Process* Process::create_kernel_process(Thread*& first_thread, String&& name, void (*e)())
1327{
1328 auto* process = new Process(first_thread, move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0);
1329 first_thread->tss().eip = (FlatPtr)e;
1330
1331 if (process->pid() != 0) {
1332 InterruptDisabler disabler;
1333 g_processes->prepend(process);
1334#ifdef TASK_DEBUG
1335 klog() << "Kernel process " << process->pid() << " (" << process->name().characters() << ") spawned @ " << String::format("%p", first_thread->tss().eip);
1336#endif
1337 }
1338
1339 first_thread->set_state(Thread::State::Runnable);
1340 return process;
1341}
1342
1343Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
1344 : m_name(move(name))
1345 , m_pid(allocate_pid())
1346 , m_uid(uid)
1347 , m_gid(gid)
1348 , m_euid(uid)
1349 , m_egid(gid)
1350 , m_ring(ring)
1351 , m_executable(move(executable))
1352 , m_cwd(move(cwd))
1353 , m_tty(tty)
1354 , m_ppid(ppid)
1355{
1356#ifdef PROCESS_DEBUG
1357 dbg() << "Created new process " << m_name << "(" << m_pid << ")";
1358#endif
1359
1360 m_page_directory = PageDirectory::create_for_userspace(*this, fork_parent ? &fork_parent->page_directory().range_allocator() : nullptr);
1361#ifdef MM_DEBUG
1362 dbg() << "Process " << pid() << " ctor: PD=" << m_page_directory.ptr() << " created";
1363#endif
1364
1365 if (fork_parent) {
1366 // NOTE: fork() doesn't clone all threads; the thread that called fork() becomes the only thread in the new process.
1367 first_thread = Thread::current->clone(*this);
1368 } else {
1369 // NOTE: This non-forked code path is only taken when the kernel creates a process "manually" (at boot.)
1370 first_thread = new Thread(*this);
1371 }
1372}
1373
1374Process::~Process()
1375{
1376 ASSERT(thread_count() == 0);
1377}
1378
1379void Process::dump_regions()
1380{
1381 klog() << "Process regions:";
1382 klog() << "BEGIN END SIZE ACCESS NAME";
1383 for (auto& region : m_regions) {
1384 klog() << String::format("%08x", region.vaddr().get()) << " -- " << String::format("%08x", region.vaddr().offset(region.size() - 1).get()) << " " << String::format("%08x", region.size()) << " " << (region.is_readable() ? 'R' : ' ') << (region.is_writable() ? 'W' : ' ') << (region.is_executable() ? 'X' : ' ') << (region.is_shared() ? 'S' : ' ') << (region.is_stack() ? 'T' : ' ') << (region.vmobject().is_purgeable() ? 'P' : ' ') << " " << region.name().characters();
1385 }
1386 MM.dump_kernel_regions();
1387}
1388
1389void Process::sys$exit(int status)
1390{
1391 cli();
1392#ifdef TASK_DEBUG
1393 klog() << "sys$exit: exit with status " << status;
1394#endif
1395
1396 if (status != 0)
1397 dump_backtrace();
1398
1399 m_termination_status = status;
1400 m_termination_signal = 0;
1401 die();
1402 Thread::current->die_if_needed();
1403 ASSERT_NOT_REACHED();
1404}
1405
1406void signal_trampoline_dummy(void)
1407{
1408 // The trampoline preserves the current eax, pushes the signal code and
1409 // then calls the signal handler. We do this because, when interrupting a
1410 // blocking syscall, that syscall may return some special error code in eax;
1411 // This error code would likely be overwritten by the signal handler, so it's
1412 // neccessary to preserve it here.
1413 asm(
1414 ".intel_syntax noprefix\n"
1415 "asm_signal_trampoline:\n"
1416 "push ebp\n"
1417 "mov ebp, esp\n"
1418 "push eax\n" // we have to store eax 'cause it might be the return value from a syscall
1419 "sub esp, 4\n" // align the stack to 16 bytes
1420 "mov eax, [ebp+12]\n" // push the signal code
1421 "push eax\n"
1422 "call [ebp+8]\n" // call the signal handler
1423 "add esp, 8\n"
1424 "mov eax, %P0\n"
1425 "int 0x82\n" // sigreturn syscall
1426 "asm_signal_trampoline_end:\n"
1427 ".att_syntax" ::"i"(Syscall::SC_sigreturn));
1428}
1429
1430extern "C" void asm_signal_trampoline(void);
1431extern "C" void asm_signal_trampoline_end(void);
1432
1433void create_signal_trampolines()
1434{
1435 InterruptDisabler disabler;
1436 // NOTE: We leak this region.
1437 auto* trampoline_region = MM.allocate_user_accessible_kernel_region(PAGE_SIZE, "Signal trampolines", Region::Access::Read | Region::Access::Write | Region::Access::Execute, false).leak_ptr();
1438 g_return_to_ring3_from_signal_trampoline = trampoline_region->vaddr();
1439
1440 u8* trampoline = (u8*)asm_signal_trampoline;
1441 u8* trampoline_end = (u8*)asm_signal_trampoline_end;
1442 size_t trampoline_size = trampoline_end - trampoline;
1443
1444 {
1445 SmapDisabler disabler;
1446 u8* code_ptr = (u8*)trampoline_region->vaddr().as_ptr();
1447 memcpy(code_ptr, trampoline, trampoline_size);
1448 }
1449
1450 trampoline_region->set_writable(false);
1451 trampoline_region->remap();
1452}
1453
1454void create_kernel_info_page()
1455{
1456 auto* info_page_region_for_userspace = MM.allocate_user_accessible_kernel_region(PAGE_SIZE, "Kernel info page", Region::Access::Read).leak_ptr();
1457 auto* info_page_region_for_kernel = MM.allocate_kernel_region_with_vmobject(info_page_region_for_userspace->vmobject(), PAGE_SIZE, "Kernel info page", Region::Access::Read | Region::Access::Write).leak_ptr();
1458 s_info_page_address_for_userspace = info_page_region_for_userspace->vaddr();
1459 s_info_page_address_for_kernel = info_page_region_for_kernel->vaddr();
1460 memset(s_info_page_address_for_kernel.as_ptr(), 0, PAGE_SIZE);
1461}
1462
1463int Process::sys$sigreturn(RegisterState& registers)
1464{
1465 REQUIRE_PROMISE(stdio);
1466 SmapDisabler disabler;
1467
1468 //Here, we restore the state pushed by dispatch signal and asm_signal_trampoline.
1469 u32* stack_ptr = (u32*)registers.userspace_esp;
1470 u32 smuggled_eax = *stack_ptr;
1471
1472 //pop the stored eax, ebp, return address, handler and signal code
1473 stack_ptr += 5;
1474
1475 Thread::current->m_signal_mask = *stack_ptr;
1476 stack_ptr++;
1477
1478 //pop edi, esi, ebp, esp, ebx, edx, ecx and eax
1479 memcpy(®isters.edi, stack_ptr, 8 * sizeof(FlatPtr));
1480 stack_ptr += 8;
1481
1482 registers.eip = *stack_ptr;
1483 stack_ptr++;
1484
1485 registers.eflags = *stack_ptr;
1486 stack_ptr++;
1487
1488 registers.userspace_esp = registers.esp;
1489 return smuggled_eax;
1490}
1491
1492void Process::crash(int signal, u32 eip)
1493{
1494 ASSERT_INTERRUPTS_DISABLED();
1495 ASSERT(!is_dead());
1496 ASSERT(Process::current == this);
1497
1498 if (eip >= 0xc0000000 && g_kernel_symbols_available) {
1499 auto* symbol = symbolicate_kernel_address(eip);
1500 dbg() << "\033[31;1m" << String::format("%p", eip) << " " << (symbol ? demangle(symbol->name) : "(k?)") << " +" << (symbol ? eip - symbol->address : 0) << "\033[0m\n";
1501 } else if (auto elf_bundle = this->elf_bundle()) {
1502 dbg() << "\033[31;1m" << String::format("%p", eip) << " " << elf_bundle->elf_loader->symbolicate(eip) << "\033[0m\n";
1503 } else {
1504 dbg() << "\033[31;1m" << String::format("%p", eip) << " (?)\033[0m\n";
1505 }
1506 dump_backtrace();
1507
1508 m_termination_signal = signal;
1509 dump_regions();
1510 ASSERT(is_ring3());
1511 die();
1512 // We can not return from here, as there is nowhere
1513 // to unwind to, so die right away.
1514 Thread::current->die_if_needed();
1515 ASSERT_NOT_REACHED();
1516}
1517
1518Process* Process::from_pid(pid_t pid)
1519{
1520 ASSERT_INTERRUPTS_DISABLED();
1521 for (auto& process : *g_processes) {
1522 if (process.pid() == pid)
1523 return &process;
1524 }
1525 return nullptr;
1526}
1527
1528RefPtr<FileDescription> Process::file_description(int fd) const
1529{
1530 if (fd < 0)
1531 return nullptr;
1532 if (static_cast<size_t>(fd) < m_fds.size())
1533 return m_fds[fd].description.ptr();
1534 return nullptr;
1535}
1536
1537int Process::fd_flags(int fd) const
1538{
1539 if (fd < 0)
1540 return -1;
1541 if (static_cast<size_t>(fd) < m_fds.size())
1542 return m_fds[fd].flags;
1543 return -1;
1544}
1545
1546ssize_t Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size)
1547{
1548 REQUIRE_PROMISE(stdio);
1549 if (size < 0)
1550 return -EINVAL;
1551 if (!validate_write(buffer, size))
1552 return -EFAULT;
1553 auto description = file_description(fd);
1554 if (!description)
1555 return -EBADF;
1556 return description->get_dir_entries((u8*)buffer, size);
1557}
1558
1559int Process::sys$lseek(int fd, off_t offset, int whence)
1560{
1561 REQUIRE_PROMISE(stdio);
1562 auto description = file_description(fd);
1563 if (!description)
1564 return -EBADF;
1565 return description->seek(offset, whence);
1566}
1567
1568int Process::sys$ttyname_r(int fd, char* buffer, ssize_t size)
1569{
1570 REQUIRE_PROMISE(tty);
1571 if (size < 0)
1572 return -EINVAL;
1573 if (!validate_write(buffer, size))
1574 return -EFAULT;
1575 auto description = file_description(fd);
1576 if (!description)
1577 return -EBADF;
1578 if (!description->is_tty())
1579 return -ENOTTY;
1580 String tty_name = description->tty()->tty_name();
1581 if ((size_t)size < tty_name.length() + 1)
1582 return -ERANGE;
1583 copy_to_user(buffer, tty_name.characters(), tty_name.length() + 1);
1584 return 0;
1585}
1586
1587int Process::sys$ptsname_r(int fd, char* buffer, ssize_t size)
1588{
1589 REQUIRE_PROMISE(tty);
1590 if (size < 0)
1591 return -EINVAL;
1592 if (!validate_write(buffer, size))
1593 return -EFAULT;
1594 auto description = file_description(fd);
1595 if (!description)
1596 return -EBADF;
1597 auto* master_pty = description->master_pty();
1598 if (!master_pty)
1599 return -ENOTTY;
1600 auto pts_name = master_pty->pts_name();
1601 if ((size_t)size < pts_name.length() + 1)
1602 return -ERANGE;
1603 copy_to_user(buffer, pts_name.characters(), pts_name.length() + 1);
1604 return 0;
1605}
1606
1607ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
1608{
1609 REQUIRE_PROMISE(stdio);
1610 if (iov_count < 0)
1611 return -EINVAL;
1612
1613 if (!validate_read_typed(iov, iov_count))
1614 return -EFAULT;
1615
1616 u64 total_length = 0;
1617 Vector<iovec, 32> vecs;
1618 vecs.resize(iov_count);
1619 copy_from_user(vecs.data(), iov, iov_count * sizeof(iovec));
1620 for (auto& vec : vecs) {
1621 if (!validate_read(vec.iov_base, vec.iov_len))
1622 return -EFAULT;
1623 total_length += vec.iov_len;
1624 if (total_length > INT32_MAX)
1625 return -EINVAL;
1626 }
1627
1628 auto description = file_description(fd);
1629 if (!description)
1630 return -EBADF;
1631
1632 if (!description->is_writable())
1633 return -EBADF;
1634
1635 int nwritten = 0;
1636 for (auto& vec : vecs) {
1637 int rc = do_write(*description, (const u8*)vec.iov_base, vec.iov_len);
1638 if (rc < 0) {
1639 if (nwritten == 0)
1640 return rc;
1641 return nwritten;
1642 }
1643 nwritten += rc;
1644 }
1645
1646 return nwritten;
1647}
1648
1649ssize_t Process::do_write(FileDescription& description, const u8* data, int data_size)
1650{
1651 ssize_t nwritten = 0;
1652 if (!description.is_blocking()) {
1653 if (!description.can_write())
1654 return -EAGAIN;
1655 }
1656
1657 if (description.should_append()) {
1658#ifdef IO_DEBUG
1659 dbg() << "seeking to end (O_APPEND)";
1660#endif
1661 description.seek(0, SEEK_END);
1662 }
1663
1664 while (nwritten < data_size) {
1665#ifdef IO_DEBUG
1666 dbg() << "while " << nwritten << " < " << size;
1667#endif
1668 if (!description.can_write()) {
1669#ifdef IO_DEBUG
1670 dbg() << "block write on " << description.absolute_path();
1671#endif
1672 if (Thread::current->block<Thread::WriteBlocker>(description) != Thread::BlockResult::WokeNormally) {
1673 if (nwritten == 0)
1674 return -EINTR;
1675 }
1676 }
1677 ssize_t rc = description.write(data + nwritten, data_size - nwritten);
1678#ifdef IO_DEBUG
1679 dbg() << " -> write returned " << rc;
1680#endif
1681 if (rc < 0) {
1682 if (nwritten)
1683 return nwritten;
1684 return rc;
1685 }
1686 if (rc == 0)
1687 break;
1688 nwritten += rc;
1689 }
1690 return nwritten;
1691}
1692
1693ssize_t Process::sys$write(int fd, const u8* data, ssize_t size)
1694{
1695 REQUIRE_PROMISE(stdio);
1696 if (size < 0)
1697 return -EINVAL;
1698 if (size == 0)
1699 return 0;
1700 if (!validate_read(data, size))
1701 return -EFAULT;
1702#ifdef DEBUG_IO
1703 dbg() << "sys$write(" << fd << ", " << (const void*)(data) << ", " << size << ")";
1704#endif
1705 auto description = file_description(fd);
1706 if (!description)
1707 return -EBADF;
1708 if (!description->is_writable())
1709 return -EBADF;
1710
1711 return do_write(*description, data, size);
1712}
1713
1714ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size)
1715{
1716 REQUIRE_PROMISE(stdio);
1717 if (size < 0)
1718 return -EINVAL;
1719 if (size == 0)
1720 return 0;
1721 if (!validate_write(buffer, size))
1722 return -EFAULT;
1723#ifdef DEBUG_IO
1724 dbg() << "sys$read(" << fd << ", " << (const void*)buffer << ", " << size << ")";
1725#endif
1726 auto description = file_description(fd);
1727 if (!description)
1728 return -EBADF;
1729 if (!description->is_readable())
1730 return -EBADF;
1731 if (description->is_directory())
1732 return -EISDIR;
1733 if (description->is_blocking()) {
1734 if (!description->can_read()) {
1735 if (Thread::current->block<Thread::ReadBlocker>(*description) != Thread::BlockResult::WokeNormally)
1736 return -EINTR;
1737 if (!description->can_read())
1738 return -EAGAIN;
1739 }
1740 }
1741 return description->read(buffer, size);
1742}
1743
1744int Process::sys$close(int fd)
1745{
1746 REQUIRE_PROMISE(stdio);
1747 auto description = file_description(fd);
1748#ifdef DEBUG_IO
1749 dbg() << "sys$close(" << fd << ") " << description.ptr();
1750#endif
1751 if (!description)
1752 return -EBADF;
1753 int rc = description->close();
1754 m_fds[fd] = {};
1755 return rc;
1756}
1757
1758int Process::sys$utime(const char* user_path, size_t path_length, const utimbuf* user_buf)
1759{
1760 REQUIRE_PROMISE(fattr);
1761 if (user_buf && !validate_read_typed(user_buf))
1762 return -EFAULT;
1763 auto path = get_syscall_path_argument(user_path, path_length);
1764 if (path.is_error())
1765 return path.error();
1766 utimbuf buf;
1767 if (user_buf) {
1768 copy_from_user(&buf, user_buf);
1769 } else {
1770 auto now = kgettimeofday();
1771 buf = { now.tv_sec, now.tv_sec };
1772 }
1773 return VFS::the().utime(path.value(), current_directory(), buf.actime, buf.modtime);
1774}
1775
1776int Process::sys$access(const char* user_path, size_t path_length, int mode)
1777{
1778 REQUIRE_PROMISE(rpath);
1779 auto path = get_syscall_path_argument(user_path, path_length);
1780 if (path.is_error())
1781 return path.error();
1782 return VFS::the().access(path.value(), mode, current_directory());
1783}
1784
1785int Process::sys$fcntl(int fd, int cmd, u32 arg)
1786{
1787 REQUIRE_PROMISE(stdio);
1788#ifdef DEBUG_IO
1789 dbg() << "sys$fcntl: fd=" << fd << ", cmd=" << cmd << ", arg=" << arg;
1790#endif
1791 auto description = file_description(fd);
1792 if (!description)
1793 return -EBADF;
1794 // NOTE: The FD flags are not shared between FileDescription objects.
1795 // This means that dup() doesn't copy the FD_CLOEXEC flag!
1796 switch (cmd) {
1797 case F_DUPFD: {
1798 int arg_fd = (int)arg;
1799 if (arg_fd < 0)
1800 return -EINVAL;
1801 int new_fd = alloc_fd(arg_fd);
1802 if (new_fd < 0)
1803 return new_fd;
1804 m_fds[new_fd].set(*description);
1805 return new_fd;
1806 }
1807 case F_GETFD:
1808 return m_fds[fd].flags;
1809 case F_SETFD:
1810 m_fds[fd].flags = arg;
1811 break;
1812 case F_GETFL:
1813 return description->file_flags();
1814 case F_SETFL:
1815 description->set_file_flags(arg);
1816 break;
1817 default:
1818 ASSERT_NOT_REACHED();
1819 }
1820 return 0;
1821}
1822
1823int Process::sys$fstat(int fd, stat* user_statbuf)
1824{
1825 REQUIRE_PROMISE(stdio);
1826 if (!validate_write_typed(user_statbuf))
1827 return -EFAULT;
1828 auto description = file_description(fd);
1829 if (!description)
1830 return -EBADF;
1831 stat buffer;
1832 memset(&buffer, 0, sizeof(buffer));
1833 int rc = description->fstat(buffer);
1834 copy_to_user(user_statbuf, &buffer);
1835 return rc;
1836}
1837
1838int Process::sys$stat(const Syscall::SC_stat_params* user_params)
1839{
1840 REQUIRE_PROMISE(rpath);
1841 Syscall::SC_stat_params params;
1842 if (!validate_read_and_copy_typed(¶ms, user_params))
1843 return -EFAULT;
1844 if (!validate_write_typed(params.statbuf))
1845 return -EFAULT;
1846 auto path = get_syscall_path_argument(params.path);
1847 if (path.is_error())
1848 return path.error();
1849 auto metadata_or_error = VFS::the().lookup_metadata(path.value(), current_directory(), params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR);
1850 if (metadata_or_error.is_error())
1851 return metadata_or_error.error();
1852 stat statbuf;
1853 auto result = metadata_or_error.value().stat(statbuf);
1854 if (result.is_error())
1855 return result;
1856 copy_to_user(params.statbuf, &statbuf);
1857 return 0;
1858}
1859
1860template<typename DataType, typename SizeType>
1861bool Process::validate(const Syscall::MutableBufferArgument<DataType, SizeType>& buffer)
1862{
1863 return validate_write(buffer.data, buffer.size);
1864}
1865
1866template<typename DataType, typename SizeType>
1867bool Process::validate(const Syscall::ImmutableBufferArgument<DataType, SizeType>& buffer)
1868{
1869 return validate_read(buffer.data, buffer.size);
1870}
1871
1872String Process::validate_and_copy_string_from_user(const char* user_characters, size_t user_length) const
1873{
1874 if (user_length == 0)
1875 return String::empty();
1876 if (!user_characters)
1877 return {};
1878 if (!validate_read(user_characters, user_length))
1879 return {};
1880 SmapDisabler disabler;
1881 size_t measured_length = strnlen(user_characters, user_length);
1882 return String(user_characters, measured_length);
1883}
1884
1885String Process::validate_and_copy_string_from_user(const Syscall::StringArgument& string) const
1886{
1887 return validate_and_copy_string_from_user(string.characters, string.length);
1888}
1889
1890int Process::sys$readlink(const Syscall::SC_readlink_params* user_params)
1891{
1892 REQUIRE_PROMISE(rpath);
1893
1894 Syscall::SC_readlink_params params;
1895 if (!validate_read_and_copy_typed(¶ms, user_params))
1896 return -EFAULT;
1897
1898 if (!validate(params.buffer))
1899 return -EFAULT;
1900
1901 auto path = get_syscall_path_argument(params.path);
1902 if (path.is_error())
1903 return path.error();
1904
1905 auto result = VFS::the().open(path.value(), O_RDONLY | O_NOFOLLOW_NOERROR, 0, current_directory());
1906 if (result.is_error())
1907 return result.error();
1908 auto description = result.value();
1909
1910 if (!description->metadata().is_symlink())
1911 return -EINVAL;
1912
1913 auto contents = description->read_entire_file();
1914 if (!contents)
1915 return -EIO; // FIXME: Get a more detailed error from VFS.
1916
1917 auto link_target = String::copy(contents);
1918 if (link_target.length() + 1 > params.buffer.size)
1919 return -ENAMETOOLONG;
1920 copy_to_user(params.buffer.data, link_target.characters(), link_target.length() + 1);
1921 return link_target.length() + 1;
1922}
1923
1924int Process::sys$chdir(const char* user_path, size_t path_length)
1925{
1926 REQUIRE_PROMISE(rpath);
1927 auto path = get_syscall_path_argument(user_path, path_length);
1928 if (path.is_error())
1929 return path.error();
1930 auto directory_or_error = VFS::the().open_directory(path.value(), current_directory());
1931 if (directory_or_error.is_error())
1932 return directory_or_error.error();
1933 m_cwd = *directory_or_error.value();
1934 return 0;
1935}
1936
1937int Process::sys$fchdir(int fd)
1938{
1939 REQUIRE_PROMISE(stdio);
1940 auto description = file_description(fd);
1941 if (!description)
1942 return -EBADF;
1943
1944 if (!description->is_directory())
1945 return -ENOTDIR;
1946
1947 if (!description->metadata().may_execute(*this))
1948 return -EACCES;
1949
1950 m_cwd = description->custody();
1951 return 0;
1952}
1953
1954int Process::sys$getcwd(char* buffer, ssize_t size)
1955{
1956 REQUIRE_PROMISE(rpath);
1957 if (size < 0)
1958 return -EINVAL;
1959 if (!validate_write(buffer, size))
1960 return -EFAULT;
1961 auto path = current_directory().absolute_path();
1962 if ((size_t)size < path.length() + 1)
1963 return -ERANGE;
1964 copy_to_user(buffer, path.characters(), path.length() + 1);
1965 return 0;
1966}
1967
1968int Process::number_of_open_file_descriptors() const
1969{
1970 int count = 0;
1971 for (auto& description : m_fds) {
1972 if (description)
1973 ++count;
1974 }
1975 return count;
1976}
1977
1978int Process::sys$open(const Syscall::SC_open_params* user_params)
1979{
1980 Syscall::SC_open_params params;
1981 if (!validate_read_and_copy_typed(¶ms, user_params))
1982 return -EFAULT;
1983
1984 int dirfd = params.dirfd;
1985 int options = params.options;
1986 u16 mode = params.mode;
1987
1988 if (options & O_NOFOLLOW_NOERROR)
1989 return -EINVAL;
1990
1991 if (options & O_UNLINK_INTERNAL)
1992 return -EINVAL;
1993
1994 if (options & O_WRONLY)
1995 REQUIRE_PROMISE(wpath);
1996 else if (options & O_RDONLY)
1997 REQUIRE_PROMISE(rpath);
1998
1999 if (options & O_CREAT)
2000 REQUIRE_PROMISE(cpath);
2001
2002 // Ignore everything except permission bits.
2003 mode &= 04777;
2004
2005 auto path = get_syscall_path_argument(params.path);
2006 if (path.is_error())
2007 return path.error();
2008#ifdef DEBUG_IO
2009 dbg() << "sys$open(dirfd=" << dirfd << ", path=\"" << path.value() << "\", options=" << options << ", mode=" << mode << ")";
2010#endif
2011 int fd = alloc_fd();
2012 if (fd < 0)
2013 return fd;
2014
2015 RefPtr<Custody> base;
2016 if (dirfd == AT_FDCWD) {
2017 base = current_directory();
2018 } else {
2019 auto base_description = file_description(dirfd);
2020 if (!base_description)
2021 return -EBADF;
2022 if (!base_description->is_directory())
2023 return -ENOTDIR;
2024 if (!base_description->custody())
2025 return -EINVAL;
2026 base = base_description->custody();
2027 }
2028
2029 auto result = VFS::the().open(path.value(), options, mode & ~umask(), *base);
2030 if (result.is_error())
2031 return result.error();
2032 auto description = result.value();
2033 u32 fd_flags = (options & O_CLOEXEC) ? FD_CLOEXEC : 0;
2034 m_fds[fd].set(move(description), fd_flags);
2035 return fd;
2036}
2037
2038int Process::alloc_fd(int first_candidate_fd)
2039{
2040 for (int i = first_candidate_fd; i < (int)m_max_open_file_descriptors; ++i) {
2041 if (!m_fds[i])
2042 return i;
2043 }
2044 return -EMFILE;
2045}
2046
2047int Process::sys$pipe(int pipefd[2], int flags)
2048{
2049 REQUIRE_PROMISE(stdio);
2050 if (!validate_write_typed(pipefd))
2051 return -EFAULT;
2052 if (number_of_open_file_descriptors() + 2 > max_open_file_descriptors())
2053 return -EMFILE;
2054 // Reject flags other than O_CLOEXEC.
2055 if ((flags & O_CLOEXEC) != flags)
2056 return -EINVAL;
2057
2058 u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0;
2059 auto fifo = FIFO::create(m_uid);
2060
2061 int reader_fd = alloc_fd();
2062 m_fds[reader_fd].set(fifo->open_direction(FIFO::Direction::Reader), fd_flags);
2063 m_fds[reader_fd].description->set_readable(true);
2064 copy_to_user(&pipefd[0], &reader_fd);
2065
2066 int writer_fd = alloc_fd();
2067 m_fds[writer_fd].set(fifo->open_direction(FIFO::Direction::Writer), fd_flags);
2068 m_fds[writer_fd].description->set_writable(true);
2069 copy_to_user(&pipefd[1], &writer_fd);
2070
2071 return 0;
2072}
2073
2074int Process::sys$killpg(int pgrp, int signum)
2075{
2076 REQUIRE_PROMISE(proc);
2077 if (signum < 1 || signum >= 32)
2078 return -EINVAL;
2079 if (pgrp < 0)
2080 return -EINVAL;
2081
2082 return do_killpg(pgrp, signum);
2083}
2084
2085int Process::sys$setuid(uid_t uid)
2086{
2087 REQUIRE_PROMISE(id);
2088 if (uid != m_uid && !is_superuser())
2089 return -EPERM;
2090 m_uid = uid;
2091 m_euid = uid;
2092 return 0;
2093}
2094
2095int Process::sys$setgid(gid_t gid)
2096{
2097 REQUIRE_PROMISE(id);
2098 if (gid != m_gid && !is_superuser())
2099 return -EPERM;
2100 m_gid = gid;
2101 m_egid = gid;
2102 return 0;
2103}
2104
2105unsigned Process::sys$alarm(unsigned seconds)
2106{
2107 REQUIRE_PROMISE(stdio);
2108 unsigned previous_alarm_remaining = 0;
2109 if (m_alarm_deadline && m_alarm_deadline > g_uptime) {
2110 previous_alarm_remaining = (m_alarm_deadline - g_uptime) / TimeManagement::the().ticks_per_second();
2111 }
2112 if (!seconds) {
2113 m_alarm_deadline = 0;
2114 return previous_alarm_remaining;
2115 }
2116 m_alarm_deadline = g_uptime + seconds * TimeManagement::the().ticks_per_second();
2117 return previous_alarm_remaining;
2118}
2119
2120int Process::sys$uname(utsname* buf)
2121{
2122 REQUIRE_PROMISE(stdio);
2123 if (!validate_write_typed(buf))
2124 return -EFAULT;
2125 LOCKER(*s_hostname_lock);
2126 if (s_hostname->length() + 1 > sizeof(utsname::nodename))
2127 return -ENAMETOOLONG;
2128 copy_to_user(buf->sysname, "SerenityOS", 11);
2129 copy_to_user(buf->release, "1.0-dev", 8);
2130 copy_to_user(buf->version, "FIXME", 6);
2131 copy_to_user(buf->machine, "i686", 5);
2132 copy_to_user(buf->nodename, s_hostname->characters(), s_hostname->length() + 1);
2133 return 0;
2134}
2135
2136KResult Process::do_kill(Process& process, int signal)
2137{
2138 // FIXME: Allow sending SIGCONT to everyone in the process group.
2139 // FIXME: Should setuid processes have some special treatment here?
2140 if (!is_superuser() && m_euid != process.m_uid && m_uid != process.m_uid)
2141 return KResult(-EPERM);
2142 if (process.is_ring0() && signal == SIGKILL) {
2143 klog() << "attempted to send SIGKILL to ring 0 process " << process.name().characters() << "(" << process.pid() << ")";
2144 return KResult(-EPERM);
2145 }
2146 if (signal != 0)
2147 process.send_signal(signal, this);
2148 return KSuccess;
2149}
2150
2151KResult Process::do_killpg(pid_t pgrp, int signal)
2152{
2153 InterruptDisabler disabler;
2154
2155 ASSERT(pgrp >= 0);
2156
2157 // Send the signal to all processes in the given group.
2158 if (pgrp == 0) {
2159 // Send the signal to our own pgrp.
2160 pgrp = pgid();
2161 }
2162
2163 bool group_was_empty = true;
2164 bool any_succeeded = false;
2165 KResult error = KSuccess;
2166
2167 Process::for_each_in_pgrp(pgrp, [&](auto& process) {
2168 group_was_empty = false;
2169
2170 KResult res = do_kill(process, signal);
2171 if (res.is_success())
2172 any_succeeded = true;
2173 else
2174 error = res;
2175
2176 return IterationDecision::Continue;
2177 });
2178
2179 if (group_was_empty)
2180 return KResult(-ESRCH);
2181 if (any_succeeded)
2182 return KSuccess;
2183 return error;
2184}
2185
2186int Process::sys$kill(pid_t pid, int signal)
2187{
2188 if (pid == m_pid)
2189 REQUIRE_PROMISE(stdio);
2190 else
2191 REQUIRE_PROMISE(proc);
2192
2193 if (signal < 0 || signal >= 32)
2194 return -EINVAL;
2195 if (pid <= 0) {
2196 if (pid == INT32_MIN)
2197 return -EINVAL;
2198 return do_killpg(-pid, signal);
2199 }
2200 if (pid == -1) {
2201 // FIXME: Send to all processes.
2202 return -ENOTIMPL;
2203 }
2204 if (pid == m_pid) {
2205 if (signal == 0)
2206 return 0;
2207 if (!Thread::current->should_ignore_signal(signal)) {
2208 Thread::current->send_signal(signal, this);
2209 (void)Thread::current->block<Thread::SemiPermanentBlocker>(Thread::SemiPermanentBlocker::Reason::Signal);
2210 }
2211 return 0;
2212 }
2213 InterruptDisabler disabler;
2214 auto* peer = Process::from_pid(pid);
2215 if (!peer)
2216 return -ESRCH;
2217 return do_kill(*peer, signal);
2218}
2219
2220int Process::sys$usleep(useconds_t usec)
2221{
2222 REQUIRE_PROMISE(stdio);
2223 if (!usec)
2224 return 0;
2225 u64 wakeup_time = Thread::current->sleep(usec / 1000);
2226 if (wakeup_time > g_uptime)
2227 return -EINTR;
2228 return 0;
2229}
2230
2231int Process::sys$sleep(unsigned seconds)
2232{
2233 REQUIRE_PROMISE(stdio);
2234 if (!seconds)
2235 return 0;
2236 u64 wakeup_time = Thread::current->sleep(seconds * TimeManagement::the().ticks_per_second());
2237 if (wakeup_time > g_uptime) {
2238 u32 ticks_left_until_original_wakeup_time = wakeup_time - g_uptime;
2239 return ticks_left_until_original_wakeup_time / TimeManagement::the().ticks_per_second();
2240 }
2241 return 0;
2242}
2243
2244timeval kgettimeofday()
2245{
2246 return const_cast<const timeval&>(((KernelInfoPage*)s_info_page_address_for_kernel.as_ptr())->now);
2247}
2248
2249void kgettimeofday(timeval& tv)
2250{
2251 tv = kgettimeofday();
2252}
2253
2254int Process::sys$gettimeofday(timeval* tv)
2255{
2256 REQUIRE_PROMISE(stdio);
2257 if (!validate_write_typed(tv))
2258 return -EFAULT;
2259 *tv = kgettimeofday();
2260 return 0;
2261}
2262
2263uid_t Process::sys$getuid()
2264{
2265 REQUIRE_PROMISE(stdio);
2266 return m_uid;
2267}
2268
2269gid_t Process::sys$getgid()
2270{
2271 REQUIRE_PROMISE(stdio);
2272 return m_gid;
2273}
2274
2275uid_t Process::sys$geteuid()
2276{
2277 REQUIRE_PROMISE(stdio);
2278 return m_euid;
2279}
2280
2281gid_t Process::sys$getegid()
2282{
2283 REQUIRE_PROMISE(stdio);
2284 return m_egid;
2285}
2286
2287pid_t Process::sys$getpid()
2288{
2289 REQUIRE_PROMISE(stdio);
2290 return m_pid;
2291}
2292
2293pid_t Process::sys$getppid()
2294{
2295 REQUIRE_PROMISE(stdio);
2296 return m_ppid;
2297}
2298
2299mode_t Process::sys$umask(mode_t mask)
2300{
2301 REQUIRE_PROMISE(stdio);
2302 auto old_mask = m_umask;
2303 m_umask = mask & 0777;
2304 return old_mask;
2305}
2306
2307siginfo_t Process::reap(Process& process)
2308{
2309 siginfo_t siginfo;
2310 memset(&siginfo, 0, sizeof(siginfo));
2311 siginfo.si_signo = SIGCHLD;
2312 siginfo.si_pid = process.pid();
2313 siginfo.si_uid = process.uid();
2314
2315 if (process.m_termination_signal) {
2316 siginfo.si_status = process.m_termination_signal;
2317 siginfo.si_code = CLD_KILLED;
2318 } else {
2319 siginfo.si_status = process.m_termination_status;
2320 siginfo.si_code = CLD_EXITED;
2321 }
2322
2323 {
2324 InterruptDisabler disabler;
2325
2326 if (process.ppid()) {
2327 auto* parent = Process::from_pid(process.ppid());
2328 if (parent) {
2329 parent->m_ticks_in_user_for_dead_children += process.m_ticks_in_user + process.m_ticks_in_user_for_dead_children;
2330 parent->m_ticks_in_kernel_for_dead_children += process.m_ticks_in_kernel + process.m_ticks_in_kernel_for_dead_children;
2331 }
2332 }
2333
2334#ifdef PROCESS_DEBUG
2335 dbg() << "Reaping process " << process;
2336#endif
2337 ASSERT(process.is_dead());
2338 g_processes->remove(&process);
2339 }
2340 delete &process;
2341 return siginfo;
2342}
2343
2344KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
2345{
2346 if (idtype == P_PID) {
2347 InterruptDisabler disabler;
2348 if (idtype == P_PID && !Process::from_pid(id))
2349 return KResult(-ECHILD);
2350 }
2351
2352 if (options & WNOHANG) {
2353 // FIXME: Figure out what WNOHANG should do with stopped children.
2354 if (idtype == P_ALL) {
2355 InterruptDisabler disabler;
2356 siginfo_t siginfo;
2357 memset(&siginfo, 0, sizeof(siginfo));
2358 for_each_child([&siginfo](Process& process) {
2359 if (process.is_dead())
2360 siginfo = reap(process);
2361 return IterationDecision::Continue;
2362 });
2363 return siginfo;
2364 } else if (idtype == P_PID) {
2365 InterruptDisabler disabler;
2366 auto* waitee_process = Process::from_pid(id);
2367 if (!waitee_process)
2368 return KResult(-ECHILD);
2369 if (waitee_process->is_dead())
2370 return reap(*waitee_process);
2371 } else {
2372 // FIXME: Implement other PID specs.
2373 return KResult(-EINVAL);
2374 }
2375 }
2376
2377 pid_t waitee_pid;
2378
2379 // FIXME: WaitBlocker should support idtype/id specs directly.
2380 if (idtype == P_ALL) {
2381 waitee_pid = -1;
2382 } else if (idtype == P_PID) {
2383 waitee_pid = id;
2384 } else {
2385 // FIXME: Implement other PID specs.
2386 return KResult(-EINVAL);
2387 }
2388
2389 if (Thread::current->block<Thread::WaitBlocker>(options, waitee_pid) != Thread::BlockResult::WokeNormally)
2390 return KResult(-EINTR);
2391
2392 InterruptDisabler disabler;
2393
2394 // NOTE: If waitee was -1, m_waitee_pid will have been filled in by the scheduler.
2395 Process* waitee_process = Process::from_pid(waitee_pid);
2396 if (!waitee_process)
2397 return KResult(-ECHILD);
2398
2399 ASSERT(waitee_process);
2400 if (waitee_process->is_dead()) {
2401 return reap(*waitee_process);
2402 } else {
2403 auto* waitee_thread = Thread::from_tid(waitee_pid);
2404 if (!waitee_thread)
2405 return KResult(-ECHILD);
2406 ASSERT(waitee_thread->state() == Thread::State::Stopped);
2407 siginfo_t siginfo;
2408 memset(&siginfo, 0, sizeof(siginfo));
2409 siginfo.si_signo = SIGCHLD;
2410 siginfo.si_pid = waitee_process->pid();
2411 siginfo.si_uid = waitee_process->uid();
2412 siginfo.si_status = CLD_STOPPED;
2413 siginfo.si_code = waitee_thread->m_stop_signal;
2414 return siginfo;
2415 }
2416}
2417
2418pid_t Process::sys$waitid(const Syscall::SC_waitid_params* user_params)
2419{
2420 REQUIRE_PROMISE(stdio);
2421
2422 Syscall::SC_waitid_params params;
2423 if (!validate_read_and_copy_typed(¶ms, user_params))
2424 return -EFAULT;
2425
2426 if (!validate_write_typed(params.infop))
2427 return -EFAULT;
2428
2429#ifdef PROCESS_DEBUG
2430 dbg() << "sys$waitid(" << params.idtype << ", " << params.id << ", " << params.infop << ", " << params.options << ")";
2431#endif
2432
2433 auto siginfo_or_error = do_waitid(static_cast<idtype_t>(params.idtype), params.id, params.options);
2434 if (siginfo_or_error.is_error())
2435 return siginfo_or_error.error();
2436 // While we waited, the process lock was dropped. This gave other threads
2437 // the opportunity to mess with the memory. For example, it could free the
2438 // region, and map it to a region to which it has no write permissions.
2439 // Therefore, we need to re-validate the pointer.
2440 if (!validate_write_typed(params.infop))
2441 return -EFAULT;
2442
2443 copy_to_user(params.infop, &siginfo_or_error.value());
2444 return 0;
2445}
2446
2447bool Process::validate_read_from_kernel(VirtualAddress vaddr, size_t size) const
2448{
2449 if (vaddr.is_null())
2450 return false;
2451 return MM.validate_kernel_read(*this, vaddr, size);
2452}
2453
2454bool Process::validate_read(const void* address, size_t size) const
2455{
2456 if (!size)
2457 return false;
2458 return MM.validate_user_read(*this, VirtualAddress(address), size);
2459}
2460
2461bool Process::validate_write(void* address, size_t size) const
2462{
2463 if (!size)
2464 return false;
2465 return MM.validate_user_write(*this, VirtualAddress(address), size);
2466}
2467
2468pid_t Process::sys$getsid(pid_t pid)
2469{
2470 REQUIRE_PROMISE(stdio);
2471 if (pid == 0)
2472 return m_sid;
2473 InterruptDisabler disabler;
2474 auto* process = Process::from_pid(pid);
2475 if (!process)
2476 return -ESRCH;
2477 if (m_sid != process->m_sid)
2478 return -EPERM;
2479 return process->m_sid;
2480}
2481
2482pid_t Process::sys$setsid()
2483{
2484 REQUIRE_PROMISE(proc);
2485 InterruptDisabler disabler;
2486 bool found_process_with_same_pgid_as_my_pid = false;
2487 Process::for_each_in_pgrp(pid(), [&](auto&) {
2488 found_process_with_same_pgid_as_my_pid = true;
2489 return IterationDecision::Break;
2490 });
2491 if (found_process_with_same_pgid_as_my_pid)
2492 return -EPERM;
2493 m_sid = m_pid;
2494 m_pgid = m_pid;
2495 m_tty = nullptr;
2496 return m_sid;
2497}
2498
2499pid_t Process::sys$getpgid(pid_t pid)
2500{
2501 REQUIRE_PROMISE(stdio);
2502 if (pid == 0)
2503 return m_pgid;
2504 InterruptDisabler disabler; // FIXME: Use a ProcessHandle
2505 auto* process = Process::from_pid(pid);
2506 if (!process)
2507 return -ESRCH;
2508 return process->m_pgid;
2509}
2510
2511pid_t Process::sys$getpgrp()
2512{
2513 REQUIRE_PROMISE(stdio);
2514 return m_pgid;
2515}
2516
2517static pid_t get_sid_from_pgid(pid_t pgid)
2518{
2519 InterruptDisabler disabler;
2520 auto* group_leader = Process::from_pid(pgid);
2521 if (!group_leader)
2522 return -1;
2523 return group_leader->sid();
2524}
2525
2526int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
2527{
2528 REQUIRE_PROMISE(proc);
2529 InterruptDisabler disabler; // FIXME: Use a ProcessHandle
2530 pid_t pid = specified_pid ? specified_pid : m_pid;
2531 if (specified_pgid < 0) {
2532 // The value of the pgid argument is less than 0, or is not a value supported by the implementation.
2533 return -EINVAL;
2534 }
2535 auto* process = Process::from_pid(pid);
2536 if (!process)
2537 return -ESRCH;
2538 if (process != this && process->ppid() != m_pid) {
2539 // The value of the pid argument does not match the process ID
2540 // of the calling process or of a child process of the calling process.
2541 return -ESRCH;
2542 }
2543 if (process->pid() == process->sid()) {
2544 // The process indicated by the pid argument is a session leader.
2545 return -EPERM;
2546 }
2547 if (process->ppid() == m_pid && process->sid() != sid()) {
2548 // The value of the pid argument matches the process ID of a child
2549 // process of the calling process and the child process is not in
2550 // the same session as the calling process.
2551 return -EPERM;
2552 }
2553
2554 pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid;
2555 pid_t current_sid = get_sid_from_pgid(process->m_pgid);
2556 pid_t new_sid = get_sid_from_pgid(new_pgid);
2557 if (current_sid != new_sid) {
2558 // Can't move a process between sessions.
2559 return -EPERM;
2560 }
2561 // FIXME: There are more EPERM conditions to check for here..
2562 process->m_pgid = new_pgid;
2563 return 0;
2564}
2565
2566int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
2567{
2568 auto description = file_description(fd);
2569 if (!description)
2570 return -EBADF;
2571 SmapDisabler disabler;
2572 return description->file().ioctl(*description, request, arg);
2573}
2574
2575int Process::sys$getdtablesize()
2576{
2577 REQUIRE_PROMISE(stdio);
2578 return m_max_open_file_descriptors;
2579}
2580
2581int Process::sys$dup(int old_fd)
2582{
2583 REQUIRE_PROMISE(stdio);
2584 auto description = file_description(old_fd);
2585 if (!description)
2586 return -EBADF;
2587 int new_fd = alloc_fd();
2588 if (new_fd < 0)
2589 return new_fd;
2590 m_fds[new_fd].set(*description);
2591 return new_fd;
2592}
2593
2594int Process::sys$dup2(int old_fd, int new_fd)
2595{
2596 REQUIRE_PROMISE(stdio);
2597 auto description = file_description(old_fd);
2598 if (!description)
2599 return -EBADF;
2600 if (new_fd < 0 || new_fd >= m_max_open_file_descriptors)
2601 return -EINVAL;
2602 m_fds[new_fd].set(*description);
2603 return new_fd;
2604}
2605
2606int Process::sys$sigprocmask(int how, const sigset_t* set, sigset_t* old_set)
2607{
2608 REQUIRE_PROMISE(stdio);
2609 if (old_set) {
2610 if (!validate_write_typed(old_set))
2611 return -EFAULT;
2612 copy_to_user(old_set, &Thread::current->m_signal_mask);
2613 }
2614 if (set) {
2615 if (!validate_read_typed(set))
2616 return -EFAULT;
2617 sigset_t set_value;
2618 copy_from_user(&set_value, set);
2619 switch (how) {
2620 case SIG_BLOCK:
2621 Thread::current->m_signal_mask &= ~set_value;
2622 break;
2623 case SIG_UNBLOCK:
2624 Thread::current->m_signal_mask |= set_value;
2625 break;
2626 case SIG_SETMASK:
2627 Thread::current->m_signal_mask = set_value;
2628 break;
2629 default:
2630 return -EINVAL;
2631 }
2632 }
2633 return 0;
2634}
2635
2636int Process::sys$sigpending(sigset_t* set)
2637{
2638 REQUIRE_PROMISE(stdio);
2639 if (!validate_write_typed(set))
2640 return -EFAULT;
2641 copy_to_user(set, &Thread::current->m_pending_signals);
2642 return 0;
2643}
2644
2645int Process::sys$sigaction(int signum, const sigaction* act, sigaction* old_act)
2646{
2647 REQUIRE_PROMISE(stdio);
2648 if (signum < 1 || signum >= 32 || signum == SIGKILL || signum == SIGSTOP)
2649 return -EINVAL;
2650 if (!validate_read_typed(act))
2651 return -EFAULT;
2652 InterruptDisabler disabler; // FIXME: This should use a narrower lock. Maybe a way to ignore signals temporarily?
2653 auto& action = Thread::current->m_signal_action_data[signum];
2654 if (old_act) {
2655 if (!validate_write_typed(old_act))
2656 return -EFAULT;
2657 copy_to_user(&old_act->sa_flags, &action.flags);
2658 copy_to_user(&old_act->sa_sigaction, &action.handler_or_sigaction, sizeof(action.handler_or_sigaction));
2659 }
2660 copy_from_user(&action.flags, &act->sa_flags);
2661 copy_from_user(&action.handler_or_sigaction, &act->sa_sigaction, sizeof(action.handler_or_sigaction));
2662 return 0;
2663}
2664
2665int Process::sys$getgroups(ssize_t count, gid_t* user_gids)
2666{
2667 REQUIRE_PROMISE(stdio);
2668 if (count < 0)
2669 return -EINVAL;
2670 if (!count)
2671 return m_extra_gids.size();
2672 if (count != (int)m_extra_gids.size())
2673 return -EINVAL;
2674 if (!validate_write_typed(user_gids, m_extra_gids.size()))
2675 return -EFAULT;
2676
2677 Vector<gid_t> gids;
2678 for (auto gid : m_extra_gids)
2679 gids.append(gid);
2680
2681 copy_to_user(user_gids, gids.data(), sizeof(gid_t) * count);
2682 return 0;
2683}
2684
2685int Process::sys$setgroups(ssize_t count, const gid_t* user_gids)
2686{
2687 REQUIRE_PROMISE(id);
2688 if (count < 0)
2689 return -EINVAL;
2690 if (!is_superuser())
2691 return -EPERM;
2692 if (count && !validate_read(user_gids, count))
2693 return -EFAULT;
2694
2695 Vector<gid_t> gids;
2696 gids.resize(count);
2697 copy_from_user(gids.data(), user_gids, sizeof(gid_t) * count);
2698
2699 HashTable<gid_t> unique_extra_gids;
2700 for (auto& gid : gids) {
2701 if (gid != m_gid)
2702 unique_extra_gids.set(gid);
2703 }
2704
2705 m_extra_gids.resize(unique_extra_gids.size());
2706 size_t i = 0;
2707 for (auto& gid : unique_extra_gids) {
2708 if (gid == m_gid)
2709 continue;
2710 m_extra_gids[i++] = gid;
2711 }
2712 return 0;
2713}
2714
2715int Process::sys$mkdir(const char* user_path, size_t path_length, mode_t mode)
2716{
2717 REQUIRE_PROMISE(cpath);
2718 auto path = get_syscall_path_argument(user_path, path_length);
2719 if (path.is_error())
2720 return path.error();
2721 return VFS::the().mkdir(path.value(), mode & ~umask(), current_directory());
2722}
2723
2724int Process::sys$realpath(const Syscall::SC_realpath_params* user_params)
2725{
2726 REQUIRE_PROMISE(rpath);
2727
2728 Syscall::SC_realpath_params params;
2729 if (!validate_read_and_copy_typed(¶ms, user_params))
2730 return -EFAULT;
2731
2732 if (!validate_write(params.buffer.data, params.buffer.size))
2733 return -EFAULT;
2734
2735 auto path = get_syscall_path_argument(params.path);
2736 if (path.is_error())
2737 return path.error();
2738
2739 auto custody_or_error = VFS::the().resolve_path(path.value(), current_directory());
2740 if (custody_or_error.is_error())
2741 return custody_or_error.error();
2742 auto& custody = custody_or_error.value();
2743 auto absolute_path = custody->absolute_path();
2744
2745 if (absolute_path.length() + 1 > params.buffer.size)
2746 return -ENAMETOOLONG;
2747
2748 copy_to_user(params.buffer.data, absolute_path.characters(), absolute_path.length() + 1);
2749 return 0;
2750};
2751
2752clock_t Process::sys$times(tms* times)
2753{
2754 REQUIRE_PROMISE(stdio);
2755 if (!validate_write_typed(times))
2756 return -EFAULT;
2757 copy_to_user(×->tms_utime, &m_ticks_in_user);
2758 copy_to_user(×->tms_stime, &m_ticks_in_kernel);
2759 copy_to_user(×->tms_cutime, &m_ticks_in_user_for_dead_children);
2760 copy_to_user(×->tms_cstime, &m_ticks_in_kernel_for_dead_children);
2761 return g_uptime & 0x7fffffff;
2762}
2763
2764int Process::sys$select(const Syscall::SC_select_params* params)
2765{
2766 REQUIRE_PROMISE(stdio);
2767 // FIXME: Return -EINVAL if timeout is invalid.
2768 if (!validate_read_typed(params))
2769 return -EFAULT;
2770
2771 SmapDisabler disabler;
2772
2773 int nfds = params->nfds;
2774 fd_set* readfds = params->readfds;
2775 fd_set* writefds = params->writefds;
2776 fd_set* exceptfds = params->exceptfds;
2777 timeval* timeout = params->timeout;
2778
2779 if (writefds && !validate_write_typed(writefds))
2780 return -EFAULT;
2781 if (readfds && !validate_write_typed(readfds))
2782 return -EFAULT;
2783 if (exceptfds && !validate_write_typed(exceptfds))
2784 return -EFAULT;
2785 if (timeout && !validate_read_typed(timeout))
2786 return -EFAULT;
2787 if (nfds < 0)
2788 return -EINVAL;
2789
2790 timeval computed_timeout;
2791 bool select_has_timeout = false;
2792 if (timeout && (timeout->tv_sec || timeout->tv_usec)) {
2793 timeval_add(Scheduler::time_since_boot(), *timeout, computed_timeout);
2794 select_has_timeout = true;
2795 }
2796
2797 Thread::SelectBlocker::FDVector rfds;
2798 Thread::SelectBlocker::FDVector wfds;
2799 Thread::SelectBlocker::FDVector efds;
2800
2801 auto transfer_fds = [&](auto* fds, auto& vector) -> int {
2802 vector.clear_with_capacity();
2803 if (!fds)
2804 return 0;
2805 for (int fd = 0; fd < nfds; ++fd) {
2806 if (FD_ISSET(fd, fds)) {
2807 if (!file_description(fd)) {
2808 dbg() << "sys$select: Bad fd number " << fd;
2809 return -EBADF;
2810 }
2811 vector.append(fd);
2812 }
2813 }
2814 return 0;
2815 };
2816 if (int error = transfer_fds(writefds, wfds))
2817 return error;
2818 if (int error = transfer_fds(readfds, rfds))
2819 return error;
2820 if (int error = transfer_fds(exceptfds, efds))
2821 return error;
2822
2823#if defined(DEBUG_IO) || defined(DEBUG_POLL_SELECT)
2824 dbg() << "selecting on (read:" << rfds.size() << ", write:" << wfds.size() << "), timeout=" << timeout;
2825#endif
2826
2827 if (!timeout || select_has_timeout) {
2828 if (Thread::current->block<Thread::SelectBlocker>(computed_timeout, select_has_timeout, rfds, wfds, efds) != Thread::BlockResult::WokeNormally)
2829 return -EINTR;
2830 // While we blocked, the process lock was dropped. This gave other threads
2831 // the opportunity to mess with the memory. For example, it could free the
2832 // region, and map it to a region to which it has no write permissions.
2833 // Therefore, we need to re-validate all pointers.
2834 if (writefds && !validate_write_typed(writefds))
2835 return -EFAULT;
2836 if (readfds && !validate_write_typed(readfds))
2837 return -EFAULT;
2838 // See the fixme below.
2839 if (exceptfds && !validate_write_typed(exceptfds))
2840 return -EFAULT;
2841 }
2842
2843 int marked_fd_count = 0;
2844 auto mark_fds = [&](auto* fds, auto& vector, auto should_mark) {
2845 if (!fds)
2846 return;
2847 FD_ZERO(fds);
2848 for (int fd : vector) {
2849 if (auto description = file_description(fd); description && should_mark(*description)) {
2850 FD_SET(fd, fds);
2851 ++marked_fd_count;
2852 }
2853 }
2854 };
2855 mark_fds(readfds, rfds, [](auto& description) { return description.can_read(); });
2856 mark_fds(writefds, wfds, [](auto& description) { return description.can_write(); });
2857 // FIXME: We should also mark exceptfds as appropriate.
2858
2859 return marked_fd_count;
2860}
2861
2862int Process::sys$poll(pollfd* fds, int nfds, int timeout)
2863{
2864 REQUIRE_PROMISE(stdio);
2865 if (!validate_read_typed(fds))
2866 return -EFAULT;
2867
2868 SmapDisabler disabler;
2869
2870 Thread::SelectBlocker::FDVector rfds;
2871 Thread::SelectBlocker::FDVector wfds;
2872
2873 for (int i = 0; i < nfds; ++i) {
2874 if (fds[i].events & POLLIN)
2875 rfds.append(fds[i].fd);
2876 if (fds[i].events & POLLOUT)
2877 wfds.append(fds[i].fd);
2878 }
2879
2880 timeval actual_timeout;
2881 bool has_timeout = false;
2882 if (timeout >= 0) {
2883 // poll is in ms, we want s/us.
2884 struct timeval tvtimeout;
2885 tvtimeout.tv_sec = 0;
2886 while (timeout >= 1000) {
2887 tvtimeout.tv_sec += 1;
2888 timeout -= 1000;
2889 }
2890 tvtimeout.tv_usec = timeout * 1000;
2891 timeval_add(Scheduler::time_since_boot(), tvtimeout, actual_timeout);
2892 has_timeout = true;
2893 }
2894
2895#if defined(DEBUG_IO) || defined(DEBUG_POLL_SELECT)
2896 dbg() << "polling on (read:" << rfds.size() << ", write:" << wfds.size() << "), timeout=" << timeout;
2897#endif
2898
2899 if (has_timeout || timeout < 0) {
2900 if (Thread::current->block<Thread::SelectBlocker>(actual_timeout, has_timeout, rfds, wfds, Thread::SelectBlocker::FDVector()) != Thread::BlockResult::WokeNormally)
2901 return -EINTR;
2902 }
2903
2904 int fds_with_revents = 0;
2905
2906 for (int i = 0; i < nfds; ++i) {
2907 auto description = file_description(fds[i].fd);
2908 if (!description) {
2909 fds[i].revents = POLLNVAL;
2910 continue;
2911 }
2912 fds[i].revents = 0;
2913 if (fds[i].events & POLLIN && description->can_read())
2914 fds[i].revents |= POLLIN;
2915 if (fds[i].events & POLLOUT && description->can_write())
2916 fds[i].revents |= POLLOUT;
2917
2918 if (fds[i].revents)
2919 ++fds_with_revents;
2920 }
2921
2922 return fds_with_revents;
2923}
2924
2925Custody& Process::current_directory()
2926{
2927 if (!m_cwd)
2928 m_cwd = VFS::the().root_custody();
2929 return *m_cwd;
2930}
2931
2932int Process::sys$link(const Syscall::SC_link_params* user_params)
2933{
2934 REQUIRE_PROMISE(cpath);
2935 Syscall::SC_link_params params;
2936 if (!validate_read_and_copy_typed(¶ms, user_params))
2937 return -EFAULT;
2938 auto old_path = validate_and_copy_string_from_user(params.old_path);
2939 auto new_path = validate_and_copy_string_from_user(params.new_path);
2940 if (old_path.is_null() || new_path.is_null())
2941 return -EFAULT;
2942 return VFS::the().link(old_path, new_path, current_directory());
2943}
2944
2945int Process::sys$unlink(const char* user_path, size_t path_length)
2946{
2947 REQUIRE_PROMISE(cpath);
2948 if (!validate_read(user_path, path_length))
2949 return -EFAULT;
2950 auto path = get_syscall_path_argument(user_path, path_length);
2951 if (path.is_error())
2952 return path.error();
2953 return VFS::the().unlink(path.value(), current_directory());
2954}
2955
2956int Process::sys$symlink(const Syscall::SC_symlink_params* user_params)
2957{
2958 REQUIRE_PROMISE(cpath);
2959 Syscall::SC_symlink_params params;
2960 if (!validate_read_and_copy_typed(¶ms, user_params))
2961 return -EFAULT;
2962 auto target = get_syscall_path_argument(params.target);
2963 if (target.is_error())
2964 return target.error();
2965 auto linkpath = get_syscall_path_argument(params.linkpath);
2966 if (linkpath.is_error())
2967 return linkpath.error();
2968 return VFS::the().symlink(target.value(), linkpath.value(), current_directory());
2969}
2970
2971KResultOr<String> Process::get_syscall_path_argument(const char* user_path, size_t path_length) const
2972{
2973 if (path_length == 0)
2974 return KResult(-EINVAL);
2975 if (path_length > PATH_MAX)
2976 return KResult(-ENAMETOOLONG);
2977 if (!validate_read(user_path, path_length))
2978 return KResult(-EFAULT);
2979 return copy_string_from_user(user_path, path_length);
2980}
2981
2982KResultOr<String> Process::get_syscall_path_argument(const Syscall::StringArgument& path) const
2983{
2984 return get_syscall_path_argument(path.characters, path.length);
2985}
2986
2987int Process::sys$rmdir(const char* user_path, size_t path_length)
2988{
2989 REQUIRE_PROMISE(cpath);
2990 auto path = get_syscall_path_argument(user_path, path_length);
2991 if (path.is_error())
2992 return path.error();
2993 return VFS::the().rmdir(path.value(), current_directory());
2994}
2995
2996int Process::sys$chmod(const char* user_path, size_t path_length, mode_t mode)
2997{
2998 REQUIRE_PROMISE(fattr);
2999 auto path = get_syscall_path_argument(user_path, path_length);
3000 if (path.is_error())
3001 return path.error();
3002 return VFS::the().chmod(path.value(), mode, current_directory());
3003}
3004
3005int Process::sys$fchmod(int fd, mode_t mode)
3006{
3007 REQUIRE_PROMISE(fattr);
3008 auto description = file_description(fd);
3009 if (!description)
3010 return -EBADF;
3011 return description->chmod(mode);
3012}
3013
3014int Process::sys$fchown(int fd, uid_t uid, gid_t gid)
3015{
3016 REQUIRE_PROMISE(chown);
3017 auto description = file_description(fd);
3018 if (!description)
3019 return -EBADF;
3020 return description->chown(uid, gid);
3021}
3022
3023int Process::sys$chown(const Syscall::SC_chown_params* user_params)
3024{
3025 REQUIRE_PROMISE(chown);
3026 Syscall::SC_chown_params params;
3027 if (!validate_read_and_copy_typed(¶ms, user_params))
3028 return -EFAULT;
3029 auto path = get_syscall_path_argument(params.path);
3030 if (path.is_error())
3031 return path.error();
3032 return VFS::the().chown(path.value(), params.uid, params.gid, current_directory());
3033}
3034
3035void Process::finalize()
3036{
3037 ASSERT(Thread::current == g_finalizer);
3038#ifdef PROCESS_DEBUG
3039 dbg() << "Finalizing process " << *this;
3040#endif
3041
3042 if (m_perf_event_buffer) {
3043 auto description_or_error = VFS::the().open(String::format("perfcore.%d", m_pid), O_CREAT | O_EXCL, 0400, current_directory(), UidAndGid { m_uid, m_gid });
3044 if (!description_or_error.is_error()) {
3045 auto& description = description_or_error.value();
3046 auto json = m_perf_event_buffer->to_json(m_pid, m_executable ? m_executable->absolute_path() : "");
3047 description->write(json.data(), json.size());
3048 }
3049 }
3050
3051 m_fds.clear();
3052 m_tty = nullptr;
3053 m_executable = nullptr;
3054 m_cwd = nullptr;
3055 m_root_directory = nullptr;
3056 m_root_directory_relative_to_global_root = nullptr;
3057
3058 disown_all_shared_buffers();
3059 {
3060 InterruptDisabler disabler;
3061 if (auto* parent_thread = Thread::from_tid(m_ppid)) {
3062 if (parent_thread->m_signal_action_data[SIGCHLD].flags & SA_NOCLDWAIT) {
3063 // NOTE: If the parent doesn't care about this process, let it go.
3064 m_ppid = 0;
3065 } else {
3066 parent_thread->send_signal(SIGCHLD, this);
3067 }
3068 }
3069 }
3070
3071 m_regions.clear();
3072
3073 m_dead = true;
3074}
3075
3076void Process::die()
3077{
3078 // Let go of the TTY, otherwise a slave PTY may keep the master PTY from
3079 // getting an EOF when the last process using the slave PTY dies.
3080 // If the master PTY owner relies on an EOF to know when to wait() on a
3081 // slave owner, we have to allow the PTY pair to be torn down.
3082 m_tty = nullptr;
3083
3084 kill_all_threads();
3085}
3086
3087size_t Process::amount_dirty_private() const
3088{
3089 // FIXME: This gets a bit more complicated for Regions sharing the same underlying VMObject.
3090 // The main issue I'm thinking of is when the VMObject has physical pages that none of the Regions are mapping.
3091 // That's probably a situation that needs to be looked at in general.
3092 size_t amount = 0;
3093 for (auto& region : m_regions) {
3094 if (!region.is_shared())
3095 amount += region.amount_dirty();
3096 }
3097 return amount;
3098}
3099
3100size_t Process::amount_clean_inode() const
3101{
3102 HashTable<const InodeVMObject*> vmobjects;
3103 for (auto& region : m_regions) {
3104 if (region.vmobject().is_inode())
3105 vmobjects.set(&static_cast<const InodeVMObject&>(region.vmobject()));
3106 }
3107 size_t amount = 0;
3108 for (auto& vmobject : vmobjects)
3109 amount += vmobject->amount_clean();
3110 return amount;
3111}
3112
3113size_t Process::amount_virtual() const
3114{
3115 size_t amount = 0;
3116 for (auto& region : m_regions) {
3117 amount += region.size();
3118 }
3119 return amount;
3120}
3121
3122size_t Process::amount_resident() const
3123{
3124 // FIXME: This will double count if multiple regions use the same physical page.
3125 size_t amount = 0;
3126 for (auto& region : m_regions) {
3127 amount += region.amount_resident();
3128 }
3129 return amount;
3130}
3131
3132size_t Process::amount_shared() const
3133{
3134 // FIXME: This will double count if multiple regions use the same physical page.
3135 // FIXME: It doesn't work at the moment, since it relies on PhysicalPage ref counts,
3136 // and each PhysicalPage is only reffed by its VMObject. This needs to be refactored
3137 // so that every Region contributes +1 ref to each of its PhysicalPages.
3138 size_t amount = 0;
3139 for (auto& region : m_regions) {
3140 amount += region.amount_shared();
3141 }
3142 return amount;
3143}
3144
3145size_t Process::amount_purgeable_volatile() const
3146{
3147 size_t amount = 0;
3148 for (auto& region : m_regions) {
3149 if (region.vmobject().is_purgeable() && static_cast<const PurgeableVMObject&>(region.vmobject()).is_volatile())
3150 amount += region.amount_resident();
3151 }
3152 return amount;
3153}
3154
3155size_t Process::amount_purgeable_nonvolatile() const
3156{
3157 size_t amount = 0;
3158 for (auto& region : m_regions) {
3159 if (region.vmobject().is_purgeable() && !static_cast<const PurgeableVMObject&>(region.vmobject()).is_volatile())
3160 amount += region.amount_resident();
3161 }
3162 return amount;
3163}
3164
3165#define REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain) \
3166 do { \
3167 if (domain == AF_INET) \
3168 REQUIRE_PROMISE(inet); \
3169 else if (domain == AF_LOCAL) \
3170 REQUIRE_PROMISE(unix); \
3171 } while (0)
3172
3173int Process::sys$socket(int domain, int type, int protocol)
3174{
3175 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain);
3176
3177 if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser())
3178 return -EACCES;
3179 int fd = alloc_fd();
3180 if (fd < 0)
3181 return fd;
3182 auto result = Socket::create(domain, type, protocol);
3183 if (result.is_error())
3184 return result.error();
3185 auto description = FileDescription::create(*result.value());
3186 description->set_readable(true);
3187 description->set_writable(true);
3188 unsigned flags = 0;
3189 if (type & SOCK_CLOEXEC)
3190 flags |= FD_CLOEXEC;
3191 if (type & SOCK_NONBLOCK)
3192 description->set_blocking(false);
3193 m_fds[fd].set(move(description), flags);
3194 return fd;
3195}
3196
3197int Process::sys$bind(int sockfd, const sockaddr* address, socklen_t address_length)
3198{
3199 if (!validate_read(address, address_length))
3200 return -EFAULT;
3201 auto description = file_description(sockfd);
3202 if (!description)
3203 return -EBADF;
3204 if (!description->is_socket())
3205 return -ENOTSOCK;
3206 auto& socket = *description->socket();
3207 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
3208 return socket.bind(address, address_length);
3209}
3210
3211int Process::sys$listen(int sockfd, int backlog)
3212{
3213 if (backlog < 0)
3214 return -EINVAL;
3215 auto description = file_description(sockfd);
3216 if (!description)
3217 return -EBADF;
3218 if (!description->is_socket())
3219 return -ENOTSOCK;
3220 auto& socket = *description->socket();
3221 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
3222 if (socket.is_connected())
3223 return -EINVAL;
3224 return socket.listen(backlog);
3225}
3226
3227int Process::sys$accept(int accepting_socket_fd, sockaddr* user_address, socklen_t* user_address_size)
3228{
3229 REQUIRE_PROMISE(accept);
3230 if (!validate_write_typed(user_address_size))
3231 return -EFAULT;
3232 socklen_t address_size = 0;
3233 copy_from_user(&address_size, user_address_size);
3234 if (!validate_write(user_address, address_size))
3235 return -EFAULT;
3236 int accepted_socket_fd = alloc_fd();
3237 if (accepted_socket_fd < 0)
3238 return accepted_socket_fd;
3239 auto accepting_socket_description = file_description(accepting_socket_fd);
3240 if (!accepting_socket_description)
3241 return -EBADF;
3242 if (!accepting_socket_description->is_socket())
3243 return -ENOTSOCK;
3244 auto& socket = *accepting_socket_description->socket();
3245 if (!socket.can_accept()) {
3246 if (accepting_socket_description->is_blocking()) {
3247 if (Thread::current->block<Thread::AcceptBlocker>(*accepting_socket_description) != Thread::BlockResult::WokeNormally)
3248 return -EINTR;
3249 } else {
3250 return -EAGAIN;
3251 }
3252 }
3253 auto accepted_socket = socket.accept();
3254 ASSERT(accepted_socket);
3255
3256 u8 address_buffer[sizeof(sockaddr_un)];
3257 address_size = min(sizeof(sockaddr_un), static_cast<size_t>(address_size));
3258 accepted_socket->get_peer_address((sockaddr*)address_buffer, &address_size);
3259 copy_to_user(user_address, address_buffer, address_size);
3260 copy_to_user(user_address_size, &address_size);
3261
3262 auto accepted_socket_description = FileDescription::create(*accepted_socket);
3263 accepted_socket_description->set_readable(true);
3264 accepted_socket_description->set_writable(true);
3265 // NOTE: The accepted socket inherits fd flags from the accepting socket.
3266 // I'm not sure if this matches other systems but it makes sense to me.
3267 accepted_socket_description->set_blocking(accepting_socket_description->is_blocking());
3268 m_fds[accepted_socket_fd].set(move(accepted_socket_description), m_fds[accepting_socket_fd].flags);
3269
3270 // NOTE: Moving this state to Completed is what causes connect() to unblock on the client side.
3271 accepted_socket->set_setup_state(Socket::SetupState::Completed);
3272 return accepted_socket_fd;
3273}
3274
3275int Process::sys$connect(int sockfd, const sockaddr* user_address, socklen_t user_address_size)
3276{
3277 if (!validate_read(user_address, user_address_size))
3278 return -EFAULT;
3279 int fd = alloc_fd();
3280 if (fd < 0)
3281 return fd;
3282 auto description = file_description(sockfd);
3283 if (!description)
3284 return -EBADF;
3285 if (!description->is_socket())
3286 return -ENOTSOCK;
3287
3288 auto& socket = *description->socket();
3289 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
3290
3291 u8 address[sizeof(sockaddr_un)];
3292 size_t address_size = min(sizeof(address), static_cast<size_t>(user_address_size));
3293 copy_from_user(address, user_address, address_size);
3294
3295 return socket.connect(*description, (const sockaddr*)address, address_size, description->is_blocking() ? ShouldBlock::Yes : ShouldBlock::No);
3296}
3297
3298int Process::sys$shutdown(int sockfd, int how)
3299{
3300 REQUIRE_PROMISE(stdio);
3301 if (how & ~SHUT_RDWR)
3302 return -EINVAL;
3303 auto description = file_description(sockfd);
3304 if (!description)
3305 return -EBADF;
3306 if (!description->is_socket())
3307 return -ENOTSOCK;
3308
3309 auto& socket = *description->socket();
3310 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
3311 return socket.shutdown(how);
3312}
3313
3314ssize_t Process::sys$sendto(const Syscall::SC_sendto_params* user_params)
3315{
3316 REQUIRE_PROMISE(stdio);
3317 Syscall::SC_sendto_params params;
3318 if (!validate_read_and_copy_typed(¶ms, user_params))
3319 return -EFAULT;
3320
3321 int flags = params.flags;
3322 const sockaddr* addr = params.addr;
3323 socklen_t addr_length = params.addr_length;
3324
3325 if (!validate(params.data))
3326 return -EFAULT;
3327 if (addr && !validate_read(addr, addr_length))
3328 return -EFAULT;
3329 auto description = file_description(params.sockfd);
3330 if (!description)
3331 return -EBADF;
3332 if (!description->is_socket())
3333 return -ENOTSOCK;
3334 auto& socket = *description->socket();
3335 if (socket.is_shut_down_for_writing())
3336 return -EPIPE;
3337 SmapDisabler disabler;
3338 return socket.sendto(*description, params.data.data, params.data.size, flags, addr, addr_length);
3339}
3340
3341ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
3342{
3343 REQUIRE_PROMISE(stdio);
3344
3345 Syscall::SC_recvfrom_params params;
3346 if (!validate_read_and_copy_typed(¶ms, user_params))
3347 return -EFAULT;
3348
3349 int flags = params.flags;
3350 sockaddr* addr = params.addr;
3351 socklen_t* addr_length = params.addr_length;
3352
3353 SmapDisabler disabler;
3354 if (!validate(params.buffer))
3355 return -EFAULT;
3356 if (addr_length) {
3357 if (!validate_write_typed(addr_length))
3358 return -EFAULT;
3359 if (!validate_write(addr, *addr_length))
3360 return -EFAULT;
3361 } else if (addr) {
3362 return -EINVAL;
3363 }
3364 auto description = file_description(params.sockfd);
3365 if (!description)
3366 return -EBADF;
3367 if (!description->is_socket())
3368 return -ENOTSOCK;
3369 auto& socket = *description->socket();
3370
3371 if (socket.is_shut_down_for_reading())
3372 return 0;
3373
3374 bool original_blocking = description->is_blocking();
3375 if (flags & MSG_DONTWAIT)
3376 description->set_blocking(false);
3377
3378 auto nrecv = socket.recvfrom(*description, params.buffer.data, params.buffer.size, flags, addr, addr_length);
3379 if (flags & MSG_DONTWAIT)
3380 description->set_blocking(original_blocking);
3381
3382 return nrecv;
3383}
3384
3385template<bool sockname, typename Params>
3386int Process::get_sock_or_peer_name(const Params& params)
3387{
3388 socklen_t addrlen_value;
3389 if (!validate_read_and_copy_typed(&addrlen_value, params.addrlen))
3390 return -EFAULT;
3391
3392 if (addrlen_value <= 0)
3393 return -EINVAL;
3394
3395 if (!validate_write(params.addr, addrlen_value))
3396 return -EFAULT;
3397
3398 if (!validate_write_typed(params.addrlen))
3399 return -EFAULT;
3400
3401 auto description = file_description(params.sockfd);
3402 if (!description)
3403 return -EBADF;
3404
3405 if (!description->is_socket())
3406 return -ENOTSOCK;
3407
3408 auto& socket = *description->socket();
3409 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
3410
3411 u8 address_buffer[sizeof(sockaddr_un)];
3412 addrlen_value = min(sizeof(sockaddr_un), static_cast<size_t>(addrlen_value));
3413 if constexpr (sockname)
3414 socket.get_local_address((sockaddr*)address_buffer, &addrlen_value);
3415 else
3416 socket.get_peer_address((sockaddr*)address_buffer, &addrlen_value);
3417 copy_to_user(params.addr, address_buffer, addrlen_value);
3418 copy_to_user(params.addrlen, &addrlen_value);
3419 return 0;
3420}
3421
3422int Process::sys$getsockname(const Syscall::SC_getsockname_params* user_params)
3423{
3424 Syscall::SC_getsockname_params params;
3425 if (!validate_read_and_copy_typed(¶ms, user_params))
3426 return -EFAULT;
3427 return get_sock_or_peer_name<true>(params);
3428}
3429
3430int Process::sys$getpeername(const Syscall::SC_getpeername_params* user_params)
3431{
3432 Syscall::SC_getpeername_params params;
3433 if (!validate_read_and_copy_typed(¶ms, user_params))
3434 return -EFAULT;
3435 return get_sock_or_peer_name<false>(params);
3436}
3437
3438int Process::sys$sched_setparam(int tid, const struct sched_param* param)
3439{
3440 REQUIRE_PROMISE(proc);
3441 if (!validate_read_typed(param))
3442 return -EFAULT;
3443
3444 int desired_priority;
3445 copy_from_user(&desired_priority, ¶m->sched_priority);
3446
3447 InterruptDisabler disabler;
3448 auto* peer = Thread::current;
3449 if (tid != 0)
3450 peer = Thread::from_tid(tid);
3451
3452 if (!peer)
3453 return -ESRCH;
3454
3455 if (!is_superuser() && m_euid != peer->process().m_uid && m_uid != peer->process().m_uid)
3456 return -EPERM;
3457
3458 if (desired_priority < THREAD_PRIORITY_MIN || desired_priority > THREAD_PRIORITY_MAX)
3459 return -EINVAL;
3460
3461 peer->set_priority((u32)desired_priority);
3462 return 0;
3463}
3464
3465int Process::sys$sched_getparam(pid_t pid, struct sched_param* param)
3466{
3467 REQUIRE_PROMISE(proc);
3468 if (!validate_write_typed(param))
3469 return -EFAULT;
3470
3471 InterruptDisabler disabler;
3472 auto* peer = Thread::current;
3473 if (pid != 0)
3474 peer = Thread::from_tid(pid);
3475
3476 if (!peer)
3477 return -ESRCH;
3478
3479 if (!is_superuser() && m_euid != peer->process().m_uid && m_uid != peer->process().m_uid)
3480 return -EPERM;
3481
3482 int priority = peer->priority();
3483 copy_to_user(¶m->sched_priority, &priority);
3484 return 0;
3485}
3486
3487int Process::sys$getsockopt(const Syscall::SC_getsockopt_params* params)
3488{
3489 if (!validate_read_typed(params))
3490 return -EFAULT;
3491
3492 SmapDisabler disabler;
3493
3494 int sockfd = params->sockfd;
3495 int level = params->level;
3496 int option = params->option;
3497 void* value = params->value;
3498 socklen_t* value_size = params->value_size;
3499
3500 if (!validate_write_typed(value_size))
3501 return -EFAULT;
3502 if (!validate_write(value, *value_size))
3503 return -EFAULT;
3504 auto description = file_description(sockfd);
3505 if (!description)
3506 return -EBADF;
3507 if (!description->is_socket())
3508 return -ENOTSOCK;
3509 auto& socket = *description->socket();
3510
3511 if (has_promised(Pledge::accept) && socket.is_local() && level == SOL_SOCKET && option == SO_PEERCRED) {
3512 // We make an exception for SOL_SOCKET::SO_PEERCRED on local sockets if you've pledged "accept"
3513 } else {
3514 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
3515 }
3516 return socket.getsockopt(*description, level, option, value, value_size);
3517}
3518
3519int Process::sys$setsockopt(const Syscall::SC_setsockopt_params* params)
3520{
3521 if (!validate_read_typed(params))
3522 return -EFAULT;
3523
3524 SmapDisabler disabler;
3525
3526 int sockfd = params->sockfd;
3527 int level = params->level;
3528 int option = params->option;
3529 const void* value = params->value;
3530 socklen_t value_size = params->value_size;
3531
3532 if (!validate_read(value, value_size))
3533 return -EFAULT;
3534 auto description = file_description(sockfd);
3535 if (!description)
3536 return -EBADF;
3537 if (!description->is_socket())
3538 return -ENOTSOCK;
3539 auto& socket = *description->socket();
3540 REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
3541 return socket.setsockopt(level, option, value, value_size);
3542}
3543
3544void Process::disown_all_shared_buffers()
3545{
3546 LOCKER(shared_buffers().lock());
3547 Vector<SharedBuffer*, 32> buffers_to_disown;
3548 for (auto& it : shared_buffers().resource())
3549 buffers_to_disown.append(it.value.ptr());
3550 for (auto* shared_buffer : buffers_to_disown)
3551 shared_buffer->disown(m_pid);
3552}
3553
3554int Process::sys$shbuf_create(int size, void** buffer)
3555{
3556 REQUIRE_PROMISE(shared_buffer);
3557 if (!size || size < 0)
3558 return -EINVAL;
3559 size = PAGE_ROUND_UP(size);
3560 if (!validate_write_typed(buffer))
3561 return -EFAULT;
3562
3563 LOCKER(shared_buffers().lock());
3564 static int s_next_shbuf_id;
3565 int shbuf_id = ++s_next_shbuf_id;
3566 auto shared_buffer = make<SharedBuffer>(shbuf_id, size);
3567 shared_buffer->share_with(m_pid);
3568
3569 void* address = shared_buffer->ref_for_process_and_get_address(*this);
3570 copy_to_user(buffer, &address);
3571 ASSERT((int)shared_buffer->size() >= size);
3572#ifdef SHARED_BUFFER_DEBUG
3573 klog() << "Created shared buffer " << shbuf_id << " @ " << buffer << " (" << size << " bytes, vmobject is " << shared_buffer->size() << ")";
3574#endif
3575 shared_buffers().resource().set(shbuf_id, move(shared_buffer));
3576
3577 return shbuf_id;
3578}
3579
3580int Process::sys$shbuf_allow_pid(int shbuf_id, pid_t peer_pid)
3581{
3582 REQUIRE_PROMISE(shared_buffer);
3583 if (!peer_pid || peer_pid < 0 || peer_pid == m_pid)
3584 return -EINVAL;
3585 LOCKER(shared_buffers().lock());
3586 auto it = shared_buffers().resource().find(shbuf_id);
3587 if (it == shared_buffers().resource().end())
3588 return -EINVAL;
3589 auto& shared_buffer = *(*it).value;
3590 if (!shared_buffer.is_shared_with(m_pid))
3591 return -EPERM;
3592 {
3593 InterruptDisabler disabler;
3594 auto* peer = Process::from_pid(peer_pid);
3595 if (!peer)
3596 return -ESRCH;
3597 }
3598 shared_buffer.share_with(peer_pid);
3599 return 0;
3600}
3601
3602int Process::sys$shbuf_allow_all(int shbuf_id)
3603{
3604 REQUIRE_PROMISE(shared_buffer);
3605 LOCKER(shared_buffers().lock());
3606 auto it = shared_buffers().resource().find(shbuf_id);
3607 if (it == shared_buffers().resource().end())
3608 return -EINVAL;
3609 auto& shared_buffer = *(*it).value;
3610 if (!shared_buffer.is_shared_with(m_pid))
3611 return -EPERM;
3612 shared_buffer.share_globally();
3613 return 0;
3614}
3615
3616int Process::sys$shbuf_release(int shbuf_id)
3617{
3618 REQUIRE_PROMISE(shared_buffer);
3619 LOCKER(shared_buffers().lock());
3620 auto it = shared_buffers().resource().find(shbuf_id);
3621 if (it == shared_buffers().resource().end())
3622 return -EINVAL;
3623 auto& shared_buffer = *(*it).value;
3624 if (!shared_buffer.is_shared_with(m_pid))
3625 return -EPERM;
3626#ifdef SHARED_BUFFER_DEBUG
3627 klog() << "Releasing shared buffer " << shbuf_id << ", buffer count: " << shared_buffers().resource().size();
3628#endif
3629 shared_buffer.deref_for_process(*this);
3630 return 0;
3631}
3632
3633void* Process::sys$shbuf_get(int shbuf_id, size_t* user_size)
3634{
3635 REQUIRE_PROMISE(shared_buffer);
3636 if (user_size && !validate_write_typed(user_size))
3637 return (void*)-EFAULT;
3638 LOCKER(shared_buffers().lock());
3639 auto it = shared_buffers().resource().find(shbuf_id);
3640 if (it == shared_buffers().resource().end())
3641 return (void*)-EINVAL;
3642 auto& shared_buffer = *(*it).value;
3643 if (!shared_buffer.is_shared_with(m_pid))
3644 return (void*)-EPERM;
3645#ifdef SHARED_BUFFER_DEBUG
3646 klog() << "Retaining shared buffer " << shbuf_id << ", buffer count: " << shared_buffers().resource().size();
3647#endif
3648 if (user_size) {
3649 size_t size = shared_buffer.size();
3650 copy_to_user(user_size, &size);
3651 }
3652 return shared_buffer.ref_for_process_and_get_address(*this);
3653}
3654
3655int Process::sys$shbuf_seal(int shbuf_id)
3656{
3657 REQUIRE_PROMISE(shared_buffer);
3658 LOCKER(shared_buffers().lock());
3659 auto it = shared_buffers().resource().find(shbuf_id);
3660 if (it == shared_buffers().resource().end())
3661 return -EINVAL;
3662 auto& shared_buffer = *(*it).value;
3663 if (!shared_buffer.is_shared_with(m_pid))
3664 return -EPERM;
3665#ifdef SHARED_BUFFER_DEBUG
3666 klog() << "Sealing shared buffer " << shbuf_id;
3667#endif
3668 shared_buffer.seal();
3669 return 0;
3670}
3671
3672int Process::sys$shbuf_set_volatile(int shbuf_id, bool state)
3673{
3674 REQUIRE_PROMISE(shared_buffer);
3675 LOCKER(shared_buffers().lock());
3676 auto it = shared_buffers().resource().find(shbuf_id);
3677 if (it == shared_buffers().resource().end())
3678 return -EINVAL;
3679 auto& shared_buffer = *(*it).value;
3680 if (!shared_buffer.is_shared_with(m_pid))
3681 return -EPERM;
3682#ifdef SHARED_BUFFER_DEBUG
3683 klog() << "Set shared buffer " << shbuf_id << " volatile: " << state;
3684#endif
3685 if (!state) {
3686 bool was_purged = shared_buffer.vmobject().was_purged();
3687 shared_buffer.vmobject().set_volatile(state);
3688 shared_buffer.vmobject().set_was_purged(false);
3689 return was_purged ? 1 : 0;
3690 }
3691 shared_buffer.vmobject().set_volatile(true);
3692 return 0;
3693}
3694
3695void Process::terminate_due_to_signal(u8 signal)
3696{
3697 ASSERT_INTERRUPTS_DISABLED();
3698 ASSERT(signal < 32);
3699 dbg() << "Terminating due to signal " << signal;
3700 m_termination_status = 0;
3701 m_termination_signal = signal;
3702 die();
3703}
3704
3705void Process::send_signal(u8 signal, Process* sender)
3706{
3707 InterruptDisabler disabler;
3708 if (!m_thread_count)
3709 return;
3710 auto* thread = Thread::from_tid(m_pid);
3711 if (!thread)
3712 thread = &any_thread();
3713 thread->send_signal(signal, sender);
3714}
3715
3716int Process::sys$create_thread(void* (*entry)(void*), void* argument, const Syscall::SC_create_thread_params* user_params)
3717{
3718 REQUIRE_PROMISE(thread);
3719 if (!validate_read((const void*)entry, sizeof(void*)))
3720 return -EFAULT;
3721
3722 Syscall::SC_create_thread_params params;
3723 if (!validate_read_and_copy_typed(¶ms, user_params))
3724 return -EFAULT;
3725
3726 unsigned detach_state = params.m_detach_state;
3727 int schedule_priority = params.m_schedule_priority;
3728 void* stack_location = params.m_stack_location;
3729 unsigned stack_size = params.m_stack_size;
3730
3731 if (!validate_write(stack_location, stack_size))
3732 return -EFAULT;
3733
3734 u32 user_stack_address = reinterpret_cast<u32>(stack_location) + stack_size;
3735
3736 if (!MM.validate_user_stack(*this, VirtualAddress(user_stack_address - 4)))
3737 return -EFAULT;
3738
3739 // FIXME: return EAGAIN if Thread::all_threads().size() is greater than PTHREAD_THREADS_MAX
3740
3741 int requested_thread_priority = schedule_priority;
3742 if (requested_thread_priority < THREAD_PRIORITY_MIN || requested_thread_priority > THREAD_PRIORITY_MAX)
3743 return -EINVAL;
3744
3745 bool is_thread_joinable = (0 == detach_state);
3746
3747 // FIXME: Do something with guard pages?
3748
3749 auto* thread = new Thread(*this);
3750
3751 // We know this thread is not the main_thread,
3752 // So give it a unique name until the user calls $set_thread_name on it
3753 // length + 4 to give space for our extra junk at the end
3754 StringBuilder builder(m_name.length() + 4);
3755 builder.append(m_name);
3756 builder.appendf("[%d]", thread->tid());
3757 thread->set_name(builder.to_string());
3758
3759 thread->set_priority(requested_thread_priority);
3760 thread->set_joinable(is_thread_joinable);
3761
3762 auto& tss = thread->tss();
3763 tss.eip = (FlatPtr)entry;
3764 tss.eflags = 0x0202;
3765 tss.cr3 = page_directory().cr3();
3766 tss.esp = user_stack_address;
3767
3768 // NOTE: The stack needs to be 16-byte aligned.
3769 thread->push_value_on_stack((FlatPtr)argument);
3770 thread->push_value_on_stack(0);
3771
3772 thread->make_thread_specific_region({});
3773 thread->set_state(Thread::State::Runnable);
3774 return thread->tid();
3775}
3776
3777void Process::sys$exit_thread(void* exit_value)
3778{
3779 REQUIRE_PROMISE(thread);
3780 cli();
3781 Thread::current->m_exit_value = exit_value;
3782 Thread::current->set_should_die();
3783 big_lock().force_unlock_if_locked();
3784 Thread::current->die_if_needed();
3785 ASSERT_NOT_REACHED();
3786}
3787
3788int Process::sys$detach_thread(int tid)
3789{
3790 REQUIRE_PROMISE(thread);
3791 InterruptDisabler disabler;
3792 auto* thread = Thread::from_tid(tid);
3793 if (!thread || thread->pid() != pid())
3794 return -ESRCH;
3795
3796 if (!thread->is_joinable())
3797 return -EINVAL;
3798
3799 thread->set_joinable(false);
3800 return 0;
3801}
3802
3803int Process::sys$join_thread(int tid, void** exit_value)
3804{
3805 REQUIRE_PROMISE(thread);
3806 if (exit_value && !validate_write_typed(exit_value))
3807 return -EFAULT;
3808
3809 InterruptDisabler disabler;
3810 auto* thread = Thread::from_tid(tid);
3811 if (!thread || thread->pid() != pid())
3812 return -ESRCH;
3813
3814 if (thread == Thread::current)
3815 return -EDEADLK;
3816
3817 if (thread->m_joinee == Thread::current)
3818 return -EDEADLK;
3819
3820 ASSERT(thread->m_joiner != Thread::current);
3821 if (thread->m_joiner)
3822 return -EINVAL;
3823
3824 if (!thread->is_joinable())
3825 return -EINVAL;
3826
3827 void* joinee_exit_value = nullptr;
3828
3829 // NOTE: pthread_join() cannot be interrupted by signals. Only by death.
3830 for (;;) {
3831 auto result = Thread::current->block<Thread::JoinBlocker>(*thread, joinee_exit_value);
3832 if (result == Thread::BlockResult::InterruptedByDeath) {
3833 // NOTE: This cleans things up so that Thread::finalize() won't
3834 // get confused about a missing joiner when finalizing the joinee.
3835 InterruptDisabler disabler_t;
3836
3837 if (Thread::current->m_joinee) {
3838 Thread::current->m_joinee->m_joiner = nullptr;
3839 Thread::current->m_joinee = nullptr;
3840 }
3841
3842 break;
3843 }
3844 }
3845
3846 // NOTE: 'thread' is very possibly deleted at this point. Clear it just to be safe.
3847 thread = nullptr;
3848
3849 if (exit_value)
3850 copy_to_user(exit_value, &joinee_exit_value);
3851 return 0;
3852}
3853
3854int Process::sys$set_thread_name(int tid, const char* user_name, size_t user_name_length)
3855{
3856 REQUIRE_PROMISE(thread);
3857 auto name = validate_and_copy_string_from_user(user_name, user_name_length);
3858 if (name.is_null())
3859 return -EFAULT;
3860
3861 const size_t max_thread_name_size = 64;
3862 if (name.length() > max_thread_name_size)
3863 return -EINVAL;
3864
3865 InterruptDisabler disabler;
3866 auto* thread = Thread::from_tid(tid);
3867 if (!thread || thread->pid() != pid())
3868 return -ESRCH;
3869
3870 thread->set_name(name);
3871 return 0;
3872}
3873int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size)
3874{
3875 REQUIRE_PROMISE(thread);
3876 if (buffer_size == 0)
3877 return -EINVAL;
3878
3879 if (!validate_write(buffer, buffer_size))
3880 return -EFAULT;
3881
3882 InterruptDisabler disabler;
3883 auto* thread = Thread::from_tid(tid);
3884 if (!thread || thread->pid() != pid())
3885 return -ESRCH;
3886
3887 if (thread->name().length() + 1 > (size_t)buffer_size)
3888 return -ENAMETOOLONG;
3889
3890 copy_to_user(buffer, thread->name().characters(), thread->name().length() + 1);
3891 return 0;
3892}
3893
3894int Process::sys$gettid()
3895{
3896 REQUIRE_PROMISE(stdio);
3897 return Thread::current->tid();
3898}
3899
3900int Process::sys$donate(int tid)
3901{
3902 REQUIRE_PROMISE(stdio);
3903 if (tid < 0)
3904 return -EINVAL;
3905 InterruptDisabler disabler;
3906 auto* thread = Thread::from_tid(tid);
3907 if (!thread || thread->pid() != pid())
3908 return -ESRCH;
3909 Scheduler::donate_to(thread, "sys$donate");
3910 return 0;
3911}
3912
3913int Process::sys$rename(const Syscall::SC_rename_params* user_params)
3914{
3915 REQUIRE_PROMISE(cpath);
3916 Syscall::SC_rename_params params;
3917 if (!validate_read_and_copy_typed(¶ms, user_params))
3918 return -EFAULT;
3919 auto old_path = get_syscall_path_argument(params.old_path);
3920 if (old_path.is_error())
3921 return old_path.error();
3922 auto new_path = get_syscall_path_argument(params.new_path);
3923 if (new_path.is_error())
3924 return new_path.error();
3925 return VFS::the().rename(old_path.value(), new_path.value(), current_directory());
3926}
3927
3928int Process::sys$ftruncate(int fd, off_t length)
3929{
3930 REQUIRE_PROMISE(stdio);
3931 if (length < 0)
3932 return -EINVAL;
3933 auto description = file_description(fd);
3934 if (!description)
3935 return -EBADF;
3936 if (!description->is_writable())
3937 return -EBADF;
3938 return description->truncate(static_cast<u64>(length));
3939}
3940
3941int Process::sys$watch_file(const char* user_path, size_t path_length)
3942{
3943 REQUIRE_PROMISE(rpath);
3944 auto path = get_syscall_path_argument(user_path, path_length);
3945 if (path.is_error())
3946 return path.error();
3947
3948 auto custody_or_error = VFS::the().resolve_path(path.value(), current_directory());
3949 if (custody_or_error.is_error())
3950 return custody_or_error.error();
3951
3952 auto& custody = custody_or_error.value();
3953 auto& inode = custody->inode();
3954
3955 if (!inode.fs().supports_watchers())
3956 return -ENOTSUP;
3957
3958 int fd = alloc_fd();
3959 if (fd < 0)
3960 return fd;
3961
3962 m_fds[fd].set(FileDescription::create(*InodeWatcher::create(inode)));
3963 m_fds[fd].description->set_readable(true);
3964 return fd;
3965}
3966
3967int Process::sys$halt()
3968{
3969 if (!is_superuser())
3970 return -EPERM;
3971
3972 REQUIRE_NO_PROMISES;
3973
3974 dbg() << "acquiring FS locks...";
3975 FS::lock_all();
3976 dbg() << "syncing mounted filesystems...";
3977 FS::sync();
3978 dbg() << "attempting system shutdown...";
3979 IO::out16(0x604, 0x2000);
3980
3981 return ESUCCESS;
3982}
3983
3984int Process::sys$reboot()
3985{
3986 if (!is_superuser())
3987 return -EPERM;
3988
3989 REQUIRE_NO_PROMISES;
3990
3991 dbg() << "acquiring FS locks...";
3992 FS::lock_all();
3993 dbg() << "syncing mounted filesystems...";
3994 FS::sync();
3995 dbg() << "attempting reboot via ACPI";
3996 if (ACPI::is_enabled())
3997 ACPI::Parser::the()->try_acpi_reboot();
3998 dbg() << "attempting reboot via KB Controller...";
3999 IO::out8(0x64, 0xFE);
4000
4001 return ESUCCESS;
4002}
4003
4004int Process::sys$mount(const Syscall::SC_mount_params* user_params)
4005{
4006 if (!is_superuser())
4007 return -EPERM;
4008
4009 REQUIRE_NO_PROMISES;
4010
4011 Syscall::SC_mount_params params;
4012 if (!validate_read_and_copy_typed(¶ms, user_params))
4013 return -EFAULT;
4014
4015 auto source_fd = params.source_fd;
4016 auto target = validate_and_copy_string_from_user(params.target);
4017 auto fs_type = validate_and_copy_string_from_user(params.fs_type);
4018
4019 if (target.is_null() || fs_type.is_null())
4020 return -EFAULT;
4021
4022 auto description = file_description(source_fd);
4023 if (!description.is_null())
4024 dbg() << "mount " << fs_type << ": source fd " << source_fd << " @ " << target;
4025 else
4026 dbg() << "mount " << fs_type << " @ " << target;
4027
4028 auto custody_or_error = VFS::the().resolve_path(target, current_directory());
4029 if (custody_or_error.is_error())
4030 return custody_or_error.error();
4031
4032 auto& target_custody = custody_or_error.value();
4033
4034 RefPtr<FS> fs;
4035
4036 if (params.flags & MS_BIND) {
4037 // We're doing a bind mount.
4038 if (description.is_null())
4039 return -EBADF;
4040 ASSERT(description->custody());
4041 return VFS::the().bind_mount(*description->custody(), target_custody, params.flags);
4042 }
4043
4044 if (fs_type == "ext2" || fs_type == "Ext2FS") {
4045 if (description.is_null())
4046 return -EBADF;
4047 ASSERT(description->custody());
4048 if (!description->file().is_seekable()) {
4049 dbg() << "mount: this is not a seekable file";
4050 return -ENODEV;
4051 }
4052
4053 dbg() << "mount: attempting to mount " << description->absolute_path() << " on " << target;
4054
4055 fs = Ext2FS::create(*description);
4056 } else if (fs_type == "proc" || fs_type == "ProcFS") {
4057 fs = ProcFS::create();
4058 } else if (fs_type == "devpts" || fs_type == "DevPtsFS") {
4059 fs = DevPtsFS::create();
4060 } else if (fs_type == "tmp" || fs_type == "TmpFS") {
4061 fs = TmpFS::create();
4062 } else {
4063 return -ENODEV;
4064 }
4065
4066 if (!fs->initialize()) {
4067 dbg() << "mount: failed to initialize " << fs_type << " filesystem, fd - " << source_fd;
4068 return -ENODEV;
4069 }
4070
4071 auto result = VFS::the().mount(fs.release_nonnull(), target_custody, params.flags);
4072 if (!description.is_null())
4073 dbg() << "mount: successfully mounted " << description->absolute_path() << " on " << target;
4074 else
4075 dbg() << "mount: successfully mounted " << target;
4076 return result;
4077}
4078
4079int Process::sys$umount(const char* user_mountpoint, size_t mountpoint_length)
4080{
4081 if (!is_superuser())
4082 return -EPERM;
4083
4084 REQUIRE_NO_PROMISES;
4085
4086 if (!validate_read(user_mountpoint, mountpoint_length))
4087 return -EFAULT;
4088
4089 auto mountpoint = get_syscall_path_argument(user_mountpoint, mountpoint_length);
4090 if (mountpoint.is_error())
4091 return mountpoint.error();
4092
4093 auto metadata_or_error = VFS::the().lookup_metadata(mountpoint.value(), current_directory());
4094 if (metadata_or_error.is_error())
4095 return metadata_or_error.error();
4096
4097 auto guest_inode_id = metadata_or_error.value().inode;
4098 return VFS::the().unmount(guest_inode_id);
4099}
4100
4101void Process::FileDescriptionAndFlags::clear()
4102{
4103 description = nullptr;
4104 flags = 0;
4105}
4106
4107void Process::FileDescriptionAndFlags::set(NonnullRefPtr<FileDescription>&& d, u32 f)
4108{
4109 description = move(d);
4110 flags = f;
4111}
4112
4113int Process::sys$mknod(const Syscall::SC_mknod_params* user_params)
4114{
4115 REQUIRE_PROMISE(dpath);
4116 Syscall::SC_mknod_params params;
4117 if (!validate_read_and_copy_typed(¶ms, user_params))
4118 return -EFAULT;
4119 if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode))
4120 return -EPERM;
4121 auto path = get_syscall_path_argument(params.path);
4122 if (path.is_error())
4123 return path.error();
4124 return VFS::the().mknod(path.value(), params.mode & ~umask(), params.dev, current_directory());
4125}
4126
4127int Process::sys$dump_backtrace()
4128{
4129 dump_backtrace();
4130 return 0;
4131}
4132
4133int Process::sys$dbgputch(u8 ch)
4134{
4135 IO::out8(0xe9, ch);
4136 return 0;
4137}
4138
4139int Process::sys$dbgputstr(const u8* characters, int length)
4140{
4141 if (!length)
4142 return 0;
4143 if (!validate_read(characters, length))
4144 return -EFAULT;
4145 SmapDisabler disabler;
4146 for (int i = 0; i < length; ++i)
4147 IO::out8(0xe9, characters[i]);
4148 return 0;
4149}
4150
4151KBuffer Process::backtrace(ProcessInspectionHandle& handle) const
4152{
4153 KBufferBuilder builder;
4154 for_each_thread([&](Thread& thread) {
4155 builder.appendf("Thread %d (%s):\n", thread.tid(), thread.name().characters());
4156 builder.append(thread.backtrace(handle));
4157 return IterationDecision::Continue;
4158 });
4159 return builder.build();
4160}
4161
4162int Process::sys$set_process_icon(int icon_id)
4163{
4164 REQUIRE_PROMISE(shared_buffer);
4165 LOCKER(shared_buffers().lock());
4166 auto it = shared_buffers().resource().find(icon_id);
4167 if (it == shared_buffers().resource().end())
4168 return -EINVAL;
4169 auto& shared_buffer = *(*it).value;
4170 if (!shared_buffer.is_shared_with(m_pid))
4171 return -EPERM;
4172 m_icon_id = icon_id;
4173 return 0;
4174}
4175
4176int Process::sys$get_process_name(char* buffer, int buffer_size)
4177{
4178 REQUIRE_PROMISE(stdio);
4179 if (buffer_size <= 0)
4180 return -EINVAL;
4181
4182 if (!validate_write(buffer, buffer_size))
4183 return -EFAULT;
4184
4185 if (m_name.length() + 1 > (size_t)buffer_size)
4186 return -ENAMETOOLONG;
4187
4188 copy_to_user(buffer, m_name.characters(), m_name.length() + 1);
4189 return 0;
4190}
4191
4192// We don't use the flag yet, but we could use it for distinguishing
4193// random source like Linux, unlike the OpenBSD equivalent. However, if we
4194// do, we should be able of the caveats that Linux has dealt with.
4195int Process::sys$getrandom(void* buffer, size_t buffer_size, unsigned int flags __attribute__((unused)))
4196{
4197 REQUIRE_PROMISE(stdio);
4198 if (buffer_size <= 0)
4199 return -EINVAL;
4200
4201 if (!validate_write(buffer, buffer_size))
4202 return -EFAULT;
4203
4204 SmapDisabler disabler;
4205 get_good_random_bytes((u8*)buffer, buffer_size);
4206 return 0;
4207}
4208
4209int Process::sys$setkeymap(const Syscall::SC_setkeymap_params* user_params)
4210{
4211 if (!is_superuser())
4212 return -EPERM;
4213
4214 REQUIRE_NO_PROMISES;
4215 Syscall::SC_setkeymap_params params;
4216 if (!validate_read_and_copy_typed(¶ms, user_params))
4217 return -EFAULT;
4218
4219 const char* map = params.map;
4220 const char* shift_map = params.shift_map;
4221 const char* alt_map = params.alt_map;
4222 const char* altgr_map = params.altgr_map;
4223
4224 if (!validate_read(map, 0x80))
4225 return -EFAULT;
4226 if (!validate_read(shift_map, 0x80))
4227 return -EFAULT;
4228 if (!validate_read(alt_map, 0x80))
4229 return -EFAULT;
4230 if (!validate_read(altgr_map, 0x80))
4231 return -EFAULT;
4232
4233 SmapDisabler disabler;
4234 KeyboardDevice::the().set_maps(map, shift_map, alt_map, altgr_map);
4235 return 0;
4236}
4237
4238int Process::sys$clock_gettime(clockid_t clock_id, timespec* user_ts)
4239{
4240 REQUIRE_PROMISE(stdio);
4241 if (!validate_write_typed(user_ts))
4242 return -EFAULT;
4243
4244 timespec ts;
4245 memset(&ts, 0, sizeof(ts));
4246
4247 switch (clock_id) {
4248 case CLOCK_MONOTONIC:
4249 ts.tv_sec = TimeManagement::the().seconds_since_boot();
4250 ts.tv_nsec = TimeManagement::the().ticks_this_second() * 1000000;
4251 break;
4252 case CLOCK_REALTIME:
4253 ts.tv_sec = TimeManagement::the().epoch_time();
4254 ts.tv_nsec = TimeManagement::the().ticks_this_second() * 1000000;
4255 break;
4256 default:
4257 return -EINVAL;
4258 }
4259
4260 copy_to_user(user_ts, &ts);
4261 return 0;
4262}
4263
4264int Process::sys$clock_settime(clockid_t clock_id, timespec* user_ts)
4265{
4266 SmapDisabler disabler;
4267 REQUIRE_PROMISE(stdio);
4268 if (!validate_write_typed(user_ts))
4269 return -EFAULT;
4270
4271 switch (clock_id) {
4272 case CLOCK_REALTIME:
4273 TimeManagement::the().set_epoch_time(user_ts->tv_sec);
4274 break;
4275 default:
4276 return -EINVAL;
4277 }
4278 return 0;
4279}
4280
4281int Process::sys$clock_nanosleep(const Syscall::SC_clock_nanosleep_params* user_params)
4282{
4283 REQUIRE_PROMISE(stdio);
4284
4285 Syscall::SC_clock_nanosleep_params params;
4286 if (!validate_read_and_copy_typed(¶ms, user_params))
4287 return -EFAULT;
4288
4289 if (params.requested_sleep && !validate_read_typed(params.requested_sleep))
4290 return -EFAULT;
4291
4292 timespec requested_sleep;
4293 copy_from_user(&requested_sleep, params.requested_sleep);
4294
4295 if (params.remaining_sleep && !validate_write_typed(params.remaining_sleep))
4296 return -EFAULT;
4297
4298 bool is_absolute = params.flags & TIMER_ABSTIME;
4299
4300 switch (params.clock_id) {
4301 case CLOCK_MONOTONIC: {
4302 u64 wakeup_time;
4303 if (is_absolute) {
4304 u64 time_to_wake = (requested_sleep.tv_sec * 1000 + requested_sleep.tv_nsec / 1000000);
4305 wakeup_time = Thread::current->sleep_until(time_to_wake);
4306 } else {
4307 u32 ticks_to_sleep = (requested_sleep.tv_sec * 1000 + requested_sleep.tv_nsec / 1000000);
4308 if (!ticks_to_sleep)
4309 return 0;
4310 wakeup_time = Thread::current->sleep(ticks_to_sleep);
4311 }
4312 if (wakeup_time > g_uptime) {
4313 u32 ticks_left = wakeup_time - g_uptime;
4314 if (!is_absolute && params.remaining_sleep) {
4315 if (!validate_write_typed(params.remaining_sleep)) {
4316 // This can happen because the lock is dropped while
4317 // sleeping, thus giving other threads the opportunity
4318 // to make the region unwritable.
4319 return -EFAULT;
4320 }
4321
4322 timespec remaining_sleep;
4323 memset(&remaining_sleep, 0, sizeof(timespec));
4324 remaining_sleep.tv_sec = ticks_left / TimeManagement::the().ticks_per_second();
4325 ticks_left -= remaining_sleep.tv_sec * TimeManagement::the().ticks_per_second();
4326 remaining_sleep.tv_nsec = ticks_left * 1000000;
4327 copy_to_user(params.remaining_sleep, &remaining_sleep);
4328 }
4329 return -EINTR;
4330 }
4331 return 0;
4332 }
4333 default:
4334 return -EINVAL;
4335 }
4336}
4337
4338int Process::sys$sync()
4339{
4340 REQUIRE_PROMISE(stdio);
4341 VFS::the().sync();
4342 return 0;
4343}
4344
4345int Process::sys$yield()
4346{
4347 REQUIRE_PROMISE(stdio);
4348 Thread::current->yield_without_holding_big_lock();
4349 return 0;
4350}
4351
4352int Process::sys$beep()
4353{
4354 PCSpeaker::tone_on(440);
4355 u64 wakeup_time = Thread::current->sleep(100);
4356 PCSpeaker::tone_off();
4357 if (wakeup_time > g_uptime)
4358 return -EINTR;
4359 return 0;
4360}
4361
4362int Process::sys$module_load(const char* user_path, size_t path_length)
4363{
4364 if (!is_superuser())
4365 return -EPERM;
4366
4367 REQUIRE_NO_PROMISES;
4368
4369 auto path = get_syscall_path_argument(user_path, path_length);
4370 if (path.is_error())
4371 return path.error();
4372 auto description_or_error = VFS::the().open(path.value(), O_RDONLY, 0, current_directory());
4373 if (description_or_error.is_error())
4374 return description_or_error.error();
4375 auto& description = description_or_error.value();
4376 auto payload = description->read_entire_file();
4377 auto storage = KBuffer::create_with_size(payload.size());
4378 memcpy(storage.data(), payload.data(), payload.size());
4379 payload.clear();
4380
4381 auto elf_image = make<ELFImage>(storage.data(), storage.size());
4382 if (!elf_image->parse())
4383 return -ENOEXEC;
4384
4385 HashMap<String, u8*> section_storage_by_name;
4386
4387 auto module = make<Module>();
4388
4389 elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELFImage::Section& section) {
4390 auto section_storage = KBuffer::copy(section.raw_data(), section.size(), Region::Access::Read | Region::Access::Write | Region::Access::Execute);
4391 section_storage_by_name.set(section.name(), section_storage.data());
4392 module->sections.append(move(section_storage));
4393 return IterationDecision::Continue;
4394 });
4395
4396 bool missing_symbols = false;
4397
4398 elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELFImage::Section& section) {
4399 auto* section_storage = section_storage_by_name.get(section.name()).value_or(nullptr);
4400 ASSERT(section_storage);
4401 section.relocations().for_each_relocation([&](const ELFImage::Relocation& relocation) {
4402 auto& patch_ptr = *reinterpret_cast<ptrdiff_t*>(section_storage + relocation.offset());
4403 switch (relocation.type()) {
4404 case R_386_PC32: {
4405 // PC-relative relocation
4406 dbg() << "PC-relative relocation: " << relocation.symbol().name();
4407 u32 symbol_address = address_for_kernel_symbol(relocation.symbol().name());
4408 if (symbol_address == 0)
4409 missing_symbols = true;
4410 dbg() << " Symbol address: " << (void*)symbol_address;
4411 ptrdiff_t relative_offset = (char*)symbol_address - ((char*)&patch_ptr + 4);
4412 patch_ptr = relative_offset;
4413 break;
4414 }
4415 case R_386_32: // Absolute relocation
4416 dbg() << "Absolute relocation: '" << relocation.symbol().name() << "' value:" << relocation.symbol().value() << ", index:" << relocation.symbol_index();
4417
4418 if (relocation.symbol().bind() == STB_LOCAL) {
4419 auto* section_storage_containing_symbol = section_storage_by_name.get(relocation.symbol().section().name()).value_or(nullptr);
4420 ASSERT(section_storage_containing_symbol);
4421 u32 symbol_address = (ptrdiff_t)(section_storage_containing_symbol + relocation.symbol().value());
4422 if (symbol_address == 0)
4423 missing_symbols = true;
4424 dbg() << " Symbol address: " << (void*)symbol_address;
4425 patch_ptr += symbol_address;
4426 } else if (relocation.symbol().bind() == STB_GLOBAL) {
4427 u32 symbol_address = address_for_kernel_symbol(relocation.symbol().name());
4428 if (symbol_address == 0)
4429 missing_symbols = true;
4430 dbg() << " Symbol address: " << (void*)symbol_address;
4431 patch_ptr += symbol_address;
4432 } else {
4433 ASSERT_NOT_REACHED();
4434 }
4435 break;
4436 }
4437 return IterationDecision::Continue;
4438 });
4439
4440 return IterationDecision::Continue;
4441 });
4442
4443 if (missing_symbols)
4444 return -EINVAL;
4445
4446 auto* text_base = section_storage_by_name.get(".text").value_or(nullptr);
4447 if (!text_base) {
4448 dbg() << "No .text section found in module!";
4449 return -EINVAL;
4450 }
4451
4452 elf_image->for_each_symbol([&](const ELFImage::Symbol& symbol) {
4453 dbg() << " - " << symbol.type() << " '" << symbol.name() << "' @ " << (void*)symbol.value() << ", size=" << symbol.size();
4454 if (symbol.name() == "module_init") {
4455 module->module_init = (ModuleInitPtr)(text_base + symbol.value());
4456 } else if (symbol.name() == "module_fini") {
4457 module->module_fini = (ModuleFiniPtr)(text_base + symbol.value());
4458 } else if (symbol.name() == "module_name") {
4459 const u8* storage = section_storage_by_name.get(symbol.section().name()).value_or(nullptr);
4460 if (storage)
4461 module->name = String((const char*)(storage + symbol.value()));
4462 }
4463 return IterationDecision::Continue;
4464 });
4465
4466 if (!module->module_init)
4467 return -EINVAL;
4468
4469 if (g_modules->contains(module->name)) {
4470 dbg() << "a module with the name " << module->name << " is already loaded; please unload it first";
4471 return -EEXIST;
4472 }
4473
4474 module->module_init();
4475
4476 auto name = module->name;
4477 g_modules->set(name, move(module));
4478
4479 return 0;
4480}
4481
4482int Process::sys$module_unload(const char* user_name, size_t name_length)
4483{
4484 if (!is_superuser())
4485 return -EPERM;
4486
4487 REQUIRE_NO_PROMISES;
4488
4489 auto module_name = validate_and_copy_string_from_user(user_name, name_length);
4490 if (module_name.is_null())
4491 return -EFAULT;
4492
4493 auto it = g_modules->find(module_name);
4494 if (it == g_modules->end())
4495 return -ENOENT;
4496
4497 if (it->value->module_fini)
4498 it->value->module_fini();
4499
4500 g_modules->remove(it);
4501 return 0;
4502}
4503
4504int Process::sys$profiling_enable(pid_t pid)
4505{
4506 REQUIRE_NO_PROMISES;
4507 InterruptDisabler disabler;
4508 auto* process = Process::from_pid(pid);
4509 if (!process)
4510 return -ESRCH;
4511 if (process->is_dead())
4512 return -ESRCH;
4513 if (!is_superuser() && process->uid() != m_uid)
4514 return -EPERM;
4515 Profiling::start(*process);
4516 process->set_profiling(true);
4517 return 0;
4518}
4519
4520int Process::sys$profiling_disable(pid_t pid)
4521{
4522 InterruptDisabler disabler;
4523 auto* process = Process::from_pid(pid);
4524 if (!process)
4525 return -ESRCH;
4526 if (!is_superuser() && process->uid() != m_uid)
4527 return -EPERM;
4528 process->set_profiling(false);
4529 Profiling::stop();
4530 return 0;
4531}
4532
4533void* Process::sys$get_kernel_info_page()
4534{
4535 REQUIRE_PROMISE(stdio);
4536 return s_info_page_address_for_userspace.as_ptr();
4537}
4538
4539Thread& Process::any_thread()
4540{
4541 Thread* found_thread = nullptr;
4542 for_each_thread([&](auto& thread) {
4543 found_thread = &thread;
4544 return IterationDecision::Break;
4545 });
4546 ASSERT(found_thread);
4547 return *found_thread;
4548}
4549
4550WaitQueue& Process::futex_queue(i32* userspace_address)
4551{
4552 auto& queue = m_futex_queues.ensure((FlatPtr)userspace_address);
4553 if (!queue)
4554 queue = make<WaitQueue>();
4555 return *queue;
4556}
4557
4558int Process::sys$futex(const Syscall::SC_futex_params* user_params)
4559{
4560 REQUIRE_PROMISE(thread);
4561
4562 Syscall::SC_futex_params params;
4563 if (!validate_read_and_copy_typed(¶ms, user_params))
4564 return -EFAULT;
4565
4566 i32* userspace_address = params.userspace_address;
4567 int futex_op = params.futex_op;
4568 i32 value = params.val;
4569 const timespec* user_timeout = params.timeout;
4570
4571 if (!validate_read_typed(userspace_address))
4572 return -EFAULT;
4573
4574 if (user_timeout && !validate_read_typed(user_timeout))
4575 return -EFAULT;
4576
4577 timespec timeout { 0, 0 };
4578 if (user_timeout)
4579 copy_from_user(&timeout, user_timeout);
4580
4581 i32 user_value;
4582
4583 switch (futex_op) {
4584 case FUTEX_WAIT:
4585 copy_from_user(&user_value, userspace_address);
4586 if (user_value != value)
4587 return -EAGAIN;
4588 // FIXME: This is supposed to be interruptible by a signal, but right now WaitQueue cannot be interrupted.
4589 // FIXME: Support timeout!
4590 Thread::current->wait_on(futex_queue(userspace_address));
4591 break;
4592 case FUTEX_WAKE:
4593 if (value == 0)
4594 return 0;
4595 if (value == 1) {
4596 futex_queue(userspace_address).wake_one();
4597 } else {
4598 // FIXME: Wake exactly (value) waiters.
4599 futex_queue(userspace_address).wake_all();
4600 }
4601 break;
4602 }
4603
4604 return 0;
4605}
4606
4607int Process::sys$set_thread_boost(int tid, int amount)
4608{
4609 REQUIRE_PROMISE(proc);
4610 if (amount < 0 || amount > 20)
4611 return -EINVAL;
4612 InterruptDisabler disabler;
4613 auto* thread = Thread::from_tid(tid);
4614 if (!thread)
4615 return -ESRCH;
4616 if (thread->state() == Thread::State::Dead || thread->state() == Thread::State::Dying)
4617 return -ESRCH;
4618 if (!is_superuser() && thread->process().uid() != euid())
4619 return -EPERM;
4620 thread->set_priority_boost(amount);
4621 return 0;
4622}
4623
4624int Process::sys$set_process_boost(pid_t pid, int amount)
4625{
4626 REQUIRE_PROMISE(proc);
4627 if (amount < 0 || amount > 20)
4628 return -EINVAL;
4629 InterruptDisabler disabler;
4630 auto* process = Process::from_pid(pid);
4631 if (!process || process->is_dead())
4632 return -ESRCH;
4633 if (!is_superuser() && process->uid() != euid())
4634 return -EPERM;
4635 process->m_priority_boost = amount;
4636 return 0;
4637}
4638
4639int Process::sys$chroot(const char* user_path, size_t path_length, int mount_flags)
4640{
4641 if (!is_superuser())
4642 return -EPERM;
4643 REQUIRE_PROMISE(chroot);
4644 auto path = get_syscall_path_argument(user_path, path_length);
4645 if (path.is_error())
4646 return path.error();
4647 auto directory_or_error = VFS::the().open_directory(path.value(), current_directory());
4648 if (directory_or_error.is_error())
4649 return directory_or_error.error();
4650 auto directory = directory_or_error.value();
4651 m_root_directory_relative_to_global_root = directory;
4652 int chroot_mount_flags = mount_flags == -1 ? directory->mount_flags() : mount_flags;
4653 set_root_directory(Custody::create(nullptr, "", directory->inode(), chroot_mount_flags));
4654 return 0;
4655}
4656
4657Custody& Process::root_directory()
4658{
4659 if (!m_root_directory)
4660 m_root_directory = VFS::the().root_custody();
4661 return *m_root_directory;
4662}
4663
4664Custody& Process::root_directory_relative_to_global_root()
4665{
4666 if (!m_root_directory_relative_to_global_root)
4667 m_root_directory_relative_to_global_root = root_directory();
4668 return *m_root_directory_relative_to_global_root;
4669}
4670
4671void Process::set_root_directory(const Custody& root)
4672{
4673 m_root_directory = root;
4674}
4675
4676int Process::sys$pledge(const Syscall::SC_pledge_params* user_params)
4677{
4678 Syscall::SC_pledge_params params;
4679 if (!validate_read_and_copy_typed(¶ms, user_params))
4680 return -EFAULT;
4681
4682 if (params.promises.length > 1024 || params.execpromises.length > 1024)
4683 return -E2BIG;
4684
4685 String promises;
4686 if (params.promises.characters) {
4687 promises = validate_and_copy_string_from_user(params.promises);
4688 if (promises.is_null())
4689 return -EFAULT;
4690 }
4691
4692 String execpromises;
4693 if (params.execpromises.characters) {
4694 execpromises = validate_and_copy_string_from_user(params.execpromises);
4695 if (execpromises.is_null())
4696 return -EFAULT;
4697 }
4698
4699 auto parse_pledge = [&](auto& pledge_spec, u32& mask) {
4700 auto parts = pledge_spec.split_view(' ');
4701 for (auto& part : parts) {
4702#define __ENUMERATE_PLEDGE_PROMISE(x) \
4703 if (part == #x) { \
4704 mask |= (1u << (u32)Pledge::x); \
4705 continue; \
4706 }
4707 ENUMERATE_PLEDGE_PROMISES
4708#undef __ENUMERATE_PLEDGE_PROMISE
4709 if (part == "dns") {
4710 // "dns" is an alias for "unix" since DNS queries go via LookupServer
4711 mask |= (1u << (u32)Pledge::unix);
4712 continue;
4713 }
4714 return false;
4715 }
4716 return true;
4717 };
4718
4719 if (!promises.is_null()) {
4720 u32 new_promises = 0;
4721 if (!parse_pledge(promises, new_promises))
4722 return -EINVAL;
4723 if (m_promises && (!new_promises || new_promises & ~m_promises))
4724 return -EPERM;
4725 m_promises = new_promises;
4726 }
4727
4728 if (!execpromises.is_null()) {
4729 u32 new_execpromises = 0;
4730 if (!parse_pledge(execpromises, new_execpromises))
4731 return -EINVAL;
4732 if (m_execpromises && (!new_execpromises || new_execpromises & ~m_execpromises))
4733 return -EPERM;
4734 m_execpromises = new_execpromises;
4735 }
4736
4737 return 0;
4738}
4739
4740Region& Process::add_region(NonnullOwnPtr<Region> region)
4741{
4742 auto* ptr = region.ptr();
4743 m_regions.append(move(region));
4744 return *ptr;
4745}
4746
4747int Process::sys$unveil(const Syscall::SC_unveil_params* user_params)
4748{
4749 Syscall::SC_unveil_params params;
4750 if (!validate_read_and_copy_typed(¶ms, user_params))
4751 return -EFAULT;
4752
4753 if (!params.path.characters && !params.permissions.characters) {
4754 m_veil_state = VeilState::Locked;
4755 return 0;
4756 }
4757
4758 if (m_veil_state == VeilState::Locked)
4759 return -EPERM;
4760
4761 if (!params.path.characters || !params.permissions.characters)
4762 return -EINVAL;
4763
4764 if (params.permissions.length > 4)
4765 return -EINVAL;
4766
4767 auto path = get_syscall_path_argument(params.path);
4768 if (path.is_error())
4769 return path.error();
4770
4771 if (path.value().is_empty() || path.value().characters()[0] != '/')
4772 return -EINVAL;
4773
4774 auto custody_or_error = VFS::the().resolve_path_without_veil(path.value(), root_directory());
4775 if (custody_or_error.is_error())
4776 // FIXME Should this be EINVAL?
4777 return custody_or_error.error();
4778
4779 auto& custody = custody_or_error.value();
4780 auto new_unveiled_path = custody->absolute_path();
4781
4782 auto permissions = validate_and_copy_string_from_user(params.permissions);
4783 if (permissions.is_null())
4784 return -EFAULT;
4785
4786 unsigned new_permissions = 0;
4787 for (size_t i = 0; i < permissions.length(); ++i) {
4788 switch (permissions[i]) {
4789 case 'r':
4790 new_permissions |= UnveiledPath::Access::Read;
4791 break;
4792 case 'w':
4793 new_permissions |= UnveiledPath::Access::Write;
4794 break;
4795 case 'x':
4796 new_permissions |= UnveiledPath::Access::Execute;
4797 break;
4798 case 'c':
4799 new_permissions |= UnveiledPath::Access::CreateOrRemove;
4800 break;
4801 default:
4802 return -EINVAL;
4803 }
4804 }
4805
4806 for (size_t i = 0; i < m_unveiled_paths.size(); ++i) {
4807 auto& unveiled_path = m_unveiled_paths[i];
4808 if (unveiled_path.path == new_unveiled_path) {
4809 if (new_permissions & ~unveiled_path.permissions)
4810 return -EPERM;
4811 unveiled_path.permissions = new_permissions;
4812 return 0;
4813 }
4814 }
4815
4816 m_unveiled_paths.append({ new_unveiled_path, new_permissions });
4817 ASSERT(m_veil_state != VeilState::Locked);
4818 m_veil_state = VeilState::Dropped;
4819 return 0;
4820}
4821
4822int Process::sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2)
4823{
4824 if (!m_perf_event_buffer)
4825 m_perf_event_buffer = make<PerformanceEventBuffer>();
4826 return m_perf_event_buffer->append(type, arg1, arg2);
4827}
4828
4829void Process::set_tty(TTY* tty)
4830{
4831 m_tty = tty;
4832}
4833
4834OwnPtr<Process::ELFBundle> Process::elf_bundle() const
4835{
4836 if (!m_executable)
4837 return nullptr;
4838 auto bundle = make<ELFBundle>();
4839 ASSERT(m_executable->inode().shared_vmobject());
4840 auto& vmobject = *m_executable->inode().shared_vmobject();
4841 bundle->region = MM.allocate_kernel_region_with_vmobject(const_cast<SharedInodeVMObject&>(vmobject), vmobject.size(), "ELF bundle", Region::Access::Read);
4842 if (!bundle->region)
4843 return nullptr;
4844 bundle->elf_loader = make<ELFLoader>(bundle->region->vaddr().as_ptr(), bundle->region->size());
4845 return bundle;
4846}
4847
4848int Process::sys$get_stack_bounds(FlatPtr* user_stack_base, size_t* user_stack_size)
4849{
4850 if (!validate_write_typed(user_stack_base))
4851 return -EFAULT;
4852 if (!validate_write_typed(user_stack_size))
4853 return -EFAULT;
4854
4855 FlatPtr stack_pointer = Thread::current->get_register_dump_from_stack().userspace_esp;
4856 auto* stack_region = MM.region_from_vaddr(*this, VirtualAddress(stack_pointer));
4857 if (!stack_region) {
4858 ASSERT_NOT_REACHED();
4859 return -EINVAL;
4860 }
4861
4862 FlatPtr stack_base = stack_region->range().base().get();
4863 size_t stack_size = stack_region->size();
4864 copy_to_user(user_stack_base, &stack_base);
4865 copy_to_user(user_stack_size, &stack_size);
4866 return 0;
4867}
4868
4869int Process::sys$ptrace(const Syscall::SC_ptrace_params* user_params)
4870{
4871 REQUIRE_PROMISE(proc);
4872 Syscall::SC_ptrace_params params;
4873 if (!validate_read_and_copy_typed(¶ms, user_params))
4874 return -EFAULT;
4875
4876 if (params.request == PT_TRACE_ME) {
4877 if (Thread::current->tracer())
4878 return -EBUSY;
4879
4880 m_wait_for_tracer_at_next_execve = true;
4881 return 0;
4882 }
4883
4884 if (params.pid == m_pid)
4885 return -EINVAL;
4886
4887 InterruptDisabler disabler;
4888 auto* peer = Thread::from_tid(params.pid);
4889 if (!peer)
4890 return -ESRCH;
4891
4892 if (peer->process().uid() != m_euid)
4893 return -EACCES;
4894
4895 if (params.request == PT_ATTACH) {
4896 if (peer->tracer()) {
4897 return -EBUSY;
4898 }
4899 peer->start_tracing_from(m_pid);
4900 if (peer->state() != Thread::State::Stopped && !(peer->m_blocker && peer->m_blocker->is_reason_signal()))
4901 peer->send_signal(SIGSTOP, this);
4902 return 0;
4903 }
4904
4905 auto* tracer = peer->tracer();
4906
4907 if (!tracer)
4908 return -EPERM;
4909
4910 if (tracer->tracer_pid() != m_pid)
4911 return -EBUSY;
4912
4913 if (peer->m_state == Thread::State::Running)
4914 return -EBUSY;
4915
4916 switch (params.request) {
4917 case PT_CONTINUE:
4918 peer->send_signal(SIGCONT, this);
4919 break;
4920
4921 case PT_DETACH:
4922 peer->stop_tracing();
4923 peer->send_signal(SIGCONT, this);
4924 break;
4925
4926 case PT_SYSCALL:
4927 tracer->set_trace_syscalls(true);
4928 peer->send_signal(SIGCONT, this);
4929 break;
4930
4931 case PT_GETREGS: {
4932 if (!tracer->has_regs())
4933 return -EINVAL;
4934
4935 PtraceRegisters* regs = reinterpret_cast<PtraceRegisters*>(params.addr);
4936 if (!validate_write(regs, sizeof(PtraceRegisters)))
4937 return -EFAULT;
4938
4939 {
4940 SmapDisabler disabler;
4941 *regs = tracer->regs();
4942 }
4943 break;
4944 }
4945
4946 default:
4947 return -EINVAL;
4948 }
4949
4950 return 0;
4951}
4952
4953bool Process::has_tracee_thread(int tracer_pid) const
4954{
4955 bool has_tracee = false;
4956
4957 for_each_thread([&](Thread& t) {
4958 if (t.tracer() && t.tracer()->tracer_pid() == tracer_pid) {
4959 has_tracee = true;
4960 return IterationDecision::Break;
4961 }
4962 return IterationDecision::Continue;
4963 });
4964 return has_tracee;
4965}
4966
4967}