summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2021-10-18 01:23:07 -0400
committerWilliam Wilgus <me.theuser@yahoo.com>2021-10-18 23:30:27 -0400
commite1553d860dc42a819fe71913d5a68a77fbf64a6e (patch)
treec29ceec89472e2c249ae3e04ba837de573b6559d
parent0f68866ae5b02e3e154f31b6da12b090380db4b0 (diff)
downloadrockbox-e1553d860dc42a819fe71913d5a68a77fbf64a6e.tar.gz
rockbox-e1553d860dc42a819fe71913d5a68a77fbf64a6e.zip
Open_Plugin add checksum on struct offsets
Adding a checksum over the struct offset will allow checking for compatibility across machines rather than using packed structs to ensure compability For any file created by the user from the device this isn't really a concern But for files between machines, across installs (sim v device), possibly even across compilers this at least will alert the user rather than returning junk data Change-Id: Id0531bbaa7013dce24dece270849f0a10ac99c20
-rw-r--r--apps/open_plugin.c43
-rw-r--r--apps/open_plugin.h18
-rw-r--r--apps/plugins/open_plugins.c36
3 files changed, 73 insertions, 24 deletions
diff --git a/apps/open_plugin.c b/apps/open_plugin.c
index 32b5195334..fe18071454 100644
--- a/apps/open_plugin.c
+++ b/apps/open_plugin.c
@@ -38,6 +38,8 @@
38 38
39struct open_plugin_entry_t open_plugin_entry = {0}; 39struct open_plugin_entry_t open_plugin_entry = {0};
40 40
41static const uint32_t open_plugin_csum = OPEN_PLUGIN_CHECKSUM;
42
41static const int op_entry_sz = sizeof(struct open_plugin_entry_t); 43static const int op_entry_sz = sizeof(struct open_plugin_entry_t);
42 44
43static int open_plugin_hash_get_entry(uint32_t hash, 45static int open_plugin_hash_get_entry(uint32_t hash,
@@ -60,6 +62,13 @@ static inline void op_clear_entry(struct open_plugin_entry_t *entry)
60 entry->lang_id = -1; 62 entry->lang_id = -1;
61} 63}
62 64
65static int op_entry_checksum(struct open_plugin_entry_t *entry)
66{
67 if (!entry || entry->checksum != open_plugin_csum)
68 return 0;
69 return 1;
70}
71
63static int op_find_entry(int fd, struct open_plugin_entry_t *entry, 72static int op_find_entry(int fd, struct open_plugin_entry_t *entry,
64 uint32_t hash, int32_t lang_id) 73 uint32_t hash, int32_t lang_id)
65{ 74{
@@ -75,6 +84,13 @@ static int op_find_entry(int fd, struct open_plugin_entry_t *entry,
75 (entry->hash == hash && hash != 0) || 84 (entry->hash == hash && hash != 0) ||
76 (lang_id == OPEN_PLUGIN_LANG_IGNOREALL))/* return first entry found */ 85 (lang_id == OPEN_PLUGIN_LANG_IGNOREALL))/* return first entry found */
77 { 86 {
87 /* sanity check */
88 if (op_entry_checksum(entry) <= 0)
89 {
90 splashf(HZ * 2, "OpenPlugin Invalid entry");
91 ret = OPEN_PLUGIN_NOT_FOUND;
92 break;
93 }
78 /* NULL terminate fields NOTE -- all are actually +1 larger */ 94 /* NULL terminate fields NOTE -- all are actually +1 larger */
79 entry->name[OPEN_PLUGIN_NAMESZ] = '\0'; 95 entry->name[OPEN_PLUGIN_NAMESZ] = '\0';
80 /*entry->key[OPEN_PLUGIN_BUFSZ] = '\0';*/ 96 /*entry->key[OPEN_PLUGIN_BUFSZ] = '\0';*/
@@ -111,24 +127,27 @@ static int op_update_dat(struct open_plugin_entry_t *entry, bool clear)
111 logf("OP update hash: %x lang_id: %d", hash, lang_id); 127 logf("OP update hash: %x lang_id: %d", hash, lang_id);
112 logf("OP update name: %s clear: %d", entry->name, (int) clear); 128 logf("OP update name: %s clear: %d", entry->name, (int) clear);
113 logf("OP update %s %s %s", entry->name, entry->path, entry->param); 129 logf("OP update %s %s %s", entry->name, entry->path, entry->param);
130
114#if (CONFIG_STORAGE & STORAGE_ATA) /* Harddrive -- update existing */ 131#if (CONFIG_STORAGE & STORAGE_ATA) /* Harddrive -- update existing */
115 logf("OP update *Updating entries* %s", OPEN_PLUGIN_DAT); 132 logf("OP update *Updating entries* %s", OPEN_PLUGIN_DAT);
116 fd = open(OPEN_PLUGIN_DAT, O_RDWR | O_CREAT, 0666); 133 fd = open(OPEN_PLUGIN_DAT, O_RDWR | O_CREAT, 0666);
117 134
118 if (fd < 0) 135 if (fd < 0)
119 return OPEN_PLUGIN_NOT_FOUND; 136 return OPEN_PLUGIN_NOT_FOUND;
120 /* Only read the hash and lang id */ 137 /* Only read the hash lang id and checksum */
121 uint32_t hash_langid[2] = {0}; 138 uint32_t hash_langid_csum[3] = {0};
122 while (read(fd, &hash_langid, sizeof(hash_langid)) == sizeof(hash_langid)) 139 const off_t hlc_sz = sizeof(hash_langid_csum);
140 while (read(fd, &hash_langid_csum, hlc_sz) == hlc_sz)
123 { 141 {
124 if (hash_langid[0] == hash || (int32_t)hash_langid[1] == lang_id) 142 if ((hash_langid_csum[0] == hash || (int32_t)hash_langid_csum[1] == lang_id) &&
143 hash_langid_csum[2] == open_plugin_csum)
125 { 144 {
126 logf("OP update *Entry Exists* hash: %x langid: %d", 145 logf("OP update *Entry Exists* hash: %x langid: %d",
127 hash_langid[0], (int32_t)hash_langid[1]); 146 hash_langid_csum[0], (int32_t)hash_langid[1]);
128 lseek(fd, 0-sizeof(hash_langid), SEEK_CUR);/* back to the start of record */ 147 lseek(fd, 0-hlc_sz, SEEK_CUR);/* back to the start of record */
129 break; 148 break;
130 } 149 }
131 lseek(fd, op_entry_sz - sizeof(hash_langid), SEEK_CUR); /* finish record */ 150 lseek(fd, op_entry_sz - hlc_sz, SEEK_CUR); /* finish record */
132 } 151 }
133 write(fd, entry, op_entry_sz); 152 write(fd, entry, op_entry_sz);
134 close(fd); 153 close(fd);
@@ -146,7 +165,8 @@ static int op_update_dat(struct open_plugin_entry_t *entry, bool clear)
146 /* copy non-duplicate entries back from original */ 165 /* copy non-duplicate entries back from original */
147 while (read(fd1, entry, op_entry_sz) == op_entry_sz) 166 while (read(fd1, entry, op_entry_sz) == op_entry_sz)
148 { 167 {
149 if (entry->hash != hash && entry->lang_id != lang_id) 168 if (entry->hash != hash && entry->lang_id != lang_id &&
169 op_entry_checksum(entry) > 0)
150 { 170 {
151 write(fd, entry, op_entry_sz); 171 write(fd, entry, op_entry_sz);
152 } 172 }
@@ -202,8 +222,9 @@ uint32_t open_plugin_add_path(const char *key, const char *plugin, const char *p
202 222
203 if (plugin) 223 if (plugin)
204 { 224 {
205 open_plugin_entry.hash = hash; 225 open_plugin_entry.hash = hash;
206 open_plugin_entry.lang_id = lang_id; 226 open_plugin_entry.lang_id = lang_id;
227 open_plugin_entry.checksum = open_plugin_csum;
207 /* name */ 228 /* name */
208 if (path_basename(plugin, (const char **)&pos) == 0) 229 if (path_basename(plugin, (const char **)&pos) == 0)
209 pos = "\0"; 230 pos = "\0";
@@ -242,7 +263,7 @@ retnhash:
242 263
243void open_plugin_browse(const char *key) 264void open_plugin_browse(const char *key)
244{ 265{
245 logf("OP Browse"); 266 logf("OP browse");
246 struct browse_context browse; 267 struct browse_context browse;
247 char tmp_buf[OPEN_PLUGIN_BUFSZ+1]; 268 char tmp_buf[OPEN_PLUGIN_BUFSZ+1];
248 open_plugin_get_entry(key, &open_plugin_entry); 269 open_plugin_get_entry(key, &open_plugin_entry);
diff --git a/apps/open_plugin.h b/apps/open_plugin.h
index e1d49bf329..adfb9a75bc 100644
--- a/apps/open_plugin.h
+++ b/apps/open_plugin.h
@@ -41,19 +41,31 @@ enum {
41 OPEN_PLUGIN_LANG_IGNORE = (-2), 41 OPEN_PLUGIN_LANG_IGNORE = (-2),
42 OPEN_PLUGIN_LANG_IGNOREALL = (-3), 42 OPEN_PLUGIN_LANG_IGNOREALL = (-3),
43 OPEN_PLUGIN_NOT_FOUND = (-1), 43 OPEN_PLUGIN_NOT_FOUND = (-1),
44 OPEN_PLUGIN_NEEDS_FLUSHED = (-2) 44 OPEN_PLUGIN_NEEDS_FLUSHED = (-2),
45}; 45};
46 46
47struct open_plugin_entry_t 47struct open_plugin_entry_t
48{ 48{
49/* hash and lang_id need to be the first items */ 49/* hash lang_id checksum need to be the first items */
50 uint32_t hash; 50 uint32_t hash;
51 int32_t lang_id; 51 int32_t lang_id;
52 uint32_t checksum;
52 char name[OPEN_PLUGIN_NAMESZ+1]; 53 char name[OPEN_PLUGIN_NAMESZ+1];
53 /*char key[OPEN_PLUGIN_BUFSZ+1];*/ 54 /*char key[OPEN_PLUGIN_BUFSZ+1];*/
54 char path[OPEN_PLUGIN_BUFSZ+1]; 55 char path[OPEN_PLUGIN_BUFSZ+1];
55 char param[OPEN_PLUGIN_BUFSZ+1]; 56 char param[OPEN_PLUGIN_BUFSZ+1];
56}__attribute__((packed)); 57};
58
59#define OPEN_PLUGIN_CHECKSUM (uint32_t) \
60( \
61 (sizeof(struct open_plugin_entry_t) << 16) + \
62 offsetof(struct open_plugin_entry_t, hash) + \
63 offsetof(struct open_plugin_entry_t, lang_id) + \
64 offsetof(struct open_plugin_entry_t, checksum) + \
65 offsetof(struct open_plugin_entry_t, name) + \
66 /*offsetof(struct open_plugin_entry_t, key)+*/ \
67 offsetof(struct open_plugin_entry_t, path) + \
68 offsetof(struct open_plugin_entry_t, param))
57 69
58inline static void open_plugin_get_hash(const char *key, uint32_t *hash) 70inline static void open_plugin_get_hash(const char *key, uint32_t *hash)
59{ 71{
diff --git a/apps/plugins/open_plugins.c b/apps/plugins/open_plugins.c
index b8d11d2ae5..3a0c34d8d6 100644
--- a/apps/plugins/open_plugins.c
+++ b/apps/plugins/open_plugins.c
@@ -49,7 +49,8 @@
49static int fd_dat; 49static int fd_dat;
50static struct gui_synclist lists; 50static struct gui_synclist lists;
51struct open_plugin_entry_t op_entry; 51struct open_plugin_entry_t op_entry;
52const off_t op_entry_sz = sizeof(struct open_plugin_entry_t); 52static const uint32_t open_plugin_csum = OPEN_PLUGIN_CHECKSUM;
53static const off_t op_entry_sz = sizeof(struct open_plugin_entry_t);
53 54
54/* we only need the names for the first menu so don't bother reading paths yet */ 55/* we only need the names for the first menu so don't bother reading paths yet */
55const off_t op_name_sz = OPEN_PLUGIN_NAMESZ + (op_entry.name - (char*)&op_entry); 56const off_t op_name_sz = OPEN_PLUGIN_NAMESZ + (op_entry.name - (char*)&op_entry);
@@ -101,6 +102,15 @@ static bool op_entry_read_name(int fd, int selected_item)
101 return op_entry_read(fd, selected_item, op_name_sz); 102 return op_entry_read(fd, selected_item, op_name_sz);
102} 103}
103 104
105static int op_entry_checksum(void)
106{
107 if (op_entry.checksum != open_plugin_csum)
108 {
109 return 0;
110 }
111 return 1;
112}
113
104static int op_entry_read_opx(const char *path) 114static int op_entry_read_opx(const char *path)
105{ 115{
106 int ret = -1; 116 int ret = -1;
@@ -112,13 +122,14 @@ static int op_entry_read_opx(const char *path)
112 if(len > OP_LEN && rb->strcasecmp(&((path)[len-OP_LEN]), "." OP_EXT) == 0) 122 if(len > OP_LEN && rb->strcasecmp(&((path)[len-OP_LEN]), "." OP_EXT) == 0)
113 { 123 {
114 fd_opx = rb->open(path, O_RDONLY); 124 fd_opx = rb->open(path, O_RDONLY);
115 if (fd_opx) 125 if (fd_opx >= 0)
116 { 126 {
117 filesize = rb->filesize(fd_opx); 127 filesize = rb->filesize(fd_opx);
118 ret = filesize; 128 ret = filesize;
119 if (filesize == op_entry_sz && !op_entry_read(fd_opx, 0, op_entry_sz)) 129 if (filesize == op_entry_sz && !op_entry_read(fd_opx, 0, op_entry_sz))
120 ret = 0; 130 ret = 0;
121 131 else if (op_entry_checksum() <= 0)
132 ret = 0;
122 rb->close(fd_opx); 133 rb->close(fd_opx);
123 } 134 }
124 } 135 }
@@ -131,7 +142,7 @@ static void op_entry_export(int selection)
131 int fd = -1; 142 int fd = -1;
132 char filename [MAX_PATH + 1]; 143 char filename [MAX_PATH + 1];
133 144
134 if (!op_entry_read(fd_dat, selection, op_entry_sz)) 145 if (!op_entry_read(fd_dat, selection, op_entry_sz) || op_entry_checksum() <= 0)
135 goto failure; 146 goto failure;
136 147
137 rb->snprintf(filename, MAX_PATH, "%s/%s", PLUGIN_APPS_DIR, op_entry.name); 148 rb->snprintf(filename, MAX_PATH, "%s/%s", PLUGIN_APPS_DIR, op_entry.name);
@@ -161,6 +172,11 @@ failure:
161 172
162} 173}
163 174
175static void op_entry_set_checksum(void)
176{
177 op_entry.checksum = open_plugin_csum;
178}
179
164static void op_entry_set_name(void) 180static void op_entry_set_name(void)
165{ 181{
166 char tmp_buf[OPEN_PLUGIN_NAMESZ+1]; 182 char tmp_buf[OPEN_PLUGIN_NAMESZ+1];
@@ -277,12 +293,12 @@ static int op_entry_transfer(int fd, int fd_tmp,
277 void *data) 293 void *data)
278{ 294{
279 int entries = -1; 295 int entries = -1;
280 if (fd_tmp && fd && rb->lseek(fd, 0, SEEK_SET) == 0) 296 if (fd_tmp >= 0 && fd >= 0 && rb->lseek(fd, 0, SEEK_SET) == 0)
281 { 297 {
282 entries = 0; 298 entries = 0;
283 while (rb->read(fd, &op_entry, op_entry_sz) == op_entry_sz) 299 while (rb->read(fd, &op_entry, op_entry_sz) == op_entry_sz)
284 { 300 {
285 if (compfn && compfn(&op_entry, entries, data) > 0) 301 if (compfn && compfn(&op_entry, entries, data) > 0 && op_entry_checksum() > 0)
286 { 302 {
287 rb->write(fd_tmp, &op_entry, op_entry_sz); 303 rb->write(fd_tmp, &op_entry, op_entry_sz);
288 entries++; 304 entries++;
@@ -359,7 +375,7 @@ static uint32_t op_entry_add_path(const char *key, const char *plugin, const cha
359 op_entry.hash = newhash; 375 op_entry.hash = newhash;
360 } 376 }
361 } 377 }
362 378 op_entry_set_checksum();
363 rb->write(fd_tmp, &op_entry, op_entry_sz); /* add new entry first */ 379 rb->write(fd_tmp, &op_entry, op_entry_sz); /* add new entry first */
364 } 380 }
365 else if(op_entry_read_opx(plugin) == op_entry_sz) 381 else if(op_entry_read_opx(plugin) == op_entry_sz)
@@ -374,13 +390,13 @@ static uint32_t op_entry_add_path(const char *key, const char *plugin, const cha
374 open_plugin_get_hash(op_entry.path, &hash); 390 open_plugin_get_hash(op_entry.path, &hash);
375 391
376 op_entry.hash = hash; 392 op_entry.hash = hash;
377 393 op_entry_set_checksum();
378 rb->write(fd_tmp, &op_entry, op_entry_sz); /* add new entry first */ 394 rb->write(fd_tmp, &op_entry, op_entry_sz); /* add new entry first */
379 } 395 }
380 else 396 else
381 { 397 {
382 if (op_entry.lang_id != LANG_SHORTCUTS) 398 if (op_entry.lang_id != LANG_SHORTCUTS)
383 rb->splashf(HZ / 2, rb->str(LANG_OPEN_PLUGIN_NOT_A_PLUGIN), pos); 399 rb->splashf(HZ * 2, rb->str(LANG_OPEN_PLUGIN_NOT_A_PLUGIN), pos);
384 return 0; 400 return 0;
385 } 401 }
386 } 402 }
@@ -845,7 +861,7 @@ reopen_datfile:
845 synclist_set(MENU_ID_MAIN, selection, items, 1); 861 synclist_set(MENU_ID_MAIN, selection, items, 1);
846 rb->gui_synclist_draw(&lists); 862 rb->gui_synclist_draw(&lists);
847 863
848 while (!exit) 864 while (!exit && fd_dat >= 0)
849 { 865 {
850 action = rb->get_action(CONTEXT_LIST,TIMEOUT_BLOCK); 866 action = rb->get_action(CONTEXT_LIST,TIMEOUT_BLOCK);
851 867