@@ -678,6 +678,82 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
678
678
* libraries. There is no binary dependent code anywhere else.
679
679
*/
680
680
681
+ static int get_elf_notes (struct linux_binprm * bprm , struct elf_phdr * phdr , char * * notes , size_t * notes_sz )
682
+ {
683
+ char * data ;
684
+ size_t datasz ;
685
+ loff_t pos ;
686
+ int ret ;
687
+
688
+ if (!phdr )
689
+ return 0 ;
690
+
691
+ datasz = phdr -> p_filesz ;
692
+ if ((datasz > MAX_FILE_NOTE_SIZE ) || (datasz < sizeof (struct elf_note )))
693
+ return - ENOEXEC ;
694
+
695
+ data = kvmalloc (datasz , GFP_KERNEL );
696
+ if (!data )
697
+ return - ENOMEM ;
698
+
699
+ pos = phdr -> p_offset ;
700
+ ret = kernel_read (bprm -> file , data , datasz , & pos );
701
+ if (ret != datasz ) {
702
+ if (ret >= 0 )
703
+ ret = - EIO ;
704
+ kvfree (data );
705
+ return ret ;
706
+ }
707
+
708
+ * notes = data ;
709
+ * notes_sz = datasz ;
710
+ return 0 ;
711
+ }
712
+
713
+ #define PRESERVED_MEM_OK_STRING "preserved-mem-ok"
714
+ #define SZ_PRESERVED_MEM_OK_STRING sizeof(PRESERVED_MEM_OK_STRING)
715
+
716
+ static int check_preserved_mem_ok (struct linux_binprm * bprm , const char * data , const size_t datasz )
717
+ {
718
+ size_t off = 0 ;
719
+ size_t remain ;
720
+
721
+ if (!data )
722
+ return 0 ;
723
+
724
+ while (off < datasz ) {
725
+ const struct elf_note * nhdr ;
726
+ const char * name ;
727
+
728
+ remain = datasz - off ;
729
+
730
+ if (remain < sizeof (* nhdr ))
731
+ return - ENOEXEC ;
732
+
733
+ nhdr = (struct elf_note * )(data + off );
734
+ off += sizeof (* nhdr );
735
+ remain -= sizeof (* nhdr );
736
+
737
+ if (nhdr -> n_type != 0x07c1feed ) {
738
+ off += roundup (nhdr -> n_namesz , 4 ) + roundup (nhdr -> n_descsz , 4 );
739
+ continue ;
740
+ }
741
+
742
+ if (nhdr -> n_namesz > SZ_PRESERVED_MEM_OK_STRING )
743
+ return - ENOEXEC ;
744
+
745
+ name = data + off ;
746
+ if (remain < SZ_PRESERVED_MEM_OK_STRING ||
747
+ strncmp (name , PRESERVED_MEM_OK_STRING , SZ_PRESERVED_MEM_OK_STRING ))
748
+ return - ENOEXEC ;
749
+
750
+ bprm -> accepts_preserved_mem = 1 ;
751
+ break ;
752
+ }
753
+
754
+ return 0 ;
755
+ }
756
+
681
757
#define MAX_RSVD_VA_RANGES 64
682
758
#define RSVD_VA_STRING "Reserved VA"
683
759
#define SZ_RSVD_VA_STRING sizeof(RSVD_VA_STRING)
@@ -784,6 +860,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
784
860
int load_addr_set = 0 ;
785
861
unsigned long error ;
786
862
struct elf_phdr * elf_ppnt , * elf_phdata , * interp_elf_phdata = NULL ;
863
+ struct elf_phdr * elf_notes_phdata = NULL ;
864
+ char * elf_notes = NULL ;
865
+ size_t elf_notes_sz = 0 ;
787
866
unsigned long elf_bss , elf_brk ;
788
867
int bss_prot = 0 ;
789
868
int retval , i ;
@@ -899,6 +978,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
899
978
executable_stack = EXSTACK_DISABLE_X ;
900
979
break ;
901
980
981
+ case PT_NOTE :
982
+ elf_notes_phdata = elf_ppnt ;
983
+ break ;
984
+
902
985
case PT_LOPROC ... PT_HIPROC :
903
986
retval = arch_elf_pt_proc (& loc -> elf_ex , elf_ppnt ,
904
987
bprm -> file , false,
@@ -950,6 +1033,14 @@ static int load_elf_binary(struct linux_binprm *bprm)
950
1033
if (retval )
951
1034
goto out_free_dentry ;
952
1035
1036
+ retval = get_elf_notes (bprm , elf_notes_phdata , & elf_notes , & elf_notes_sz );
1037
+ if (retval )
1038
+ goto out_free_dentry ;
1039
+
1040
+ retval = check_preserved_mem_ok (bprm , elf_notes , elf_notes_sz );
1041
+ if (retval )
1042
+ goto out_free_dentry ;
1043
+
953
1044
/* Flush all traces of the currently running executable */
954
1045
retval = flush_old_exec (bprm );
955
1046
if (retval )
@@ -1226,6 +1317,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
1226
1317
}
1227
1318
}
1228
1319
1320
+ kvfree (elf_notes );
1229
1321
kfree (interp_elf_phdata );
1230
1322
kfree (elf_phdata );
1231
1323
@@ -1306,6 +1398,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
1306
1398
if (interpreter )
1307
1399
fput (interpreter );
1308
1400
out_free_ph :
1401
+ kvfree (elf_notes );
1309
1402
kfree (elf_phdata );
1310
1403
goto out ;
1311
1404
}
0 commit comments