2020-12-18 17:58:56 +13:00
/*
Fuzz sddl decoding and encoding
Copyright ( C ) Catalyst IT 2023
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "libcli/security/security.h"
2023-09-21 15:03:23 +12:00
# include "librpc/gen_ndr/conditional_ace.h"
2020-12-18 17:58:56 +13:00
# include "fuzzing/fuzzing.h"
2023-09-22 15:19:32 +12:00
# include "util/charset/charset.h"
2020-12-18 17:58:56 +13:00
# define MAX_LENGTH (100 * 1024 - 1)
static char sddl_string [ MAX_LENGTH + 1 ] = { 0 } ;
static struct dom_sid dom_sid = { 0 } ;
int LLVMFuzzerInitialize ( int * argc , char * * * argv )
{
string_to_sid ( & dom_sid ,
" S-1-5-21-2470180966-3899876309-2637894779 " ) ;
return 0 ;
}
2023-08-05 14:30:24 +12:00
int LLVMFuzzerTestOneInput ( const uint8_t * input , size_t len )
2020-12-18 17:58:56 +13:00
{
TALLOC_CTX * mem_ctx = NULL ;
struct security_descriptor * sd1 = NULL ;
struct security_descriptor * sd2 = NULL ;
char * result = NULL ;
bool ok ;
if ( len > MAX_LENGTH ) {
return 0 ;
}
memcpy ( sddl_string , input , len ) ;
sddl_string [ len ] = ' \0 ' ;
mem_ctx = talloc_new ( NULL ) ;
sd1 = sddl_decode ( mem_ctx , sddl_string , & dom_sid ) ;
if ( sd1 = = NULL ) {
goto end ;
}
result = sddl_encode ( mem_ctx , sd1 , & dom_sid ) ;
2023-09-22 15:19:32 +12:00
if ( result = = NULL ) {
/*
* Because Samba currently doesn ' t enforce strict
* utf - 8 parsing , illegal utf - 8 sequences in
* sddl_string could have ferried bad characters
* through into the security descriptor conditions
* that we then find we can ' t encode .
*
* The proper solution is strict UTF - 8 enforcement in
* sddl_decode , but for now we forgive unencodable
* security descriptors made from bad utf - 8.
*/
size_t byte_len , char_len , utf16_len ;
ok = utf8_check ( sddl_string , len ,
& byte_len , & char_len , & utf16_len ) ;
if ( ! ok ) {
goto end ;
}
/* utf-8 was fine, but we couldn't encode! */
abort ( ) ;
}
2020-12-18 17:58:56 +13:00
sd2 = sddl_decode ( mem_ctx , result , & dom_sid ) ;
2023-09-21 15:03:23 +12:00
if ( sd2 = = NULL ) {
if ( strlen ( result ) > CONDITIONAL_ACE_MAX_LENGTH ) {
/*
* This could fail if a unicode string or
* attribute name that contains escapable
* bytes ( e . g ' \x0b ' ) in an unescaped form in
* the original string ends up with them in
* the escaped form ( " %000b " ) in the result
* string , making the entire attribute name
* too long for the arbitrary limit we set for
* SDDL attribute names .
*
* We could increase that arbitrary limit ( to ,
* say , CONDITIONAL_ACE_MAX_LENGTH * 5 ) , but
* that is getting very far from real world
* needs .
*/
goto end ;
}
abort ( ) ;
}
2020-12-18 17:58:56 +13:00
ok = security_descriptor_equal ( sd1 , sd2 ) ;
if ( ! ok ) {
abort ( ) ;
}
end :
talloc_free ( mem_ctx ) ;
return 0 ;
}