2011-10-07 23:06:39 +04:00
/***
This file is part of systemd .
Copyright 2011 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2011-10-07 23:06:39 +04:00
( at your option ) any later version .
systemd 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
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2011-10-07 23:06:39 +04:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2011-10-07 23:06:39 +04:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <string.h>
2015-10-24 23:58:24 +03:00
# include "sd-daemon.h"
# include "sd-id128.h"
2012-01-05 19:01:58 +04:00
2015-10-27 05:01:06 +03:00
# include "alloc-util.h"
2016-07-25 21:50:24 +03:00
# include "fd-util.h"
# include "fileio.h"
# include "id128-util.h"
2011-10-07 23:06:39 +04:00
# include "macro.h"
2015-10-24 23:58:24 +03:00
# include "string-util.h"
# include "util.h"
2011-10-07 23:06:39 +04:00
# define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10)
2013-04-30 01:39:12 +04:00
# define STR_WALDI "0102030405060708090a0b0c0d0e0f10"
# define UUID_WALDI "01020304-0506-0708-090a-0b0c0d0e0f10"
2011-10-07 23:06:39 +04:00
int main ( int argc , char * argv [ ] ) {
sd_id128_t id , id2 ;
2016-07-21 18:57:57 +03:00
char t [ 33 ] , q [ 37 ] ;
2013-04-30 01:39:12 +04:00
_cleanup_free_ char * b = NULL ;
2016-07-25 21:50:24 +03:00
_cleanup_close_ int fd = - 1 ;
2011-10-07 23:06:39 +04:00
assert_se ( sd_id128_randomize ( & id ) = = 0 ) ;
printf ( " random: %s \n " , sd_id128_to_string ( id , t ) ) ;
assert_se ( sd_id128_from_string ( t , & id2 ) = = 0 ) ;
assert_se ( sd_id128_equal ( id , id2 ) ) ;
2013-07-18 10:30:06 +04:00
if ( sd_booted ( ) > 0 ) {
assert_se ( sd_id128_get_machine ( & id ) = = 0 ) ;
printf ( " machine: %s \n " , sd_id128_to_string ( id , t ) ) ;
2011-10-07 23:06:39 +04:00
2013-07-18 10:30:06 +04:00
assert_se ( sd_id128_get_boot ( & id ) = = 0 ) ;
printf ( " boot: %s \n " , sd_id128_to_string ( id , t ) ) ;
}
2011-10-07 23:06:39 +04:00
printf ( " waldi: %s \n " , sd_id128_to_string ( ID128_WALDI , t ) ) ;
2013-04-30 01:39:12 +04:00
assert_se ( streq ( t , STR_WALDI ) ) ;
assert_se ( asprintf ( & b , SD_ID128_FORMAT_STR , SD_ID128_FORMAT_VAL ( ID128_WALDI ) ) = = 32 ) ;
printf ( " waldi2: %s \n " , b ) ;
assert_se ( streq ( t , b ) ) ;
2016-07-21 18:57:57 +03:00
printf ( " waldi3: %s \n " , id128_to_uuid_string ( ID128_WALDI , q ) ) ;
assert_se ( streq ( q , UUID_WALDI ) ) ;
b = mfree ( b ) ;
assert_se ( asprintf ( & b , ID128_UUID_FORMAT_STR , SD_ID128_FORMAT_VAL ( ID128_WALDI ) ) = = 36 ) ;
printf ( " waldi4: %s \n " , b ) ;
assert_se ( streq ( q , b ) ) ;
assert_se ( sd_id128_from_string ( STR_WALDI , & id ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , ID128_WALDI ) ) ;
2013-04-30 01:39:12 +04:00
assert_se ( sd_id128_from_string ( UUID_WALDI , & id ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , ID128_WALDI ) ) ;
assert_se ( sd_id128_from_string ( " " , & id ) < 0 ) ;
assert_se ( sd_id128_from_string ( " 01020304-0506-0708-090a-0b0c0d0e0f101 " , & id ) < 0 ) ;
assert_se ( sd_id128_from_string ( " 01020304-0506-0708-090a-0b0c0d0e0f10- " , & id ) < 0 ) ;
assert_se ( sd_id128_from_string ( " 01020304-0506-0708-090a0b0c0d0e0f10 " , & id ) < 0 ) ;
assert_se ( sd_id128_from_string ( " 010203040506-0708-090a-0b0c0d0e0f10 " , & id ) < 0 ) ;
assert_se ( id128_is_valid ( STR_WALDI ) ) ;
assert_se ( id128_is_valid ( UUID_WALDI ) ) ;
assert_se ( ! id128_is_valid ( " " ) ) ;
assert_se ( ! id128_is_valid ( " 01020304-0506-0708-090a-0b0c0d0e0f101 " ) ) ;
assert_se ( ! id128_is_valid ( " 01020304-0506-0708-090a-0b0c0d0e0f10- " ) ) ;
assert_se ( ! id128_is_valid ( " 01020304-0506-0708-090a0b0c0d0e0f10 " ) ) ;
assert_se ( ! id128_is_valid ( " 010203040506-0708-090a-0b0c0d0e0f10 " ) ) ;
2012-01-04 05:09:05 +04:00
2016-07-25 21:50:24 +03:00
fd = open_tmpfile_unlinkable ( NULL , O_RDWR | O_CLOEXEC ) ;
assert_se ( fd > = 0 ) ;
/* First, write as UUID */
assert_se ( sd_id128_randomize ( & id ) > = 0 ) ;
assert_se ( id128_write_fd ( fd , ID128_UUID , id , false ) > = 0 ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_PLAIN , & id2 ) = = - EINVAL ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_UUID , & id2 ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , id2 ) ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_ANY , & id2 ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , id2 ) ) ;
/* Second, write as plain */
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( ftruncate ( fd , 0 ) > = 0 ) ;
assert_se ( sd_id128_randomize ( & id ) > = 0 ) ;
assert_se ( id128_write_fd ( fd , ID128_PLAIN , id , false ) > = 0 ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_UUID , & id2 ) = = - EINVAL ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_PLAIN , & id2 ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , id2 ) ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_ANY , & id2 ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , id2 ) ) ;
/* Third, write plain without trailing newline */
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( ftruncate ( fd , 0 ) > = 0 ) ;
assert_se ( sd_id128_randomize ( & id ) > = 0 ) ;
assert_se ( write ( fd , sd_id128_to_string ( id , t ) , 32 ) = = 32 ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_UUID , & id2 ) = = - EINVAL ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_PLAIN , & id2 ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , id2 ) ) ;
/* Third, write UUID without trailing newline */
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( ftruncate ( fd , 0 ) > = 0 ) ;
assert_se ( sd_id128_randomize ( & id ) > = 0 ) ;
test: fix stack overflow reported by ASAN
It was meant to write to q instead of t
FAIL: test-id128
================
=================================================================
==125770==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd4615bd31 at pc 0x7a2f41b1bf33 bp 0x7ffd4615b750 sp 0x7ffd4615b748
WRITE of size 1 at 0x7ffd4615bd31 thread T0
#0 0x7a2f41b1bf32 in id128_to_uuid_string src/libsystemd/sd-id128/id128-util.c:42
#1 0x401f73 in main src/test/test-id128.c:147
#2 0x7a2f41336341 in __libc_start_main (/lib64/libc.so.6+0x20341)
#3 0x401129 in _start (/home/crrodriguez/scm/systemd/.libs/test-id128+0x401129)
Address 0x7ffd4615bd31 is located in stack of thread T0 at offset 1409 in frame
#0 0x401205 in main src/test/test-id128.c:37
This frame has 23 object(s):
[32, 40) 'b'
[96, 112) 'id'
[160, 176) 'id2'
[224, 240) 'a'
[288, 304) 'b'
[352, 368) 'a'
[416, 432) 'b'
[480, 496) 'a'
[544, 560) 'b'
[608, 624) 'a'
[672, 688) 'b'
[736, 752) 'a'
[800, 816) 'b'
[864, 880) 'a'
[928, 944) 'b'
[992, 1008) 'a'
[1056, 1072) 'b'
[1120, 1136) 'a'
[1184, 1200) 'b'
[1248, 1264) 'a'
[1312, 1328) 'b'
[1376, 1409) 't' <== Memory access at offset 1409 overflows this variable
[1472, 1509) 'q'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow src/libsystemd/sd-id128/id128-util.c:42 in id128_to_uuid_string
Shadow bytes around the buggy address:
0x100028c23750: f2 f2 00 00 f4 f4 f2 f2 f2 f2 00 00 f4 f4 f2 f2
0x100028c23760: f2 f2 00 00 f4 f4 f2 f2 f2 f2 00 00 f4 f4 f2 f2
0x100028c23770: f2 f2 00 00 f4 f4 f2 f2 f2 f2 00 00 f4 f4 f2 f2
0x100028c23780: f2 f2 00 00 f4 f4 f2 f2 f2 f2 00 00 f4 f4 f2 f2
0x100028c23790: f2 f2 00 00 f4 f4 f2 f2 f2 f2 00 00 f4 f4 f2 f2
=>0x100028c237a0: f2 f2 00 00 00 00[01]f4 f4 f4 f2 f2 f2 f2 00 00
0x100028c237b0: 00 00 05 f4 f4 f4 00 00 00 00 00 00 00 00 00 00
0x100028c237c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100028c237d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100028c237e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100028c237f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==125770==ABORTING
FAIL test-id128 (exit status: 1)
2016-08-05 19:07:49 +03:00
assert_se ( write ( fd , id128_to_uuid_string ( id , q ) , 36 ) = = 36 ) ;
2016-07-25 21:50:24 +03:00
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_PLAIN , & id2 ) = = - EINVAL ) ;
assert_se ( lseek ( fd , 0 , SEEK_SET ) = = 0 ) ;
assert_se ( id128_read_fd ( fd , ID128_UUID , & id2 ) > = 0 ) ;
assert_se ( sd_id128_equal ( id , id2 ) ) ;
2011-10-07 23:06:39 +04:00
return 0 ;
}