diff options
-rw-r--r-- | src/firejail/appimage_size.c | 34 | ||||
-rw-r--r-- | status | 6 |
2 files changed, 29 insertions, 11 deletions
diff --git a/src/firejail/appimage_size.c b/src/firejail/appimage_size.c index a20dbba6c..b277553e3 100644 --- a/src/firejail/appimage_size.c +++ b/src/firejail/appimage_size.c | |||
@@ -18,6 +18,9 @@ | |||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | /* | 20 | /* |
21 | This code borrows heavily from src/libappimage_shared/elf.c in libappimage | ||
22 | */ | ||
23 | /* | ||
21 | Compile with: | 24 | Compile with: |
22 | gcc elfsize.c -o elfsize | 25 | gcc elfsize.c -o elfsize |
23 | Example: | 26 | Example: |
@@ -74,7 +77,10 @@ static uint64_t file64_to_cpu(uint64_t val) { | |||
74 | // return 0 if error | 77 | // return 0 if error |
75 | static long unsigned int read_elf32(int fd) { | 78 | static long unsigned int read_elf32(int fd) { |
76 | Elf32_Ehdr ehdr32; | 79 | Elf32_Ehdr ehdr32; |
80 | Elf32_Shdr shdr32; | ||
81 | off_t last_shdr_offset; | ||
77 | ssize_t ret; | 82 | ssize_t ret; |
83 | unsigned long sht_end, last_section_end; | ||
78 | 84 | ||
79 | ret = pread(fd, &ehdr32, sizeof(ehdr32), 0); | 85 | ret = pread(fd, &ehdr32, sizeof(ehdr32), 0); |
80 | if (ret < 0 || (size_t)ret != sizeof(ehdr)) | 86 | if (ret < 0 || (size_t)ret != sizeof(ehdr)) |
@@ -84,14 +90,25 @@ static long unsigned int read_elf32(int fd) { | |||
84 | ehdr.e_shentsize = file16_to_cpu(ehdr32.e_shentsize); | 90 | ehdr.e_shentsize = file16_to_cpu(ehdr32.e_shentsize); |
85 | ehdr.e_shnum = file16_to_cpu(ehdr32.e_shnum); | 91 | ehdr.e_shnum = file16_to_cpu(ehdr32.e_shnum); |
86 | 92 | ||
87 | return(ehdr.e_shoff + (ehdr.e_shentsize * ehdr.e_shnum)); | 93 | last_shdr_offset = ehdr.e_shoff + (ehdr.e_shentsize * (ehdr.e_shnum - 1)); |
94 | ret = pread(fd, &shdr32, sizeof(shdr32), last_shdr_offset); | ||
95 | if (ret < 0 || (size_t)ret != sizeof(shdr32)) | ||
96 | return 0; | ||
97 | |||
98 | /* ELF ends either with the table of section headers (SHT) or with a section. */ | ||
99 | sht_end = ehdr.e_shoff + (ehdr.e_shentsize * ehdr.e_shnum); | ||
100 | last_section_end = file64_to_cpu(shdr32.sh_offset) + file64_to_cpu(shdr32.sh_size); | ||
101 | return sht_end > last_section_end ? sht_end : last_section_end; | ||
88 | } | 102 | } |
89 | 103 | ||
90 | 104 | ||
91 | // return 0 if error | 105 | // return 0 if error |
92 | static long unsigned int read_elf64(int fd) { | 106 | static long unsigned int read_elf64(int fd) { |
93 | Elf64_Ehdr ehdr64; | 107 | Elf64_Ehdr ehdr64; |
108 | Elf64_Shdr shdr64; | ||
109 | off_t last_shdr_offset; | ||
94 | ssize_t ret; | 110 | ssize_t ret; |
111 | unsigned long sht_end, last_section_end; | ||
95 | 112 | ||
96 | ret = pread(fd, &ehdr64, sizeof(ehdr64), 0); | 113 | ret = pread(fd, &ehdr64, sizeof(ehdr64), 0); |
97 | if (ret < 0 || (size_t)ret != sizeof(ehdr)) | 114 | if (ret < 0 || (size_t)ret != sizeof(ehdr)) |
@@ -101,18 +118,21 @@ static long unsigned int read_elf64(int fd) { | |||
101 | ehdr.e_shentsize = file16_to_cpu(ehdr64.e_shentsize); | 118 | ehdr.e_shentsize = file16_to_cpu(ehdr64.e_shentsize); |
102 | ehdr.e_shnum = file16_to_cpu(ehdr64.e_shnum); | 119 | ehdr.e_shnum = file16_to_cpu(ehdr64.e_shnum); |
103 | 120 | ||
104 | return(ehdr.e_shoff + (ehdr.e_shentsize * ehdr.e_shnum)); | 121 | last_shdr_offset = ehdr.e_shoff + (ehdr.e_shentsize * (ehdr.e_shnum - 1)); |
122 | ret = pread(fd, &shdr64, sizeof(shdr64), last_shdr_offset); | ||
123 | if (ret < 0 || (size_t)ret != sizeof(shdr64)) | ||
124 | return 0; | ||
125 | |||
126 | /* ELF ends either with the table of section headers (SHT) or with a section. */ | ||
127 | sht_end = ehdr.e_shoff + (ehdr.e_shentsize * ehdr.e_shnum); | ||
128 | last_section_end = file64_to_cpu(shdr64.sh_offset) + file64_to_cpu(shdr64.sh_size); | ||
129 | return sht_end > last_section_end ? sht_end : last_section_end; | ||
105 | } | 130 | } |
106 | 131 | ||
107 | 132 | ||
108 | // return 0 if error | 133 | // return 0 if error |
109 | // return 0 if this is not an appimgage2 file | 134 | // return 0 if this is not an appimgage2 file |
110 | long unsigned int appimage2_size(const char *fname) { | 135 | long unsigned int appimage2_size(const char *fname) { |
111 | /* TODO, FIXME: This assumes that the section header table (SHT) is | ||
112 | the last part of the ELF. This is usually the case but | ||
113 | it could also be that the last section is the last part | ||
114 | of the ELF. This should be checked for. | ||
115 | */ | ||
116 | ssize_t ret; | 136 | ssize_t ret; |
117 | int fd; | 137 | int fd; |
118 | long unsigned int size = 0; | 138 | long unsigned int size = 0; |
@@ -6,10 +6,8 @@ done: mount empty home if macro can't be whitelisted | |||
6 | done: AppArmor: Allow writing to removable media | 6 | done: AppArmor: Allow writing to removable media |
7 | done: tests: skip audit.exp if tests are already running in a pid namespace | 7 | done: tests: skip audit.exp if tests are already running in a pid namespace |
8 | done: configure.ac: set sysconfdir only if none was specified manually | 8 | done: configure.ac: set sysconfdir only if none was specified manually |
9 | 9 | done: Firejail should look for processes with names exactly named "firejail | |
10 | todo: Firejail should look for processes with names exactly named "firejail | 10 | done: Update appimage size calculation to newest code from libappimage. |
11 | |||
12 | todo: Update appimage size calculation to newest code from libappimage. | ||
13 | 11 | ||
14 | todo: clean /run/user directory (smitsohu) | 12 | todo: clean /run/user directory (smitsohu) |
15 | - firejail.h | 13 | - firejail.h |