The following issues were found

Userland/Libraries/LibCore/DirIterator.cpp
3 issues
access - This usually indicates a security flaw. If an attacker can change anything along the path between the call to access() and the file's actual use (e.g., by moving files), the attacker can exploit the race condition
Security

Line: 91 Column: 13 CWE codes: 362/367!
Suggestion: Set up the correct permissions (e.g., using setuid()) and try to open the file directly

              String find_executable_in_path(String filename)
{
    if (filename.starts_with('/')) {
        if (access(filename.characters(), X_OK) == 0)
            return filename;

        return {};
    }


            

Reported by FlawFinder.

access - This usually indicates a security flaw. If an attacker can change anything along the path between the call to access() and the file's actual use (e.g., by moving files), the attacker can exploit the race condition
Security

Line: 100 Column: 13 CWE codes: 362/367!
Suggestion: Set up the correct permissions (e.g., using setuid()) and try to open the file directly

                  for (auto directory : String { getenv("PATH") }.split(':')) {
        auto fullpath = String::formatted("{}/{}", directory, filename);

        if (access(fullpath.characters(), X_OK) == 0)
            return fullpath;
    }

    return {};
}

            

Reported by FlawFinder.

getenv - Environment variables are untrustable input if they can be set by an attacker. They can have any content and length, and the same variable can be set more than once
Security

Line: 97 Column: 36 CWE codes: 807 20
Suggestion: Check environment variables carefully before using them

                      return {};
    }

    for (auto directory : String { getenv("PATH") }.split(':')) {
        auto fullpath = String::formatted("{}/{}", directory, filename);

        if (access(fullpath.characters(), X_OK) == 0)
            return fullpath;
    }

            

Reported by FlawFinder.

Kernel/Bus/VirtIO/VirtIOConsolePort.cpp
3 issues
open - Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents?
Security

Line: 159 Column: 62 CWE codes: 362

                  return String::formatted("hvc{}p{}", m_console.device_id(), m_port);
}

KResultOr<NonnullRefPtr<FileDescription>> VirtIOConsolePort::open(int options)
{
    if (!m_open)
        m_console.send_open_control_message(m_port, true);

    return File::open(options);

            

Reported by FlawFinder.

open - Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents?
Security

Line: 164 Column: 18 CWE codes: 362

                  if (!m_open)
        m_console.send_open_control_message(m_port, true);

    return File::open(options);
}

}

            

Reported by FlawFinder.

read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 90 Column: 38 CWE codes: 120 20

                  return m_receive_buffer->used_bytes() > 0;
}

KResultOr<size_t> VirtIOConsolePort::read(FileDescription& desc, u64, UserOrKernelBuffer& buffer, size_t size)
{
    if (!size)
        return 0;

    ScopedSpinLock ringbuffer_lock(m_receive_buffer->lock());

            

Reported by FlawFinder.

Kernel/FileSystem/Ext2FileSystem.cpp
3 issues
chmod - This accepts filename arguments; if an attacker can move those files, a race condition results.
Security

Line: 1733 Column: 22 CWE codes: 362
Suggestion: Use fchmod( ) instead

                  m_inode_cache.remove(index);
}

KResult Ext2FSInode::chmod(mode_t mode)
{
    MutexLocker locker(m_inode_lock);
    if (m_raw_inode.i_mode == mode)
        return KSuccess;
    m_raw_inode.i_mode = mode;

            

Reported by FlawFinder.

chown - This accepts filename arguments; if an attacker can move those files, a race condition results.
Security

Line: 1743 Column: 22 CWE codes: 362
Suggestion: Use fchown( ) instead

                  return KSuccess;
}

