libreboot-utils: unified max path lengths

just use PATH_MAX like a normal person

with additional safety

Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
Leah Rowe
2026-03-31 07:42:40 +01:00
parent fb5f1b4ed1
commit 2f7623ff06
7 changed files with 26 additions and 78 deletions
+5 -3
View File
@@ -65,8 +65,10 @@ int fchmod(int fd, mode_t mode);
#define MAX_CMD_LEN 50 #define MAX_CMD_LEN 50
#ifndef PATH_LEN #ifndef PATH_MAX
#define PATH_LEN 4096 #error PATH_MAX_undefined
#elif ((PATH_MAX) < 1024)
#error PATH_MAX_too_low
#endif #endif
#define OFF_ERR 0 #define OFF_ERR 0
@@ -613,7 +615,7 @@ typedef char assert_read[(IO_READ==0)?1:-1];
typedef char assert_write[(IO_WRITE==1)?1:-1]; typedef char assert_write[(IO_WRITE==1)?1:-1];
typedef char assert_pread[(IO_PREAD==2)?1:-1]; typedef char assert_pread[(IO_PREAD==2)?1:-1];
typedef char assert_pwrite[(IO_PWRITE==3)?1:-1]; typedef char assert_pwrite[(IO_PWRITE==3)?1:-1];
typedef char assert_pathlen[(PATH_LEN>=256)?1:-1]; typedef char assert_pathlen[(PATH_MAX>=1024)?1:-1];
/* commands */ /* commands */
typedef char assert_cmd_dump[(CMD_DUMP==0)?1:-1]; typedef char assert_cmd_dump[(CMD_DUMP==0)?1:-1];
typedef char assert_cmd_setmac[(CMD_SETMAC==1)?1:-1]; typedef char assert_cmd_setmac[(CMD_SETMAC==1)?1:-1];
+6 -31
View File
@@ -71,7 +71,6 @@ fsync_dir(const char *path)
int saved_errno = errno; int saved_errno = errno;
size_t pathlen = 0; size_t pathlen = 0;
size_t maxlen = 0;
char *dirbuf = NULL; char *dirbuf = NULL;
int dirfd = -1; int dirfd = -1;
@@ -81,14 +80,7 @@ fsync_dir(const char *path)
int close_errno; int close_errno;
#if defined(PATH_LEN) && \ if (if_err(slen(path, PATH_MAX, &pathlen) == 0, EINVAL))
(PATH_LEN) >= 256
maxlen = PATH_LEN;
#else
maxlen = 4096;
#endif
if (if_err(slen(path, maxlen, &pathlen) == 0, EINVAL))
goto err_fsync_dir; goto err_fsync_dir;
memcpy(smalloc(&dirbuf, pathlen + 1), memcpy(smalloc(&dirbuf, pathlen + 1),
@@ -677,7 +669,7 @@ rootfs(void)
* TODO: * TODO:
missing length bound check. missing length bound check.
potential CPU DoS on very long paths, spammed repeatedly. potential CPU DoS on very long paths, spammed repeatedly.
perhaps cap at PATH_LEN? perhaps cap at MAX_PATH?
*/ */
int int
fs_resolve_at(int dirfd, const char *path, int flags) fs_resolve_at(int dirfd, const char *path, int flags)
@@ -685,12 +677,7 @@ fs_resolve_at(int dirfd, const char *path, int flags)
int nextfd = -1; int nextfd = -1;
int curfd; int curfd;
const char *p; const char *p;
#if defined(PATH_LEN) && \ char name[PATH_MAX];
((PATH_LEN) >= 256)
char name[PATH_LEN];
#else
char name[4096];
#endif
int saved_errno = errno; int saved_errno = errno;
int r; int r;
int is_last; int is_last;
@@ -756,12 +743,6 @@ fs_next_component(const char **p,
{ {
const char *s = *p; const char *s = *p;
size_t len = 0; size_t len = 0;
#if defined(PATH_LEN) && \
(PATH_LEN) >= 256
size_t maxlen = PATH_LEN;
#else
size_t maxlen = 4096;
#endif
while (*s == '/') while (*s == '/')
s++; s++;
@@ -775,7 +756,7 @@ fs_next_component(const char **p,
len++; len++;
if (len == 0 || len >= namesz || if (len == 0 || len >= namesz ||
len >= maxlen) { len >= PATH_MAX) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
return -1; return -1;
} }
@@ -831,17 +812,11 @@ fs_dirname_basename(const char *path,
char *slash; char *slash;
size_t len; size_t len;
int rval; int rval;
#if defined(PATH_LEN) && \
(PATH_LEN) >= 256
size_t maxlen = PATH_LEN;
#else
size_t maxlen = 4096;
#endif
if (if_err(path == NULL || dir == NULL || base == NULL, EFAULT)) if (if_err(path == NULL || dir == NULL || base == NULL, EFAULT))
return -1; return -1;
slen(path, maxlen, &len); slen(path, PATH_MAX, &len);
memcpy(smalloc(&buf, len + 1), memcpy(smalloc(&buf, len + 1),
path, len + 1); path, len + 1);
@@ -863,7 +838,7 @@ fs_dirname_basename(const char *path,
} }
} else if (allow_relative) { } else if (allow_relative) {
sdup(".", maxlen, dir); sdup(".", PATH_MAX, dir);
*base = buf; *base = buf;
} else { } else {
errno = EINVAL; errno = EINVAL;
+6 -25
View File
@@ -55,12 +55,6 @@ int
new_tmp_common(int *fd, char **path, int type, new_tmp_common(int *fd, char **path, int type,
char *tmpdir, const char *template) char *tmpdir, const char *template)
{ {
#if defined(PATH_LEN) && \
(PATH_LEN) >= 256
size_t maxlen = PATH_LEN;
#else
size_t maxlen = 4096;
#endif
struct stat st; struct stat st;
const char *templatestr; const char *templatestr;
@@ -131,11 +125,11 @@ new_tmp_common(int *fd, char **path, int type,
templatestr = "tmp.XXXXXXXXXX"; templatestr = "tmp.XXXXXXXXXX";
/* may as well calculate in advance */ /* may as well calculate in advance */
destlen = slen(tmpdir, maxlen, &dirlen) + 1 destlen = slen(tmpdir, PATH_MAX, &dirlen) + 1
+ slen(templatestr, maxlen, &templatestr_len); + slen(templatestr, PATH_MAX, &templatestr_len);
/* full path: */ /* full path: */
dest = scatn(3, (const char *[]) { tmpdir, "/", templatestr }, dest = scatn(3, (const char *[]) { tmpdir, "/", templatestr },
maxlen, &dest); PATH_MAX, &dest);
fname = dest + dirlen + 1; fname = dest + dirlen + 1;
@@ -298,19 +292,12 @@ same_dir(const char *a, const char *b)
int saved_errno = errno; int saved_errno = errno;
int rval_scmp; int rval_scmp;
#if defined(PATH_LEN) && \
(PATH_LEN) >= 256
size_t maxlen = (PATH_LEN);
#else
size_t maxlen = 4096;
#endif
/* optimisation: if both dirs /* optimisation: if both dirs
are the same, we don't need are the same, we don't need
to check anything. sehr schnell! to check anything. sehr schnell!
*/ */
/* bonus: scmp checks null for us */ /* bonus: scmp checks null for us */
if (!scmp(a, b, maxlen, &rval_scmp)) if (!scmp(a, b, PATH_MAX, &rval_scmp))
goto success_same_dir; goto success_same_dir;
fd_a = fs_open(a, O_RDONLY | O_DIRECTORY | O_NOFOLLOW); fd_a = fs_open(a, O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
@@ -531,12 +518,6 @@ mkhtemp(int *fd,
int close_errno; int close_errno;
int saved_errno = errno; int saved_errno = errno;
#if defined(PATH_LEN) && \
(PATH_LEN) >= 256
size_t max_len = PATH_LEN;
#else
size_t max_len = 4096;
#endif
int r; int r;
char *end; char *end;
@@ -547,10 +528,10 @@ mkhtemp(int *fd,
return -1; return -1;
/* count X */ /* count X */
for (end = template + slen(template, max_len, &template_len); for (end = template + slen(template, PATH_MAX, &template_len);
end > template && *--end == 'X'; xc++); end > template && *--end == 'X'; xc++);
fname_len = slen(fname, max_len, &fname_len); fname_len = slen(fname, PATH_MAX, &fname_len);
if (if_err(strrchr(fname, '/') != NULL, EINVAL)) if (if_err(strrchr(fname, '/') != NULL, EINVAL))
return -1; return -1;
+2 -8
View File
@@ -22,12 +22,6 @@
struct xstate * struct xstate *
xstart(int argc, char *argv[]) xstart(int argc, char *argv[])
{ {
#if defined(PATH_LEN) && \
((PATH_LEN) >= 256)
static size_t maxlen = PATH_LEN;
#else
static size_t maxlen = 4096;
#endif
static int first_run = 1; static int first_run = 1;
static char *dir = NULL; static char *dir = NULL;
static char *base = NULL; static char *base = NULL;
@@ -119,7 +113,7 @@ xstart(int argc, char *argv[])
err_exit(errno, "xstart: don't know CWD of %s", err_exit(errno, "xstart: don't know CWD of %s",
us.f.fname); us.f.fname);
sdup(base, maxlen, &us.f.base); sdup(base, PATH_MAX, &us.f.base);
us.f.dirfd = fs_open(dir, us.f.dirfd = fs_open(dir,
O_RDONLY | O_DIRECTORY); O_RDONLY | O_DIRECTORY);
@@ -133,7 +127,7 @@ xstart(int argc, char *argv[])
&tmpdir, &tmpbase_local, 0) < 0) &tmpdir, &tmpbase_local, 0) < 0)
err_exit(errno, "tmp basename"); err_exit(errno, "tmp basename");
sdup(tmpbase_local, maxlen, &us.f.tmpbase); sdup(tmpbase_local, PATH_MAX, &us.f.tmpbase);
free_and_set_null(&tmpdir); free_and_set_null(&tmpdir);
+1 -1
View File
@@ -601,7 +601,7 @@ lbsetprogname(char *argv0)
if (!set) { if (!set) {
if (argv0 == NULL) if (argv0 == NULL)
return "libreboot-utils"; return "libreboot-utils";
(void) sdup(argv0, 4096, &progname); (void) sdup(argv0, PATH_MAX, &progname);
set = 1; set = 1;
} }
+2
View File
@@ -36,6 +36,8 @@ main(int argc, char **argv)
free_and_set_null(&buf); free_and_set_null(&buf);
fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!"); fprintf(stderr, "\n%s\n", same ? "You win!" : "You lose!");
printf("%lu\n", PATH_MAX);
return same ? EXIT_SUCCESS : EXIT_FAILURE; return same ? EXIT_SUCCESS : EXIT_FAILURE;
} }
+4 -10
View File
@@ -40,12 +40,6 @@ exit_cleanup(void);
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
#if defined (PATH_LEN) && \
(PATH_LEN) >= 256
size_t maxlen = PATH_LEN;
#else
size_t maxlen = 4096;
#endif
size_t len; size_t len;
size_t tlen; size_t tlen;
size_t xc = 0; size_t xc = 0;
@@ -55,7 +49,7 @@ main(int argc, char *argv[])
char *p; char *p;
char *s = NULL; char *s = NULL;
char *rp; char *rp;
char resolved[maxlen]; char resolved[PATH_MAX];
char c; char c;
int fd = -1; int fd = -1;
@@ -95,7 +89,7 @@ main(int argc, char *argv[])
/* custom template e.g. foo.XXXXXXXXXXXXXXXXXXXXX */ /* custom template e.g. foo.XXXXXXXXXXXXXXXXXXXXX */
if (template != NULL) { if (template != NULL) {
for (p = template + slen(template, maxlen, &tlen); for (p = template + slen(template, PATH_MAX, &tlen);
p > template && *--p == 'X'; xc++); p > template && *--p == 'X'; xc++);
if (xc < 3) /* the gnu mktemp errs on less than 3 */ if (xc < 3) /* the gnu mktemp errs on less than 3 */
@@ -129,8 +123,8 @@ main(int argc, char *argv[])
if (*s == '\0') if (*s == '\0')
err_exit(EFAULT, "empty string initialisation"); err_exit(EFAULT, "empty string initialisation");
slen(s, maxlen, &len); /* Nullterminierung prüfen */ slen(s, PATH_MAX, &len); /* Nullterminierung prüfen */
/* for good measure */ /* for good measure. (bonus: also re-checks length overflow) */
printf("%s\n", s); printf("%s\n", s);