/* Return the canonical absolute name of a given file inside chroot.
- Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1996-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; version 2 of the License, or
+ (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
-#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
-#include "ldconfig.h"
+#include <eloop-threshold.h>
+#include <ldconfig.h>
#ifndef PATH_MAX
#define PATH_MAX 1024
char *
chroot_canon (const char *chroot, const char *name)
{
- char *rpath, *dest, *extra_buf = NULL, *rpath_root;
- const char *start, *end, *rpath_limit;
+ char *rpath;
+ char *dest;
+ char *extra_buf = NULL;
+ char *rpath_root;
+ const char *start;
+ const char *end;
+ const char *rpath_limit;
int num_links = 0;
size_t chroot_len = strlen (chroot);
return NULL;
}
- rpath = malloc (chroot_len + PATH_MAX);
+ rpath = xmalloc (chroot_len + PATH_MAX);
+
rpath_limit = rpath + chroot_len + PATH_MAX;
rpath_root = (char *) mempcpy (rpath, chroot, chroot_len) - 1;
for (start = end = name; *start; start = end)
{
- struct stat64 st;
- int n;
+ struct stat st;
/* Skip sequence of multiple path-separators. */
while (*start == '/')
if (dest + (end - start) >= rpath_limit)
{
ptrdiff_t dest_offset = dest - rpath;
+ char *new_rpath;
new_size = rpath_limit - rpath;
if (end - start + 1 > PATH_MAX)
new_size += end - start + 1;
else
new_size += PATH_MAX;
- rpath = realloc (rpath, new_size);
+ new_rpath = (char *) xrealloc (rpath, new_size);
+ rpath = new_rpath;
rpath_limit = rpath + new_size;
- if (rpath == NULL)
- return NULL;
dest = rpath + dest_offset;
}
dest = mempcpy (dest, start, end - start);
*dest = '\0';
- if (lstat64 (rpath, &st) < 0)
+ if (lstat (rpath, &st) < 0)
{
if (*end == '\0')
goto done;
char *buf = alloca (PATH_MAX);
size_t len;
- if (++num_links > MAXSYMLINKS)
+ if (++num_links > __eloop_threshold ())
{
__set_errno (ELOOP);
goto error;
}
- n = readlink (rpath, buf, PATH_MAX);
+ ssize_t n = readlink (rpath, buf, PATH_MAX - 1);
if (n < 0)
{
if (*end == '\0')
extra_buf = alloca (PATH_MAX);
len = strlen (end);
- if ((long int) (n + len) >= PATH_MAX)
+ if (len >= PATH_MAX - n)
{
__set_errno (ENAMETOOLONG);
goto error;