mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-26 07:22:06 +00:00 
			
		
		
		
	 204a091765
			
		
	
	
		204a091765
		
	
	
	
	
		
			
			For example, consider the following SecretString construction:
    String foo = "foo";
    auto ss = SecretString::take_ownership(foo.to_byte_buffer());
The ByteBuffer created by to_byte_buffer() will not contain the NUL
terminator. Therefore, the value returned by SecretString::characters
will not be NUL-terminated either.
Currently, the only use of SecretString is to pass its character data to
crypt(), which requires a NUL-terminated string. To ensure this cannot
result in a buffer overrun, make SecretString append a NUL terminator to
its buffer if there isn't one already.
		
	
			
		
			
				
	
	
		
			51 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
 | |
|  * Copyright (c) 2021, Mustafa Quraish <mustafa@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #include <AK/Memory.h>
 | |
| #include <LibCore/SecretString.h>
 | |
| 
 | |
| namespace Core {
 | |
| 
 | |
| SecretString SecretString::take_ownership(char*& cstring, size_t length)
 | |
| {
 | |
|     auto buffer = ByteBuffer::copy(cstring, length);
 | |
|     VERIFY(buffer.has_value());
 | |
| 
 | |
|     secure_zero(cstring, length);
 | |
|     free(cstring);
 | |
|     cstring = nullptr;
 | |
| 
 | |
|     return SecretString(buffer.release_value());
 | |
| }
 | |
| 
 | |
| SecretString SecretString::take_ownership(ByteBuffer&& buffer)
 | |
| {
 | |
|     return SecretString(move(buffer));
 | |
| }
 | |
| 
 | |
| SecretString::SecretString(ByteBuffer&& buffer)
 | |
|     : m_secure_buffer(move(buffer))
 | |
| {
 | |
|     // SecretString is currently only used to provide the character data to invocations to crypt(),
 | |
|     // which requires a NUL-terminated string. To ensure this operation avoids a buffer overrun,
 | |
|     // append a NUL terminator here if there isn't already one.
 | |
|     if (m_secure_buffer.is_empty() || (m_secure_buffer[m_secure_buffer.size() - 1] != 0)) {
 | |
|         u8 nul = '\0';
 | |
|         m_secure_buffer.append(&nul, 1);
 | |
|     }
 | |
| }
 | |
| 
 | |
| SecretString::~SecretString()
 | |
| {
 | |
|     // Note: We use secure_zero to avoid the zeroing from being optimized out by the compiler,
 | |
|     // which is possible if memset was to be used here.
 | |
|     if (!m_secure_buffer.is_empty()) {
 | |
|         secure_zero(m_secure_buffer.data(), m_secure_buffer.capacity());
 | |
|     }
 | |
| }
 | |
| 
 | |
| }
 |