Skip to content

Only one element in the array field "privileges" of TOKEN_PRIVILEGES is reachable #2375

@kappilini

Description

@kappilini

Which crate is this about?

windows

Crate version

"0.44.0"

Summary

The TOKEN_PRIVILEGES struct has an array field with size 1.

pub struct TOKEN_PRIVILEGES {
    pub PrivilegeCount: u32,
    pub Privileges: [LUID_AND_ATTRIBUTES;1]
}

For the C API the windows documentation says that one must allocate sufficient memory for the structure to take into account additional elements. But this is not possible in Rust. An array of size one remains with size one because it is constant.
So it is not possible to get more elements from the array than one even if the array contains more elements.

Toolchain version/configuration

No response

Reproducible example

use windows::core::{
    PCWSTR,
    PCSTR,
    PSTR
};

use windows::Win32::{
    Security::{ 
        GetTokenInformation, 
        TokenPrivileges, 
        Authorization::{
            LUID_AND_ATTRIBUTES,
            LookupPrivilegeNameA
        }
    },
    
    Foundation::{
        HANDLE,
        LUID
    },
    
    System::{
        Threading::{
            OpenProcessToken,
            GetCurrentProcess
        }
    }
};

fn show_privileges() {
    unsafe {
        let current_process = GetCurrentProcess();

        let mut token = HANDLE::default();

        OpenProcessToken(current_process, TOKEN_QUERY, &mut token as *mut HANDLE);

        let mut token_privileges : *mut TOKEN_PRIVILEGES = std::ptr::null_mut();
        let mut token_privileges_len = 0u32;

        // Call it first with 0 to get the buffer length
        GetTokenInformation(
             token, 
             TokenPrivileges, 
             None, 
             0, 
             &mut token_privileges_len as *mut u32
        );

        // Allocate memory for the buffer
        let mut token_privileges_vec = vec![0u8; token_privileges_len as usize];
        token_privileges = token_privileges_vec.as_mut_ptr() as *mut TOKEN_PRIVILEGES;

        GetTokenInformation(
             token, 
             TokenPrivileges, 
             Some(token_privileges as *mut std::ffi::c_void), 
             token_privileges_len,
             &mut token_privileges_len as *mut u32
        );

        let mut privilege_name_len = 0u32;

        LookupPrivilegeNameA(
             PCSTR::null(),
             &(*token_privileges).Privileges[0].Luid,
             PSTR::null(), 
             &mut privilege_name_len as *mut u32
        );

        // Allocate memory for the privilege name
        let mut privileges_str = String::with_capacity(privilege_name_len as usize);
        let privileges_name = PSTR::from_raw(privileges_str.as_mut_ptr());

        LookupPrivilegeNameA(
            PCSTR::null(), 
            &(*token_privileges).Privileges[0].Luid, 
            privileges_name, 
            &mut privilege_name_len as *mut u32
        );

        println!("{}", privileges_name.to_string().unwrap())
    };

    Ok(())
}

Crate manifest

[dependencies.windows]
version = "0.44.0"
features = [
    "Win32_Foundation",
    "Win32_Security",
    "Win32_Security_Authorization",
    "Win32_System_Threading"
]

Expected behavior

If the PrivilegeCount of TOKEN_PRIVILEGES is greater than one, it should be possible to get the element on the index greater than 0 from the privileges field and the privileges field should have enough memory for all elements which are counted by PrivilegeCount.

Actual behavior

If the PrivilegeCount of TOKEN_PRIVILEGES is greater than one, it is not possible to get the element with the index greater than 0 from the array field privileges because it is an constant array with size one.

Additional comments

"privileges" shoud be a vec or a pointer to a vec or somthing else with dynamic memory allocation at runtime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions