build: create time and date independent binary
PATCH v2 1/1 build: create time and date independent binary
With this option enabled each compilation creates the exact same binary. There are no timestamps, with which a U-Boot binary can be identified.
This option is disabled by default.
---
For testing this patch, I wrote the following 2 scripts, and add a patch, which enables CONFIG_SYS_EXACT_BINARY, as this is normally disabled in default configs.
steps:
- create file, which contains a list of boards you want to check, if they create a date/time independent binary for example:
$ cat test_list at91sam9g20ek_2mmc cairo corvus smartweb axm
- create reference files with
$ ./comp_list_boards.sh test_list init init boards in test_list check board at91sam9g20ek_2mmc init at91sam9g20ek_2mmc check board cairo init cairo check board corvus init corvus check board smartweb init smartweb check board axm init axm
- start another round of compile and compare with base
$ ./comp_list_boards.sh test_list checking boards in test_list check board at91sam9g20ek_2mmc compile at91sam9g20ek_2mmc check board cairo compile cairo check board corvus compile corvus check board smartweb compile smartweb check board axm compile axm
and here the scripts:
exact_bin_defconfig.patch:
.config +1 -1
@@ -228,7 +228,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_SYS_MALLOC_F is not set CONFIG_EXPERT=y -# CONFIG_SYS_EXACT_BINARY is not set +CONFIG_SYS_EXACT_BINARY=y # # Boot images
-------------------------------------------comp_diff_board.sh
base_bin_dir="base_bin"
logfile_base="/tmp/comp"
boardname=""
if [ $# -lt 1 ]
then
echo "need boardname"
exit 1
else
boardname=$1
fi
if [ ! -d "$logfile_base" ]
then
mkdir $logfile_base
fi
logfile=$logfile_base"/"$boardname".log"
init=0
if [ $# -lt 2 ]
then
echo compile $boardname
else
init=1
echo init $boardname
fi
if [ -e $logfile ]
then
rm -rf $logfile
fi
function diff_and_fail (){
echo "-------------------------------------" echo $boardname has differences
if [ -n "$2" ]
then
hexdump -C $2 > gnlmpf2
else
hexdump -C $base_bin_dir/$boardname-$1 > gnlmpf2
fi
hexdump -C $1 > gnlmpf
echo "-------------------------------------" exit 1
}
function diff_or_cp (){
if [ $init -eq 1 ]
then
if [ -n "$2" ] then cp $1 $base_bin_dir/$boardname-$2 else cp $1 $base_bin_dir/$boardname-$1 fi else if [ -n "$2" ] then cmp $1 $base_bin_dir/$boardname-$2 if [ $? -ne 0 ]; then diff_and_fail $1 $base_bin_dir/$boardname-$2 fi else cmp $1 $base_bin_dir/$boardname-$1 if [ $? -ne 0 ]; then diff_and_fail $1 fi fi
fi
}
make mrproper &>>$logfile
git reset --hard HEAD &>>$logfile
make $boardname"_defconfig" &>>$logfile
patch -p1 < exact_bin_defconfig.patch &>>$logfile make -s all &>>$logfile
if [ -s "u-boot.bin" ];
then
diff_or_cp u-boot.bin
fi
if [ -s "spl/u-boot-spl.bin" ];
then
diff_or_cp spl/u-boot-spl.bin u-boot-spl.bin
fi
if [ -s "u-boot.img" ];
then
diff_or_cp u-boot.img
fi
if [ -s "u-boot.kwb" ];
then
diff_or_cp u-boot.kwb
fi
if [ -s "u-boot.pbl" ];
then
diff_or_cp u-boot.pbl
fi
if [ -s "u-boot.pbl" ];
then
diff_or_cp u-boot.pbl
fi
if [ -s "MLO" ];
then
diff_or_cp MLO
fi
-------------------------------------------comp_list_boards.sh
if [ $# -lt 1 ]
then
echo "need boardlist"
exit 1
else
boardlist=$1
fi
init=0
if [ $# -lt 2 ]
then
echo checking boards in $boardlist
else
init=1
echo init boards in $boardlist
fi
while read line
do
echo check board $line
if [ $init -eq 1 ]
then
comp_diff_board.sh $line init
else
comp_diff_board.sh $line
fi
done < $boardlist
Changes in v2:
- add Tested-by: Chris Kuethe <[email protected]>
- add new cmdline parameter for mkimage "-b" so mkimage creates also headers without date/timing information
- add in patch notes 2 scripts and a patch for checking if created binaries are really time/date independent.
Kconfig | 9 +++++++++ Makefile | 16 +++++++++++++++- tools/default_image.c | 2 ++ tools/imagetool.h | 1 + tools/mkimage.c | 5 +++++ 5 files changed, 32 insertions(+), 1 deletion(-)
Kconfig +9 -0
@@ -81,6 +81,15 @@ menuconfig EXPERT Only use this if you really know what you are doing. if EXPERT + config SYS_EXACT_BINARY + bool "Create time and date independent binary" + default n + help + With this option enabled each compilation creates the exact + same binary. There are no timestamps, with which a U-Boot + binary can be identified. + This option is disabled by default. + config SYS_MALLOC_CLEAR_ON_INIT bool "Init with zeros the memory reserved for malloc (slow)" default y
Makefile +15 -1
@@ -780,8 +780,14 @@ endif quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ +ifeq ($(CONFIG_SYS_EXACT_BINARY),y) +MKIMAGEFLAGS_EXTRA = -b +else +MKIMAGEFLAGS_EXTRA = +endif + quiet_cmd_mkimage = MKIMAGE $@ -cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \ +cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_EXTRA) $(MKIMAGEFLAGS_$(@F)) -d $< $@ \ $(if $(KBUILD_VERBOSE:1=), >/dev/null) quiet_cmd_cat = CAT $@
@@ -1230,11 +1236,19 @@ define filechk_version.h echo \#define LD_VERSION_STRING \"$$($(LD) --version | head -n 1)\"; ) endef +ifeq ($(CONFIG_SYS_EXACT_BINARY),y) +define filechk_timestamp.h + (LC_ALL=C date +'#define U_BOOT_DATE "NODATE"'; \ + LC_ALL=C date +'#define U_BOOT_TIME "NOTIME"'; \ + LC_ALL=C date +'#define U_BOOT_TZ "NOTZ"') +endef +else define filechk_timestamp.h (LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \ LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \ LC_ALL=C date +'#define U_BOOT_TZ "%z"') endef +endif $(version_h): include/config/uboot.release FORCE $(call filechk,version.h)
tools/default_image.c +2 -0
@@ -98,6 +98,8 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd,/* Build new header */ image_set_magic (hdr,IH_MAGIC ); +if (params->bflag) + sbuf->st_mtime =0 ;image_set_time (hdr, sbuf->st_mtime);image_set_size (hdr, sbuf->st_size -sizeof (image_header_t));image_set_load (hdr, params->addr);
tools/imagetool.h +1 -0
@@ -33,6 +33,7 @@* type specific functions */ struct image_tool_params { +int bflag;int dflag;int eflag;int fflag;
tools/mkimage.c +5 -0
@@ -51,6 +51,9 @@ main (int argc, char **argv) genimg_get_arch_id (*++argv)) < 0)usage (); goto NXTARG; +case 'b' : + params.bflag =1 ; +break ;case 'c' :if (--argc <=0 )usage ();
@@ -544,6 +547,8 @@ static void usage(void)#else fprintf (stderr,"Signing / verified boot not supported (CONFIG_FIT_SIGNATURE undefined)\n" );#endif +fprintf (stderr," %s -b ==> build exact binary (without date/time stamp)\n" , + params.cmdname);fprintf (stderr," %s -V ==> print version information and exit\n" , params.cmdname);
Signature · 1 line
2.1.0