ldconfig: remove chroot
Andreas Jaeger
aj@suse.de
Tue Sep 26 09:52:00 GMT 2000
>>>>> Andreas Schwab writes:
> Andreas Jaeger <aj@suse.de> writes:
> |> + buf_ptr = stpncpy (buf_ptr, entry->path, sizeof (buf) - (buf_ptr - buf));
> |> + /* Check for overflow. */
> |> + if ((buf_ptr - buf) >= sizeof (buf))
> |> + {
> |> + if (use_chroot)
> |> + error (0, 0, _("Length of directory %s%s is too large -- directory is ignored\n"),
> |> + opt_chroot, entry->path);
> |> + else
> |> + error (0, 0, _("Length of directory %s is too large -- directory is ignored\n"),
> |> + entry->path);
> |> + return;
> |> + }
> Arbitrary limits are bad. Could you please make buf dynamically
> allocated?
I've removed all arbitrary limits. Is the following ok?
Andreas
2000-09-26 Andreas Jaeger <aj@suse.de>
* elf/ldconfig.c (search_dir): Allow unlimited path length.
(create_links): Likewise.
(parse_opt): Remove trailing slashes from opt_chroot.
(search_dir): Handle chroot.
(setup_file): New function.
(main): Use it to handle chroot.
============================================================
Index: elf/ldconfig.c
--- elf/ldconfig.c 2000/09/24 18:35:02 1.7
+++ elf/ldconfig.c 2000/09/26 16:17:06
@@ -17,6 +17,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <alloca.h>
#include <argp.h>
#include <dirent.h>
#include <elf.h>
@@ -105,14 +106,16 @@
/* Path to root for chroot. */
static char *opt_chroot;
+static int use_chroot;
+
/* Manually link given shared libraries. */
static int opt_manual_link = 0;
/* Cache file to use. */
-static const char *cache_file;
+static char *cache_file;
/* Configuration file. */
-static const char *config_file;
+static char *config_file;
/* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state);
@@ -221,7 +224,19 @@
opt_print_cache = 1;
break;
case 'r':
- opt_chroot = arg;
+ {
+ size_t len = strlen (arg);
+ opt_chroot = arg;
+ use_chroot = 1;
+
+ /* Make sure that opt_chroot ends without a slash. */
+ len = strlen (opt_chroot);
+ while (len && opt_chroot [len - 1] == '/')
+ {
+ --len;
+ opt_chroot [len] = '\0';
+ }
+ }
break;
case 'v':
opt_verbose = 1;
@@ -337,15 +352,17 @@
static void
create_links (const char *path, const char *libname, const char *soname)
{
- char full_libname [PATH_MAX], full_soname [PATH_MAX];
+ char *full_libname, *full_soname;
struct stat stat_lib, stat_so, lstat_so;
int do_link = 1;
int do_remove = 1;
/* XXX: The logics in this function should be simplified. */
/* Get complete path. */
- snprintf (full_libname, sizeof full_libname, "%s/%s", path, libname);
- snprintf (full_soname, sizeof full_soname, "%s/%s", path, soname);
+ full_libname = alloca (strlen (path) + strlen (libname) + 2);
+ full_soname = alloca (strlen (path) + strlen (libname) + 2);
+ sprintf (full_libname, "%s/%s", path, libname);
+ sprintf (full_soname, "%s/%s", path, soname);
/* Does soname already exist and point to the right library? */
if (stat (full_soname, &stat_so) == 0)
@@ -511,15 +528,18 @@
{
DIR *dir;
struct dirent *direntry;
- char buf [PATH_MAX];
- char *soname;
+ char *dir_name, *file_name;
+ int file_name_len, len;
+ char *soname, *tmp_ptr;
struct dlib_entry *dlibs;
struct dlib_entry *dlib_ptr;
- int nchars;
struct stat stat_buf;
int is_link;
unsigned long int hwcap = path_hwcap (entry->path);
+ file_name_len = PATH_MAX;
+ file_name = alloca (file_name_len);
+
dlibs = NULL;
if (opt_verbose)
@@ -529,8 +549,16 @@
else
printf ("%s:\n", entry->path);
}
+
+ dir_name = alloca ((use_chroot ? strlen (opt_chroot) : 0) + strlen (entry->path));
+ tmp_ptr = dir_name;
+
+ if (use_chroot)
+ tmp_ptr = stpcpy (tmp_ptr, opt_chroot);
+
+ tmp_ptr = stpcpy (tmp_ptr, entry->path);
- dir = opendir (entry->path);
+ dir = opendir (dir_name);
if (dir == NULL)
{
if (opt_verbose)
@@ -558,23 +586,28 @@
|| strstr (direntry->d_name, ".so") == NULL)
&& !is_hwcap (direntry->d_name))
continue;
- nchars = snprintf (buf, sizeof (buf), "%s/%s", entry->path,
- direntry->d_name);
- /* Check for overflow. */
- if (nchars >= (int) sizeof (buf))
+ len = (use_chroot ? strlen (opt_chroot) : 0) + strlen (entry->path)
+ + strlen (direntry->d_name);
+ if (len > file_name_len)
{
- error (0, 0, _("buffer for snprintf too small for %s/%s--file is ignored\n"),
- entry->path, direntry->d_name);
- continue;
+ file_name_len = len + 1;
+ file_name = alloca (file_name_len);
}
+
+ if (use_chroot)
+ sprintf (file_name, "%s%s/%s", opt_chroot, entry->path,
+ direntry->d_name);
+ else
+ sprintf (file_name , "%s/%s", entry->path, direntry->d_name);
+
#ifdef _DIRENT_HAVE_D_TYPE
if (direntry->d_type != DT_UNKNOWN)
stat_buf.st_mode = DTTOIF (direntry->d_type);
else
#endif
- if (lstat (buf, &stat_buf))
+ if (lstat (file_name, &stat_buf))
{
- error (0, errno, _("Can't lstat %s"), buf);
+ error (0, errno, _("Can't lstat %s"), file_name);
continue;
}
@@ -585,7 +618,9 @@
new_entry = xmalloc (sizeof (struct dir_entry));
- new_entry->path = buf;
+ len = strlen (entry->path) + strlen (direntry->d_name) + 2;
+ new_entry->path = xmalloc (len);
+ sprintf (new_entry->path, "%s/%s", entry->path, direntry->d_name);
new_entry->flag = entry->flag;
new_entry->next = NULL;
add_single_dir (new_entry, 0);
@@ -596,7 +631,7 @@
is_link = S_ISLNK (stat_buf.st_mode);
- if (process_file (buf, direntry->d_name, &flag, &soname, is_link))
+ if (process_file (file_name, direntry->d_name, &flag, &soname, is_link))
continue;
/* Links will just point to itself. */
@@ -615,13 +650,13 @@
{
if (flag == FLAG_ELF_LIBC5 && entry->flag != FLAG_ELF_LIBC5
&& entry->flag != FLAG_ANY)
- error (0, 0, _("libc5 library %s in wrong directory"), buf);
+ error (0, 0, _("libc5 library %s in wrong directory"), file_name);
if (flag == FLAG_ELF_LIBC6 && entry->flag != FLAG_ELF_LIBC6
&& entry->flag != FLAG_ANY)
- error (0, 0, _("libc6 library %s in wrong directory"), buf);
+ error (0, 0, _("libc6 library %s in wrong directory"), file_name);
if (flag == FLAG_LIBC4 && entry->flag != FLAG_LIBC4
&& entry->flag != FLAG_ANY)
- error (0, 0, _("libc4 library %s in wrong directory"), buf);
+ error (0, 0, _("libc4 library %s in wrong directory"), file_name);
}
/* Add library to list. */
@@ -761,6 +796,33 @@
fclose (file);
}
+static char *
+setup_file (const char *file, const char *default_name)
+{
+ char *res, *tmp;
+ int len_chroot = use_chroot ? strlen (opt_chroot) : 0;
+
+ if (file == NULL)
+ {
+ res = xmalloc (len_chroot + strlen (default_name) + 1);
+ tmp = res;
+ if (use_chroot)
+ tmp = stpcpy (tmp, opt_chroot);
+ stpcpy (tmp, default_name);
+ }
+ else
+ {
+ res = xmalloc (len_chroot + strlen (file) + 1);
+
+ tmp = res;
+ if (use_chroot)
+ tmp = stpcpy (tmp, opt_chroot);
+ stpcpy (tmp, file);
+ }
+
+ return res;
+}
+
int
main (int argc, char **argv)
@@ -778,28 +840,14 @@
for (i = remaining; i < argc; ++i)
add_dir (argv [i]);
}
-
- if (cache_file == NULL)
- cache_file = LD_SO_CACHE;
- if (config_file == NULL)
- config_file = LD_SO_CONF;
+ cache_file = setup_file (cache_file, LD_SO_CACHE);
+ config_file = setup_file (config_file, LD_SO_CONF);
- /* Chroot first. */
- if (opt_chroot)
- {
- if (chroot (opt_chroot))
- /* Report failure and exit program. */
- error (EXIT_FAILURE, errno, _("Can't chroot to %s"), opt_chroot);
- /* chroot doesn't change the working directory, let's play safe. */
- if (chdir ("/"))
- error (EXIT_FAILURE, errno, _("Can't chdir to /"));
- }
-
if (opt_print_cache)
{
print_cache (cache_file);
- exit (0);
+ goto cleanup;
}
if (opt_manual_link)
@@ -810,10 +858,9 @@
for (i = remaining; i < argc; ++i)
manual_link (argv [i]);
- exit (0);
+ goto cleanup;
}
-
if (opt_build_cache)
init_cache ();
@@ -831,6 +878,11 @@
if (opt_build_cache)
save_cache (cache_file);
+
+ /* Cleanup. */
+ cleanup:
+ free (cache_file);
+ free (config_file);
return 0;
}
--
Andreas Jaeger
SuSE Labs aj@suse.de
private aj@arthur.inka.de
http://www.suse.de/~aj
More information about the Libc-hacker
mailing list