KResult Ext2FSInode::chown(uid_t uid, gid_t gid)
{
    MutexLocker locker(m_inode_lock);
    if (m_raw_inode.i_uid == uid && m_raw_inode.i_gid == gid)
        return KSuccess;
    m_raw_inode.i_uid = uid;

            

Reported by FlawFinder.

read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 1003 Column: 23 CWE codes: 120 20

                      VERIFY(offset == 0);
        if (max((size_t)(offset + count), (size_t)m_raw_inode.i_size) < max_inline_symlink_length) {
            dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_bytes(): Poking into i_block array for inline symlink '{}' ({} bytes)", identifier(), data.copy_into_string(count), count);
            if (!data.read(((u8*)m_raw_inode.i_block) + offset, (size_t)count))
                return EFAULT;
            if ((size_t)(offset + count) > (size_t)m_raw_inode.i_size)
                m_raw_inode.i_size = offset + count;
            set_metadata_dirty(true);
            return count;

            

Reported by FlawFinder.

Userland/Applications/Terminal/main.cpp
3 issues
execl - This causes a new program to execute and is difficult to use safely
Security

Line: 64 Column: 9 CWE codes: 78
Suggestion: try using a library call that implements the same functionality if available

                      // including the heap! So resort to low-level APIs
        char pid_str[32];
        snprintf(pid_str, sizeof(pid_str), "%d", pid);
        execl("/bin/utmpupdate", "/bin/utmpupdate", "-f", "Terminal", "-p", pid_str, (create ? "-c" : "-d"), tty, nullptr);
    } else {
    wait_again:
        int status = 0;
        if (waitpid(utmpupdate_pid, &status, 0) < 0) {
            int err = errno;

            

Reported by FlawFinder.

char - Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues
Security

Line: 62 Column: 9 CWE codes: 119 120
Suggestion: Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length

                      // Be careful here! Because fork() only clones one thread it's
        // possible that we deadlock on anything involving a mutex,
        // including the heap! So resort to low-level APIs
        char pid_str[32];
        snprintf(pid_str, sizeof(pid_str), "%d", pid);
        execl("/bin/utmpupdate", "/bin/utmpupdate", "-f", "Terminal", "-p", pid_str, (create ? "-c" : "-d"), tty, nullptr);
    } else {
    wait_again:
        int status = 0;

            

Reported by FlawFinder.

open - Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents?
Security

Line: 430 Column: 28 CWE codes: 362

              
    auto& help_menu = window->add_menu("&Help");
    help_menu.add_action(GUI::CommonActions::make_help_action([](auto&) {
        Desktop::Launcher::open(URL::create_with_file_protocol("/usr/share/man/man1/Terminal.md"), "/bin/Help");
    }));
    help_menu.add_action(GUI::CommonActions::make_about_action("Terminal", app_icon, window));

    window->on_close = [&]() {
        if (find_window)

            

Reported by FlawFinder.

Userland/Libraries/LibC/malloc.cpp
3 issues
char - Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues
Security

Line: 260 Column: 13 CWE codes: 119 120
Suggestion: Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length

                      if (block->m_size != good_size) {
            new (block) ChunkedBlock(good_size);
            ue_notify_chunk_size_changed(block, good_size);
            char buffer[64];
            snprintf(buffer, sizeof(buffer), "malloc: ChunkedBlock(%zu)", good_size);
            set_mmap_name(block, ChunkedBlock::block_size, buffer);
        }
        allocator->usable_blocks.append(*block);
    }

            

Reported by FlawFinder.

char - Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues
Security

Line: 292 Column: 9 CWE codes: 119 120
Suggestion: Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length

              
    if (!block) {
        g_malloc_stats.number_of_block_allocs++;
        char buffer[64];
        snprintf(buffer, sizeof(buffer), "malloc: ChunkedBlock(%zu)", good_size);
        block = (ChunkedBlock*)os_alloc(ChunkedBlock::block_size, buffer);
        new (block) ChunkedBlock(good_size);
        allocator->usable_blocks.append(*block);
        ++allocator->block_count;

            

Reported by FlawFinder.

memcpy - Does not check for buffer overflows when copying to destination
Security

Line: 485 Column: 9 CWE codes: 120
Suggestion: Make sure destination can always hold the source data

                  }
    auto* new_ptr = malloc(size);
    if (new_ptr) {
        memcpy(new_ptr, ptr, min(existing_allocation_size, size));
        free(ptr);
    }
    return new_ptr;
}


            

Reported by FlawFinder.

Kernel/FileSystem/DevFS.h
3 issues
chmod - This accepts filename arguments; if an attacker can move those files, a race condition results.
Security

Line: 64 Column: 21 CWE codes: 362
Suggestion: Use fchmod( ) instead

                  virtual KResultOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, uid_t, gid_t) override;
    virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
    virtual KResult remove_child(const StringView& name) override;
    virtual KResult chmod(mode_t) override;
    virtual KResult chown(uid_t, gid_t) override;
    virtual KResult truncate(u64) override;
};

class DevFSDeviceInode : public DevFSInode {

            

Reported by FlawFinder.

chown - This accepts filename arguments; if an attacker can move those files, a race condition results.
Security

Line: 65 Column: 21 CWE codes: 362
Suggestion: Use fchown( ) instead

                  virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
    virtual KResult remove_child(const StringView& name) override;
    virtual KResult chmod(mode_t) override;
    virtual KResult chown(uid_t, gid_t) override;
    virtual KResult truncate(u64) override;
};

class DevFSDeviceInode : public DevFSInode {
    friend class DevFS;

            

Reported by FlawFinder.

chown - This accepts filename arguments; if an attacker can move those files, a race condition results.
Security

Line: 83 Column: 21 CWE codes: 362
Suggestion: Use fchown( ) instead

                  virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
    virtual InodeMetadata metadata() const override;
    virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
    virtual KResult chown(uid_t, gid_t) override;

    NonnullRefPtr<Device> m_attached_device;
    NonnullOwnPtr<KString> m_name;

    uid_t m_uid { 0 };

            

Reported by FlawFinder.

Userland/Applications/Help/ManualSectionNode.cpp
3 issues
open - Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents?
Security

Line: 41 Column: 39 CWE codes: 362

