Hi,
Currently busybox's biggest stack user (per-function)
is actually in uclibc, not busybox. It's realpath().
Proposed patch uses user-supplied buffer directly,
without intermediate on-stack copy.
This can only make a difference if user supplied
a buffer which is too small - thus user breaks API.
Failure scenario:
realpath("/link_name", user_buffer)
/link_name -> /very_long_name_which_fits_into_PATH_MAX_and_is_also_a_link ->
-> /shorter_name
If user will give e.g. 40-char user_buffer, current implementation
will work, patched one will overflow user_buffer by intermediate name.
This should not be a problem - user must supply PATH_MAX sized buffer,
and in this case patched version also works correctly.
Run tested.
ACK, anyone?
--
vda
Index: libc/stdlib/realpath.c
===================================================================
--- libc/stdlib/realpath.c (revision 20608)
+++ libc/stdlib/realpath.c (working copy)
@@ -43,18 +43,21 @@
#define MAX_READLINKS 32
#ifdef __STDC__
-char *realpath(const char *path, char resolved_path[])
+char *realpath(const char *path, char got_path[])
#else
-char *realpath(path, resolved_path)
+char *realpath(path, got_path)
const char *path;
-char resolved_path[];
+char got_path[];
#endif
{
char copy_path[PATH_MAX];
+ /* use user supplied buffer directly - reduces stack usage */
+ /* char got_path[PATH_MAX]; */
+#ifdef S_IFLNK
char link_path[PATH_MAX];
- char got_path[PATH_MAX];
+#endif
+ const char *max_path;
char *new_path = got_path;
- char *max_path;
int readlinks = 0;
int n;
@@ -124,18 +127,21 @@
__set_errno(ELOOP);
return NULL;
}
- /* See if latest pathname component is a symlink. */
+ /* See if last (so far) pathname component is a symlink. */
*new_path = '\0';
n = readlink(got_path, link_path, PATH_MAX - 1);
if (n < 0) {
/* EINVAL means the file exists but isn't a symlink. */
if (errno != EINVAL) {
- /* Make sure it's null terminated. */
- *new_path = '\0';
- strcpy(resolved_path, got_path);
+ /*strcpy(resolved_path, got_path);*/
return NULL;
}
} else {
+ /* Safe sex check. */
+ if (strlen(path) + n >= PATH_MAX - 2) {
+ __set_errno(ENAMETOOLONG);
+ return NULL;
+ }
/* Note: readlink doesn't add the null byte. */
link_path[n] = '\0';
if (*link_path == '/')
@@ -144,13 +150,8 @@
else
/* Otherwise back up over this component. */
while (*(--new_path) != '/');
- /* Safe sex check. */
- if (strlen(path) + n >= PATH_MAX - 2) {
- __set_errno(ENAMETOOLONG);
- return NULL;
- }
/* Insert symlink contents into path. */
- strcat(link_path, path);
+ strcpy(link_path + n, path);
strcpy(copy_path, link_path);
path = copy_path;
}
@@ -162,6 +163,6 @@
new_path--;
/* Make sure it's null terminated. */
*new_path = '\0';
- strcpy(resolved_path, got_path);
- return resolved_path;
+ /*strcpy(resolved_path, got_path);*/
+ return got_path;
}
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc