diff options
author | Thomas Martitz <kugel@rockbox.org> | 2011-01-27 20:17:55 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2011-01-27 20:17:55 +0000 |
commit | b703d251be071d0d1bbb7abe458cc0bd215052e0 (patch) | |
tree | 1db8fb978d8cddbaf4a7414466bbd6f2e1f65d6a /apps/tagcache.c | |
parent | 3a1bc3cfdd27b2f6d7268c9fc72910a32899f940 (diff) | |
download | rockbox-b703d251be071d0d1bbb7abe458cc0bd215052e0.tar.gz rockbox-b703d251be071d0d1bbb7abe458cc0bd215052e0.zip |
Workaround the brokenness of realpath() a bit more.
At least on android it blindly writes to the end of the buffer passed to it assuming it's sufficiently. It wasn't in our case, resulting in a buffer overflow (and breakage).
This should fix strange problems relating to database initialization on application targets.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29147 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index 50c6253522..b964da6915 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -4226,8 +4226,17 @@ static bool add_search_root(const char *name) | |||
4226 | #ifndef WIN32 | 4226 | #ifndef WIN32 |
4227 | struct search_roots_ll *this, *prev = NULL; | 4227 | struct search_roots_ll *this, *prev = NULL; |
4228 | char target[MAX_PATH]; | 4228 | char target[MAX_PATH]; |
4229 | char _abs_target[MAX_PATH]; | 4229 | /* Okay, realpath() is almost completely broken on android |
4230 | char * abs_target; | 4230 | * |
4231 | * It doesn't accept NULL for resolved_name to dynamically allocate | ||
4232 | * the resulting path; and it assumes resolved_name to be PATH_MAX | ||
4233 | * (actually MAXPATHLEN, but it's the same [as of 2.3]) long | ||
4234 | * and blindly writes to the end if it | ||
4235 | * | ||
4236 | * therefore use sufficiently large static storage here | ||
4237 | * Note that PATH_MAX != MAX_PATH | ||
4238 | **/ | ||
4239 | static char abs_target[PATH_MAX]; | ||
4231 | ssize_t len; | 4240 | ssize_t len; |
4232 | 4241 | ||
4233 | len = readlink(name, target, sizeof(target)); | 4242 | len = readlink(name, target, sizeof(target)); |
@@ -4235,9 +4244,7 @@ static bool add_search_root(const char *name) | |||
4235 | return false; | 4244 | return false; |
4236 | 4245 | ||
4237 | target[len] = '\0'; | 4246 | target[len] = '\0'; |
4238 | /* realpath(target, NULL) doesn't work on android ... */ | 4247 | if (realpath(target, abs_target) == NULL) |
4239 | abs_target = realpath(target, _abs_target); | ||
4240 | if (abs_target == NULL) | ||
4241 | return false; | 4248 | return false; |
4242 | 4249 | ||
4243 | for(this = &roots_ll; this; prev = this, this = this->next) | 4250 | for(this = &roots_ll; this; prev = this, this = this->next) |
@@ -4258,6 +4265,7 @@ static bool add_search_root(const char *name) | |||
4258 | logf("Error at adding a search root: %s", this ? "path too long":"OOM"); | 4265 | logf("Error at adding a search root: %s", this ? "path too long":"OOM"); |
4259 | free(this); | 4266 | free(this); |
4260 | prev->next = NULL; | 4267 | prev->next = NULL; |
4268 | return false; | ||
4261 | } | 4269 | } |
4262 | this->path = ((char*)this) + sizeof(struct search_roots_ll); | 4270 | this->path = ((char*)this) + sizeof(struct search_roots_ll); |
4263 | strcpy((char*)this->path, abs_target); /* ok to cast const away here */ | 4271 | strcpy((char*)this->path, abs_target); /* ok to cast const away here */ |
@@ -4327,7 +4335,7 @@ static bool check_dir(const char *dirname, int add_files) | |||
4327 | struct dirinfo info = dir_get_info(dir, entry); | 4335 | struct dirinfo info = dir_get_info(dir, entry); |
4328 | 4336 | ||
4329 | yield(); | 4337 | yield(); |
4330 | 4338 | ||
4331 | len = strlen(curpath); | 4339 | len = strlen(curpath); |
4332 | /* don't add an extra / for curpath == / */ | 4340 | /* don't add an extra / for curpath == / */ |
4333 | if (len <= 1) len = 0; | 4341 | if (len <= 1) len = 0; |