                      m_children.append(make<ManualPageNode>(*this, move(page_name)));
}

void ManualSectionNode::set_open(bool open)
{
    if (m_open == open)
        return;
    m_open = open;
}

            

Reported by FlawFinder.

open - Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents?
Security

Line: 43 Column: 19 CWE codes: 362

              
void ManualSectionNode::set_open(bool open)
{
    if (m_open == open)
        return;
    m_open = open;
}

            

Reported by FlawFinder.

open - Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents?
Security

Line: 45 Column: 14 CWE codes: 362

              {
    if (m_open == open)
        return;
    m_open = open;
}

            

Reported by FlawFinder.

Userland/Libraries/LibC/grp.cpp
3 issues
fprintf - If format strings can be influenced by an attacker, they can be exploited
Security

Line: 189 Column: 24 CWE codes: 134
Suggestion: Use a constant for the format specification

              
    if (group->gr_mem) {
        for (size_t i = 0; group->gr_mem[i] != nullptr; i++) {
            nwritten = fprintf(stream, i == 0 ? "%s" : ",%s", group->gr_mem[i]);
            if (!nwritten || nwritten < 0) {
                errno = ferror(stream);
                return -1;
            }
        }

            

Reported by FlawFinder.

fopen - Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents?
Security

Line: 35 Column: 20 CWE codes: 362

                  if (s_stream) {
        rewind(s_stream);
    } else {
        s_stream = fopen("/etc/group", "r");
        if (!s_stream) {
            perror("open /etc/group");
        }
    }
}

            

Reported by FlawFinder.

char - Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues
Security

Line: 128 Column: 9 CWE codes: 119 120
Suggestion: Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length

                          return nullptr;
        }

        char buffer[1024];
        ++s_line_number;
        char* s = fgets(buffer, sizeof(buffer), s_stream);

        // Silently tolerate an empty line at the end.
        if ((!s || !s[0]) && feof(s_stream))

            

Reported by FlawFinder.

Kernel/Bus/VirtIO/VirtIO.cpp
3 issues
read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 130 Column: 40 CWE codes: 120 20

              
u8 VirtIODevice::config_read8(const Configuration& config, u32 offset)
{
    return mapping_for_bar(config.bar).read<u8>(config.offset + offset);
}

u16 VirtIODevice::config_read16(const Configuration& config, u32 offset)
{
    return mapping_for_bar(config.bar).read<u16>(config.offset + offset);

            

Reported by FlawFinder.

read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 135 Column: 40 CWE codes: 120 20

              
u16 VirtIODevice::config_read16(const Configuration& config, u32 offset)
{
    return mapping_for_bar(config.bar).read<u16>(config.offset + offset);
}

u32 VirtIODevice::config_read32(const Configuration& config, u32 offset)
{
    return mapping_for_bar(config.bar).read<u32>(config.offset + offset);

            

Reported by FlawFinder.

read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 140 Column: 40 CWE codes: 120 20

              
u32 VirtIODevice::config_read32(const Configuration& config, u32 offset)
{
    return mapping_for_bar(config.bar).read<u32>(config.offset + offset);
}

void VirtIODevice::config_write8(const Configuration& config, u32 offset, u8 value)
{
    mapping_for_bar(config.bar).write(config.offset + offset, value);

            

Reported by FlawFinder.

Kernel/DoubleBuffer.h
3 issues
read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 25 Column: 37 CWE codes: 120 20

                  {
        return write(UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>(data)), size);
    }
    [[nodiscard]] KResultOr<size_t> read(UserOrKernelBuffer&, size_t);
    [[nodiscard]] KResultOr<size_t> read(u8* data, size_t size)
    {
        auto buffer = UserOrKernelBuffer::for_kernel_buffer(data);
        return read(buffer, size);
    }

            

Reported by FlawFinder.

read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 26 Column: 37 CWE codes: 120 20

                      return write(UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>(data)), size);
    }
    [[nodiscard]] KResultOr<size_t> read(UserOrKernelBuffer&, size_t);
    [[nodiscard]] KResultOr<size_t> read(u8* data, size_t size)
    {
        auto buffer = UserOrKernelBuffer::for_kernel_buffer(data);
        return read(buffer, size);
    }
    [[nodiscard]] KResultOr<size_t> peek(UserOrKernelBuffer&, size_t);

            

Reported by FlawFinder.

read - Check buffer boundaries if used in a loop including recursive loops
Security

Line: 29 Column: 16 CWE codes: 120 20

                  [[nodiscard]] KResultOr<size_t> read(u8* data, size_t size)
    {
        auto buffer = UserOrKernelBuffer::for_kernel_buffer(data);
        return read(buffer, size);
    }
    [[nodiscard]] KResultOr<size_t> peek(UserOrKernelBuffer&, size_t);
    [[nodiscard]] KResultOr<size_t> peek(u8* data, size_t size)
    {
        auto buffer = UserOrKernelBuffer::for_kernel_buffer(data);

            

Reported by FlawFinder.