Also results in a binary size shrink by sharing more code :)
Without this a process having write access to a directory could trick
a more privilidged rm -r call to delete any file that the rm process
has access to.
From 6591d36bb46222489737a8384b51bfefc381d837 Mon Sep 17 00:00:00 2001
From: Sertonix <[email protected]>
Date: Tue, 9 Dec 2025 15:12:14 +0100
Subject: [PATCH 1/7] recursive_action: prevent file type confusion when files
changed
It could for example unintentionally follow symlinks when a directory
is replaced with a symlink after the type check. Callers need to use
state->dirfd and state->baseName in some cases to make this effective.
function old new delta
recursive_action1 418 721 +303
recursive_action 108 157 +49
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 352/0) Total: 352 bytes
---
include/libbb.h | 2 ++
libbb/recursive_action.c | 66 +++++++++++++++++++++++++++-------------
2 files changed, 47 insertions(+), 21 deletions(-)
diff --git a/include/libbb.h b/include/libbb.h
index 17c9bc785..957f549de 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -536,6 +536,8 @@ typedef struct recursive_state {
unsigned flags;
unsigned depth;
void *userData;
+ char *fileName, *baseName;
+ int dirfd;
int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
} recursive_state_t;
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c
index b1c4bfad7..f168001be 100644
--- a/libbb/recursive_action.c
+++ b/libbb/recursive_action.c
@@ -15,10 +15,8 @@
* location, and do something (something specified
* by the fileAction and dirAction function pointers).
*
- * Unfortunately, while nftw(3) could replace this and reduce
- * code size a bit, nftw() wasn't supported before GNU libc 2.1,
- * and so isn't sufficiently portable to take over since glibc2.1
- * is so stinking huge.
+ * Unfortunately, while nftw(3) works very similar it does not expose
+ * the file descriptors to allow safe usage.
*/
static int FAST_FUNC true_action(struct recursive_state *state UNUSED_PARAM,
@@ -64,11 +62,11 @@ static int FAST_FUNC true_action(struct recursive_state *state UNUSED_PARAM,
* 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir.
*/
-static int recursive_action1(recursive_state_t *state, const char *fileName)
+static int recursive_action1(recursive_state_t *state)
{
struct stat statbuf;
unsigned follow;
- int status;
+ int status, olddirfd = state->dirfd;
DIR *dir;
struct dirent *next;
@@ -76,17 +74,17 @@ static int recursive_action1(recursive_state_t *state, const char *fileName)
if (state->depth == 0)
follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0;
follow &= state->flags;
- status = (follow ? stat : lstat)(fileName, &statbuf);
+ status = fstatat(state->dirfd, state->baseName, &statbuf, follow ? 0 : AT_SYMLINK_NOFOLLOW);
if (status < 0) {
#ifdef DEBUG_RECURS_ACTION
bb_error_msg("status=%d flags=%x", status, state->flags);
#endif
if ((state->flags & ACTION_DANGLING_OK)
&& errno == ENOENT
- && lstat(fileName, &statbuf) == 0
+ && fstatat(state->dirfd, state->baseName, &statbuf, AT_SYMLINK_NOFOLLOW) == 0
) {
/* Dangling link */
- return state->fileAction(state, fileName, &statbuf);
+ return state->fileAction(state, state->fileName, &statbuf);
}
goto done_nak_warn;
}
@@ -97,57 +95,75 @@ static int recursive_action1(recursive_state_t *state, const char *fileName)
if ( /* (!(state->flags & ACTION_FOLLOWLINKS) && S_ISLNK(statbuf.st_mode)) || */
!S_ISDIR(statbuf.st_mode)
) {
- return state->fileAction(state, fileName, &statbuf);
+ return state->fileAction(state, state->fileName, &statbuf);
}
/* It's a directory (or a link to one, and followLinks is set) */
if (!(state->flags & ACTION_RECURSE)) {
- return state->dirAction(state, fileName, &statbuf);
+ return state->dirAction(state, state->fileName, &statbuf);
}
if (!(state->flags & ACTION_DEPTHFIRST)) {
- status = state->dirAction(state, fileName, &statbuf);
+ status = state->dirAction(state, state->fileName, &statbuf);
if (status == FALSE)
goto done_nak_warn;
if (status == SKIP)
return TRUE;
}
- dir = opendir(fileName);
+ state->dirfd = openat(olddirfd, state->baseName, O_RDONLY | O_DIRECTORY | (follow ? 0 : O_NOFOLLOW));
+ if (state->dirfd < 0)
+ goto done_nak_warn;
+ dir = fdopendir(state->dirfd);
if (!dir) {
/* findutils-4.1.20 reports this */
/* (i.e. it doesn't silently return with exit code 1) */
/* To trigger: "find -exec rm -rf {} \;" */
goto done_nak_warn;
}
+ state->dirfd = dirfd(dir);
status = TRUE;
while ((next = readdir(dir)) != NULL) {
- char *nextFile;
+ size_t n1, n2, n3;
int s;
- nextFile = concat_subpath_file(fileName, next->d_name);
- if (nextFile == NULL)
+ if (DOT_OR_DOTDOT(next->d_name))
continue;
+ n1 = strlen(state->fileName);
+ n2 = (state->fileName[n1 - 1] != '/'); /* 1: "path has no trailing slash" */
+ n3 = strlen(next->d_name) + 1;
+
+ state->fileName = xrealloc(state->fileName, n1 + n2 + n3);
+ if (n2)
+ state->fileName[n1] = '/';
+ state->baseName = &state->fileName[n1+n2];
+ memcpy(state->baseName, next->d_name, n3);
+
/* process every file (NB: ACTION_RECURSE is set in flags) */
state->depth++;
- s = recursive_action1(state, nextFile);
+ s = recursive_action1(state);
if (s == FALSE)
status = FALSE;
- free(nextFile);
state->depth--;
+ state->fileName = xrealloc(state->fileName, n1 + 1);
+ state->fileName[n1] = '\0';
+ state->baseName = strrchr(state->fileName, '/');
+ state->baseName = state->baseName ? state->baseName + 1 : state->fileName;
+
//#define RECURSE_RESULT_ABORT -1
// if (s == RECURSE_RESULT_ABORT) {
// closedir(dir);
// return s;
// }
}
+ state->dirfd = olddirfd;
closedir(dir);
if (state->flags & ACTION_DEPTHFIRST) {
- if (!state->dirAction(state, fileName, &statbuf))
+ if (!state->dirAction(state, state->fileName, &statbuf))
goto done_nak_warn;
}
@@ -155,7 +171,9 @@ static int recursive_action1(recursive_state_t *state, const char *fileName)
done_nak_warn:
if (!(state->flags & ACTION_QUIET))
- bb_simple_perror_msg(fileName);
+ bb_simple_perror_msg(state->fileName);
+
+ state->dirfd = olddirfd;
return FALSE;
}
@@ -165,6 +183,7 @@ int FAST_FUNC recursive_action(const char *fileName,
int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
void *userData)
{
+ int ret;
/* Keeping a part of variables of recusive descent in a "state structure"
* instead of passing ALL of them down as parameters of recursive_action1()
* relieves register pressure, both in recursive_action1()
@@ -174,8 +193,13 @@ int FAST_FUNC recursive_action(const char *fileName,
state.flags = flags;
state.depth = 0;
state.userData = userData;
+ state.fileName = xstrdup(fileName);
+ state.baseName = state.fileName;
+ state.dirfd = xopen(".", O_RDONLY|O_DIRECTORY);
state.fileAction = fileAction ? fileAction : true_action;
state.dirAction = dirAction ? dirAction : true_action;
- return recursive_action1(&state, fileName);
+ ret = recursive_action1(&state);
+ free(state.fileName);
+ return ret;
}
--
2.52.0
From ed4ebd243e8ea2e688a9ecb8f6a37bcc07200056 Mon Sep 17 00:00:00 2001
From: Sertonix <[email protected]>
Date: Tue, 9 Dec 2025 15:17:50 +0100
Subject: [PATCH 2/7] remove_file: switch to using recursive_action
Prevents recursive deletion to follow symlinks
function old new delta
fileAction 200 337 +137
recursive_action 157 178 +21
recursive_action1 721 737 +16
.rodata 100908 100875 -33
remove_file 694 47 -647
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/2 up/down: 174/-680) Total: -506 bytes
---
coreutils/chown.c | 2 +-
findutils/find.c | 4 +-
findutils/grep.c | 2 +-
include/libbb.h | 9 ++--
libbb/recursive_action.c | 13 +++--
libbb/remove_file.c | 109 ++++++++++++---------------------------
6 files changed, 49 insertions(+), 90 deletions(-)
diff --git a/coreutils/chown.c b/coreutils/chown.c
index 528a2a05a..c32812b8a 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -147,7 +147,7 @@ int chown_main(int argc UNUSED_PARAM, char **argv)
param.chown_func = lchown;
}
- flags = ACTION_DEPTHFIRST; /* match coreutils order */
+ flags = ACTION_DEPTH_POST; /* match coreutils order */
if (OPT_RECURSE)
flags |= ACTION_RECURSE;
if (OPT_TRAVERSE_TOP)
diff --git a/findutils/find.c b/findutils/find.c
index 31c996988..582bc83bb 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -1307,7 +1307,7 @@ static action*** parse_params(char **argv)
#if ENABLE_FEATURE_FIND_DEPTH
else if (parm == OPT_DEPTH) {
dbg("%d", __LINE__);
- G.recurse_flags |= ACTION_DEPTHFIRST;
+ G.recurse_flags |= ACTION_DEPTH_POST;
}
#endif
/* Actions are grouped by operators
@@ -1369,7 +1369,7 @@ static action*** parse_params(char **argv)
else if (parm == PARM_delete) {
dbg("%d", __LINE__);
G.need_print = 0;
- G.recurse_flags |= ACTION_DEPTHFIRST;
+ G.recurse_flags |= ACTION_DEPTH_POST;
(void) ALLOC_ACTION(delete);
}
#endif
diff --git a/findutils/grep.c b/findutils/grep.c
index 0bd4898bc..e21bec885 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -697,7 +697,7 @@ static int grep_dir(const char *dir)
| ACTION_RECURSE
| ((option_mask32 & OPT_R) ? ACTION_FOLLOWLINKS : 0)
| ACTION_FOLLOWLINKS_L0 /* grep -r ... SYMLINK follows it */
- | ACTION_DEPTHFIRST
+ | ACTION_DEPTH_POST
| 0,
/* fileAction= */ file_action_grep,
/* dirAction= */ NULL,
diff --git a/include/libbb.h b/include/libbb.h
index 957f549de..71199f1e2 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -527,9 +527,10 @@ enum {
ACTION_RECURSE = (1 << 0),
ACTION_FOLLOWLINKS = (1 << 1),
ACTION_FOLLOWLINKS_L0 = (1 << 2),
- ACTION_DEPTHFIRST = (1 << 3),
- ACTION_QUIET = (1 << 4),
- ACTION_DANGLING_OK = (1 << 5),
+ ACTION_DEPTH_PRE = (1 << 3),
+ ACTION_DEPTH_POST = (1 << 4),
+ ACTION_QUIET = (1 << 5),
+ ACTION_DANGLING_OK = (1 << 6),
};
typedef uint8_t recurse_flags_t;
typedef struct recursive_state {
@@ -537,7 +538,7 @@ typedef struct recursive_state {
unsigned depth;
void *userData;
char *fileName, *baseName;
- int dirfd;
+ int dirfd, state;
int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
} recursive_state_t;
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c
index f168001be..48182ded2 100644
--- a/libbb/recursive_action.c
+++ b/libbb/recursive_action.c
@@ -48,13 +48,13 @@ static int FAST_FUNC true_action(struct recursive_state *state UNUSED_PARAM,
* on each file/subdirectory.
* If any one of these calls returns 0, current recursive_action() returns 0.
*
- * If !ACTION_DEPTHFIRST, dirAction is called before recurse.
+ * If ACTION_DEPTH_PRE, dirAction is called before recurse.
* Return value of 0 (FALSE) is an error: prevents recursion,
* the warning is printed (unless ACTION_QUIET) and recursive_action() returns 0.
* Return value of 2 (SKIP) prevents recursion, instead recursive_action()
* returns 1 (TRUE, no error).
*
- * If ACTION_DEPTHFIRST, dirAction is called after recurse.
+ * If ACTION_DEPTH_POST, dirAction is called after recurse.
* If it returns 0, the warning is printed and recursive_action() returns 0.
*
* ACTION_FOLLOWLINKS mainly controls handling of links to dirs.
@@ -104,7 +104,8 @@ static int recursive_action1(recursive_state_t *state)
return state->dirAction(state, state->fileName, &statbuf);
}
- if (!(state->flags & ACTION_DEPTHFIRST)) {
+ if (state->flags & ACTION_DEPTH_PRE) {
+ state->state = ACTION_DEPTH_PRE;
status = state->dirAction(state, state->fileName, &statbuf);
if (status == FALSE)
goto done_nak_warn;
@@ -162,7 +163,8 @@ static int recursive_action1(recursive_state_t *state)
state->dirfd = olddirfd;
closedir(dir);
- if (state->flags & ACTION_DEPTHFIRST) {
+ if (state->flags & ACTION_DEPTH_POST) {
+ state->state = ACTION_DEPTH_POST;
if (!state->dirAction(state, state->fileName, &statbuf))
goto done_nak_warn;
}
@@ -190,12 +192,13 @@ int FAST_FUNC recursive_action(const char *fileName,
* and in every file/dirAction().
*/
recursive_state_t state;
- state.flags = flags;
+ state.flags = flags | ((flags & (ACTION_DEPTH_PRE|ACTION_DEPTH_POST)) ? 0 : ACTION_DEPTH_PRE);
state.depth = 0;
state.userData = userData;
state.fileName = xstrdup(fileName);
state.baseName = state.fileName;
state.dirfd = xopen(".", O_RDONLY|O_DIRECTORY);
+ state.state = 0;
state.fileAction = fileAction ? fileAction : true_action;
state.dirAction = dirAction ? dirAction : true_action;
diff --git a/libbb/remove_file.c b/libbb/remove_file.c
index 1505e6218..8721a1ea0 100644
--- a/libbb/remove_file.c
+++ b/libbb/remove_file.c
@@ -10,97 +10,52 @@
/* Used from NOFORK applets. Must not allocate anything */
-int FAST_FUNC remove_file(const char *path, int flags)
+static int FAST_FUNC fileAction(struct recursive_state *state,
+ const char *fileName,
+ struct stat *statbuf)
{
- struct stat path_stat;
-
- if (lstat(path, &path_stat) < 0) {
- if (errno != ENOENT) {
- bb_perror_msg("can't stat '%s'", path);
- return -1;
- }
- if (!(flags & FILEUTILS_FORCE)) {
- bb_perror_msg("can't remove '%s'", path);
- return -1;
- }
- return 0;
- }
-
- if (S_ISDIR(path_stat.st_mode)) {
- DIR *dp;
- struct dirent *d;
- int status = 0;
+ int flags = *((int*)state->userData);
+ int isdir = S_ISDIR(statbuf->st_mode);
- if (!(flags & FILEUTILS_RECUR)) {
- bb_error_msg("'%s' is a directory", path);
- return -1;
+ if (!isdir || (state->state & ACTION_DEPTH_PRE)) {
+ if (isdir && !(flags & FILEUTILS_RECUR)) {
+ bb_error_msg("'%s' is a directory", fileName);
+ return FALSE;
}
- if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 && isatty(0))
+ if ((!(flags & FILEUTILS_FORCE)
+ && faccessat(state->dirfd, state->baseName, W_OK, 0) < 0
+ && !S_ISLNK(statbuf->st_mode)
+ && isatty(0))
|| (flags & FILEUTILS_INTERACTIVE)
) {
- fprintf(stderr, "%s: descend into directory '%s'? ",
- applet_name, path);
- if (!bb_ask_y_confirmation())
- return 0;
- }
-
- dp = opendir(path);
- if (dp == NULL) {
- return -1;
- }
-
- while ((d = readdir(dp)) != NULL) {
- char *new_path;
-
- new_path = concat_subpath_file(path, d->d_name);
- if (new_path == NULL)
- continue;
- if (remove_file(new_path, flags) < 0)
- status = -1;
- free(new_path);
- }
- closedir(dp);
-
- if (flags & FILEUTILS_INTERACTIVE) {
- fprintf(stderr, "%s: remove directory '%s'? ",
- applet_name, path);
+ fprintf(stderr, "%s: %s '%s'? ", isdir ? "remove" : "descend into directory", applet_name, state->fileName);
if (!bb_ask_y_confirmation())
- return status;
- }
-
- if (status == 0 && rmdir(path) < 0) {
- bb_perror_msg("can't remove '%s'", path);
- return -1;
- }
-
- if (flags & FILEUTILS_VERBOSE) {
- printf("removed directory: '%s'\n", path);
+ return isdir ? SKIP : TRUE;
}
- return status;
+ if (isdir)
+ return TRUE;
}
- /* !ISDIR */
- if ((!(flags & FILEUTILS_FORCE)
- && access(path, W_OK) < 0
- && !S_ISLNK(path_stat.st_mode)
- && isatty(0))
- || (flags & FILEUTILS_INTERACTIVE)
- ) {
- fprintf(stderr, "%s: remove '%s'? ", applet_name, path);
- if (!bb_ask_y_confirmation())
- return 0;
- }
-
- if (unlink(path) < 0) {
- bb_perror_msg("can't remove '%s'", path);
- return -1;
+ // FIXME isdir && status == 0
+ if (unlinkat(state->dirfd, state->baseName, isdir ? AT_REMOVEDIR : 0) < 0) {
+ bb_perror_msg("can't remove '%s'", fileName);
+ return FALSE;
}
if (flags & FILEUTILS_VERBOSE) {
- printf("removed '%s'\n", path);
+ printf("removed %s'%s'\n", isdir ? "directory: " : "", fileName);
}
- return 0;
+ return TRUE;
+}
+
+int FAST_FUNC remove_file(const char *path, int flags)
+{
+ int ret = recursive_action(path,
+ ACTION_QUIET|ACTION_DEPTH_PRE|ACTION_DEPTH_POST | ((flags & FILEUTILS_RECUR) ? ACTION_RECURSE : 0),
+ fileAction, fileAction, &flags
+ );
+ return ret == FALSE ? -1 : 0;
}
--
2.52.0
From 21568dc0094669b1f90531a45a0afc97466333d5 Mon Sep 17 00:00:00 2001
From: Sertonix <[email protected]>
Date: Tue, 9 Dec 2025 14:30:54 +0100
Subject: [PATCH 3/7] archival/tar: use dirfd of recursive_action
function old new delta
writeFileToTarball 497 542 +45
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 45/0) Total: 45 bytes
---
archival/tar.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/archival/tar.c b/archival/tar.c
index e7a74a547..9dca211f6 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -533,8 +533,9 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
/* Is this a regular file? */
if (tbInfo->hlInfo == NULL && S_ISREG(statbuf->st_mode)) {
/* open the file we want to archive, and make sure all is well */
- inputFileFd = open_or_warn(fileName, O_RDONLY);
+ inputFileFd = openat(state->dirfd, state->baseName, O_RDONLY);
if (inputFileFd < 0) {
+ bb_perror_msg("can't open '%s'", fileName);
return FALSE; /* make recursive_action() return FALSE */
}
}
--
2.52.0
From 555282b5a48ed235435c27e20f20064d4e6c02fa Mon Sep 17 00:00:00 2001
From: Sertonix <[email protected]>
Date: Tue, 9 Dec 2025 14:39:48 +0100
Subject: [PATCH 4/7] chmod: use dirfd from recursive_action
function old new delta
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0) Total: 0 bytes
---
coreutils/chmod.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/coreutils/chmod.c b/coreutils/chmod.c
index 5832cc51b..5714ae595 100644
--- a/coreutils/chmod.c
+++ b/coreutils/chmod.c
@@ -75,7 +75,7 @@ static int FAST_FUNC fileAction(struct recursive_state *state,
/* match coreutils behavior */
if (state->depth == 0) {
/* statbuf holds lstat result, but we need stat (follow link) */
- if (stat(fileName, statbuf))
+ if (fstatat(state->dirfd, state->baseName, statbuf, 0))
goto err;
} else { /* depth > 0: skip links */
if (S_ISLNK(statbuf->st_mode))
@@ -86,7 +86,7 @@ static int FAST_FUNC fileAction(struct recursive_state *state,
if (newmode == (mode_t)-1)
bb_error_msg_and_die("invalid mode '%s'", (char *)state->userData);
- if (chmod(fileName, newmode) == 0) {
+ if (fchmodat(state->dirfd, state->baseName, newmode, AT_SYMLINK_NOFOLLOW) == 0) {
if (OPT_VERBOSE
|| (OPT_CHANGED
&& (statbuf->st_mode & 07777) != (newmode & 07777))
--
2.52.0
From 649cf83c8ccfa108feac68a4bad2af3a18342280 Mon Sep 17 00:00:00 2001
From: Sertonix <[email protected]>
Date: Tue, 9 Dec 2025 14:39:57 +0100
Subject: [PATCH 5/7] chown: use dirfd from recursive_action
function old new delta
chown_main 220 215 -5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-5) Total: -5 bytes
---
coreutils/chown.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/coreutils/chown.c b/coreutils/chown.c
index c32812b8a..11ee4693e 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -94,14 +94,12 @@ static const char chown_longopts[] ALIGN1 =
;
#endif
-typedef int (*chown_fptr)(const char *, uid_t, gid_t);
-
struct param_t {
struct bb_uidgid_t ugid;
- chown_fptr chown_func;
+ int chown_flag;
};
-static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
+static int FAST_FUNC fileAction(struct recursive_state *state,
const char *fileName, struct stat *statbuf)
{
#define param (*(struct param_t*)state->userData)
@@ -109,7 +107,7 @@ static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
uid_t u = (param.ugid.uid == (uid_t)-1L) ? statbuf->st_uid : param.ugid.uid;
gid_t g = (param.ugid.gid == (gid_t)-1L) ? statbuf->st_gid : param.ugid.gid;
- if (param.chown_func(fileName, u, g) == 0) {
+ if (fchownat(state->dirfd, state->baseName, u, g, param.chown_flag) == 0) {
if (OPT_VERBOSE
|| (OPT_CHANGED && (statbuf->st_uid != u || statbuf->st_gid != g))
) {
@@ -139,12 +137,12 @@ int chown_main(int argc UNUSED_PARAM, char **argv)
argv += optind;
/* This matches coreutils behavior (almost - see below) */
- param.chown_func = chown;
+ param.chown_flag = 0;
if (OPT_NODEREF
/* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
) {
- param.chown_func = lchown;
+ param.chown_flag = AT_SYMLINK_NOFOLLOW;
}
flags = ACTION_DEPTH_POST; /* match coreutils order */
--
2.52.0
From f9950912bc8053c27da27b5a0e6652daa0c58177 Mon Sep 17 00:00:00 2001
From: Sertonix <[email protected]>
Date: Tue, 9 Dec 2025 14:42:26 +0100
Subject: [PATCH 6/7] run_parts: use dirfd from recursive_action
function old new delta
act 218 226 +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 8/0) Total: 8 bytes
---
debianutils/run_parts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index 780df3e96..cff7a0390 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -151,7 +151,7 @@ static int FAST_FUNC act(struct recursive_state *state,
if (state->depth == 1
&& ( !(statbuf->st_mode & (S_IFREG | S_IFLNK))
|| invalid_name(file)
- || (!(option_mask32 & OPT_l) && access(file, X_OK) != 0))
+ || (!(option_mask32 & OPT_l) && faccessat(state->dirfd, state->baseName, W_OK, 0) != 0))
) {
return SKIP;
}
--
2.52.0
From 9fd9c723ba0fd96f3de96c49b297cc1b4b0afef5 Mon Sep 17 00:00:00 2001
From: Sertonix <[email protected]>
Date: Tue, 9 Dec 2025 17:24:43 +0100
Subject: [PATCH 7/7] recursive_action: remove fileName argument from
fileAction/dirAction
function old new delta
skip_dir 176 180 +4
uuidcache_check_device 112 114 +2
fileAction 337 338 +1
dir_act 275 276 +1
add_to_prg_cache_if_socket 276 277 +1
add_to_dirlist 77 78 +1
act 226 221 -5
writeFileToTarball 542 528 -14
recursive_action1 737 721 -16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 6/3 up/down: 10/-35) Total: -25 bytes
---
archival/tar.c | 15 +++++++--------
coreutils/chmod.c | 5 ++---
coreutils/chown.c | 6 +++---
debianutils/run_parts.c | 6 +++---
editors/diff.c | 8 +++-----
findutils/find.c | 7 +++----
findutils/grep.c | 13 ++++++-------
include/libbb.h | 8 ++++----
libbb/recursive_action.c | 15 +++++++--------
libbb/remove_file.c | 7 +++----
modutils/depmod.c | 9 ++++-----
modutils/modprobe-small.c | 3 +--
modutils/modprobe.c | 5 ++---
networking/netstat.c | 8 +++-----
selinux/chcon.c | 19 +++++++++----------
selinux/setfiles.c | 5 ++---
util-linux/lspci.c | 5 ++---
util-linux/lsusb.c | 9 ++++-----
util-linux/mdev.c | 8 +++-----
util-linux/volume_id/get_devname.c | 7 +++----
20 files changed, 74 insertions(+), 94 deletions(-)
diff --git a/archival/tar.c b/archival/tar.c
index 9dca211f6..30298e5d7 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -472,17 +472,16 @@ static int exclude_file(const llist_t *excluded_files, const char *file)
# endif
static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
- const char *fileName,
struct stat *statbuf)
{
struct TarBallInfo *tbInfo = (struct TarBallInfo *) state->userData;
const char *header_name;
int inputFileFd = -1;
- DBG("writeFileToTarball('%s')", fileName);
+ DBG("writeFileToTarball('%s')", state->fileName);
/* Strip leading '/' and such (must be before memorizing hardlink's name) */
- header_name = skip_unsafe_prefix(fileName);
+ header_name = skip_unsafe_prefix(state->fileName);
if (header_name[0] == '\0')
return TRUE;
@@ -492,7 +491,7 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
/* It is against the rules to archive a socket */
if (S_ISSOCK(statbuf->st_mode)) {
- bb_error_msg("%s: socket ignored", fileName);
+ bb_error_msg("%s: socket ignored", state->fileName);
return TRUE;
}
@@ -519,7 +518,7 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
if (tbInfo->tarFileStatBuf.st_dev == statbuf->st_dev
&& tbInfo->tarFileStatBuf.st_ino == statbuf->st_ino
) {
- bb_error_msg("%s: file is the archive; skipping", fileName);
+ bb_error_msg("%s: file is the archive; skipping", state->fileName);
return TRUE;
}
@@ -535,13 +534,13 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
/* open the file we want to archive, and make sure all is well */
inputFileFd = openat(state->dirfd, state->baseName, O_RDONLY);
if (inputFileFd < 0) {
- bb_perror_msg("can't open '%s'", fileName);
+ bb_perror_msg("can't open '%s'", state->fileName);
return FALSE; /* make recursive_action() return FALSE */
}
}
/* Add an entry to the tarball */
- if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
+ if (writeTarHeader(tbInfo, header_name, state->fileName, statbuf) == FALSE) {
return FALSE; /* make recursive_action() return FALSE */
}
@@ -558,7 +557,7 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
////off_t readSize;
////readSize = bb_copyfd_size(inputFileFd, tbInfo->tarFd, statbuf->st_size);
////if (readSize != statbuf->st_size && readSize >= 0) {
- //// bb_error_msg_and_die("short read from %s, aborting", fileName);
+ //// bb_error_msg_and_die("short read from %s, aborting", state->fileName);
////}
/* Check that file did not grow in between? */
diff --git a/coreutils/chmod.c b/coreutils/chmod.c
index 5714ae595..c2a4961f2 100644
--- a/coreutils/chmod.c
+++ b/coreutils/chmod.c
@@ -67,7 +67,6 @@
*/
static int FAST_FUNC fileAction(struct recursive_state *state,
- const char *fileName,
struct stat *statbuf)
{
mode_t newmode;
@@ -92,14 +91,14 @@ static int FAST_FUNC fileAction(struct recursive_state *state,
&& (statbuf->st_mode & 07777) != (newmode & 07777))
) {
char modestr[12];
- printf("mode of '%s' changed to %04o (%s)\n", fileName,
+ printf("mode of '%s' changed to %04o (%s)\n", state->fileName,
newmode & 07777, bb_mode_string(modestr, newmode)+1);
}
return TRUE;
}
err:
if (!OPT_QUIET)
- bb_simple_perror_msg(fileName);
+ bb_simple_perror_msg(state->fileName);
return FALSE;
}
diff --git a/coreutils/chown.c b/coreutils/chown.c
index 11ee4693e..720364383 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -100,7 +100,7 @@ struct param_t {
};
static int FAST_FUNC fileAction(struct recursive_state *state,
- const char *fileName, struct stat *statbuf)
+ struct stat *statbuf)
{
#define param (*(struct param_t*)state->userData)
#define opt option_mask32
@@ -112,12 +112,12 @@ static int FAST_FUNC fileAction(struct recursive_state *state,
|| (OPT_CHANGED && (statbuf->st_uid != u || statbuf->st_gid != g))
) {
printf("changed ownership of '%s' to %u:%u\n",
- fileName, (unsigned)u, (unsigned)g);
+ state->fileName, (unsigned)u, (unsigned)g);
}
return TRUE;
}
if (!OPT_QUIET)
- bb_simple_perror_msg(fileName);
+ bb_simple_perror_msg(state->fileName);
return FALSE;
#undef opt
#undef param
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index cff7a0390..edb06e050 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -143,21 +143,21 @@ static int bb_alphasort(const void *p1, const void *p2)
}
static int FAST_FUNC act(struct recursive_state *state,
- const char *file, struct stat *statbuf)
+ struct stat *statbuf)
{
if (state->depth == 0)
return TRUE;
if (state->depth == 1
&& ( !(statbuf->st_mode & (S_IFREG | S_IFLNK))
- || invalid_name(file)
+ || invalid_name(state->fileName)
|| (!(option_mask32 & OPT_l) && faccessat(state->dirfd, state->baseName, W_OK, 0) != 0))
) {
return SKIP;
}
names = xrealloc_vector(names, 4, cur);
- names[cur++] = xstrdup(file);
+ names[cur++] = xstrdup(state->fileName);
/*names[cur] = NULL; - xrealloc_vector did it */
return TRUE;
diff --git a/editors/diff.c b/editors/diff.c
index 6f4ed9712..862e132b8 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -804,11 +804,10 @@ struct dlist {
/* This function adds a filename to dl, the directory listing. */
static int FAST_FUNC add_to_dirlist(struct recursive_state *state,
- const char *filename,
struct stat *sb UNUSED_PARAM)
{
struct dlist *const l = state->userData;
- const char *file = filename + l->len;
+ const char *file = state->fileName + l->len;
while (*file == '/')
file++;
l->dl = xrealloc_vector(l->dl, 6, l->e);
@@ -821,11 +820,10 @@ static int FAST_FUNC add_to_dirlist(struct recursive_state *state,
* to the list and prevents recursive_action from recursing into it.
*/
static int FAST_FUNC skip_dir(struct recursive_state *state,
- const char *filename,
struct stat *sb)
{
if (!(option_mask32 & FLAG(r)) && state->depth) {
- add_to_dirlist(state, filename, sb);
+ add_to_dirlist(state, sb);
return SKIP;
}
if (!(option_mask32 & FLAG(N))) {
@@ -834,7 +832,7 @@ static int FAST_FUNC skip_dir(struct recursive_state *state,
* Testcase: diff -r /tmp /
* (it would recurse deep into /proc without this code) */
struct dlist *const l = state->userData;
- filename += l->len;
+ char *filename = state->fileName + l->len;
if (filename[0]) {
struct stat osb;
char *othername = concat_path_file(G.other_dir, filename);
diff --git a/findutils/find.c b/findutils/find.c
index 582bc83bb..443b02849 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -1011,7 +1011,6 @@ ACTF(links)
static int FAST_FUNC fileAction(
struct recursive_state *state IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM),
- const char *fileName,
struct stat *statbuf)
{
int r;
@@ -1024,7 +1023,7 @@ static int FAST_FUNC fileAction(
if (G.xdev_dev[i] == statbuf->st_dev)
goto found;
}
- //bb_error_msg("'%s': not same fs", fileName);
+ //bb_error_msg("'%s': not same fs", state->fileName);
same_fs = 0;
found: ;
}
@@ -1040,10 +1039,10 @@ static int FAST_FUNC fileAction(
return SKIP; /* stop recursing */
#endif
- r = exec_actions(G.actions, fileName, statbuf);
+ r = exec_actions(G.actions, state->fileName, statbuf);
/* Had no explicit -print[0] or -exec? then print */
if ((r & TRUE) && G.need_print)
- puts(fileName);
+ puts(state->fileName);
#if ENABLE_FEATURE_FIND_MAXDEPTH
if (S_ISDIR(statbuf->st_mode)) {
diff --git a/findutils/grep.c b/findutils/grep.c
index e21bec885..6545040fb 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -654,8 +654,7 @@ static void load_pattern_list(llist_t **lst, char *pattern)
llist_add_to(lst, new_grep_list_data(p, 0));
}
-static int FAST_FUNC file_action_grep(struct recursive_state *state UNUSED_PARAM,
- const char *filename,
+static int FAST_FUNC file_action_grep(struct recursive_state *state,
struct stat *statbuf)
{
FILE *file;
@@ -668,23 +667,23 @@ static int FAST_FUNC file_action_grep(struct recursive_state *state UNUSED_PARAM
struct stat sb;
if (!(option_mask32 & OPT_R))
return 0;
- if (stat(filename, &sb) != 0) {
+ if (stat(state->fileName, &sb) != 0) {
if (!SUPPRESS_ERR_MSGS)
- bb_simple_perror_msg(filename);
+ bb_simple_perror_msg(state->fileName);
return 0;
}
if (S_ISDIR(sb.st_mode))
return 1;
}
- file = fopen_for_read(filename);
+ file = fopen_for_read(state->fileName);
if (file == NULL) {
if (!SUPPRESS_ERR_MSGS)
- bb_simple_perror_msg(filename);
+ bb_simple_perror_msg(state->fileName);
open_errors = 1;
return 0;
}
- cur_file = filename;
+ cur_file = state->fileName;
*(int*)state->userData |= grep_file(file);
fclose(file);
return 1;
diff --git a/include/libbb.h b/include/libbb.h
index 71199f1e2..40043dfb3 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -539,12 +539,12 @@ typedef struct recursive_state {
void *userData;
char *fileName, *baseName;
int dirfd, state;
- int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
- int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
+ int FAST_FUNC (*fileAction)(struct recursive_state *state, struct stat* statbuf);
+ int FAST_FUNC (*dirAction)(struct recursive_state *state, struct stat* statbuf);
} recursive_state_t;
int recursive_action(const char *fileName, unsigned flags,
- int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
- int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
+ int FAST_FUNC (*fileAction)(struct recursive_state *state, struct stat* statbuf),
+ int FAST_FUNC (*dirAction)(struct recursive_state *state, struct stat* statbuf),
void *userData
) FAST_FUNC;
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c
index 48182ded2..f4034121b 100644
--- a/libbb/recursive_action.c
+++ b/libbb/recursive_action.c
@@ -20,7 +20,6 @@
*/
static int FAST_FUNC true_action(struct recursive_state *state UNUSED_PARAM,
- const char *fileName UNUSED_PARAM,
struct stat *statbuf UNUSED_PARAM)
{
return TRUE;
@@ -84,7 +83,7 @@ static int recursive_action1(recursive_state_t *state)
&& fstatat(state->dirfd, state->baseName, &statbuf, AT_SYMLINK_NOFOLLOW) == 0
) {
/* Dangling link */
- return state->fileAction(state, state->fileName, &statbuf);
+ return state->fileAction(state, &statbuf);
}
goto done_nak_warn;
}
@@ -95,18 +94,18 @@ static int recursive_action1(recursive_state_t *state)
if ( /* (!(state->flags & ACTION_FOLLOWLINKS) && S_ISLNK(statbuf.st_mode)) || */
!S_ISDIR(statbuf.st_mode)
) {
- return state->fileAction(state, state->fileName, &statbuf);
+ return state->fileAction(state, &statbuf);
}
/* It's a directory (or a link to one, and followLinks is set) */
if (!(state->flags & ACTION_RECURSE)) {
- return state->dirAction(state, state->fileName, &statbuf);
+ return state->dirAction(state, &statbuf);
}
if (state->flags & ACTION_DEPTH_PRE) {
state->state = ACTION_DEPTH_PRE;
- status = state->dirAction(state, state->fileName, &statbuf);
+ status = state->dirAction(state, &statbuf);
if (status == FALSE)
goto done_nak_warn;
if (status == SKIP)
@@ -165,7 +164,7 @@ static int recursive_action1(recursive_state_t *state)
if (state->flags & ACTION_DEPTH_POST) {
state->state = ACTION_DEPTH_POST;
- if (!state->dirAction(state, state->fileName, &statbuf))
+ if (!state->dirAction(state, &statbuf))
goto done_nak_warn;
}
@@ -181,8 +180,8 @@ static int recursive_action1(recursive_state_t *state)
int FAST_FUNC recursive_action(const char *fileName,
unsigned flags,
- int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
- int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
+ int FAST_FUNC (*fileAction)(struct recursive_state *state, struct stat* statbuf),
+ int FAST_FUNC (*dirAction)(struct recursive_state *state, struct stat* statbuf),
void *userData)
{
int ret;
diff --git a/libbb/remove_file.c b/libbb/remove_file.c
index 8721a1ea0..8a8d3b939 100644
--- a/libbb/remove_file.c
+++ b/libbb/remove_file.c
@@ -11,7 +11,6 @@
/* Used from NOFORK applets. Must not allocate anything */
static int FAST_FUNC fileAction(struct recursive_state *state,
- const char *fileName,
struct stat *statbuf)
{
int flags = *((int*)state->userData);
@@ -19,7 +18,7 @@ static int FAST_FUNC fileAction(struct recursive_state *state,
if (!isdir || (state->state & ACTION_DEPTH_PRE)) {
if (isdir && !(flags & FILEUTILS_RECUR)) {
- bb_error_msg("'%s' is a directory", fileName);
+ bb_error_msg("'%s' is a directory", state->fileName);
return FALSE;
}
@@ -40,12 +39,12 @@ static int FAST_FUNC fileAction(struct recursive_state *state,
// FIXME isdir && status == 0
if (unlinkat(state->dirfd, state->baseName, isdir ? AT_REMOVEDIR : 0) < 0) {
- bb_perror_msg("can't remove '%s'", fileName);
+ bb_perror_msg("can't remove '%s'", state->fileName);
return FALSE;
}
if (flags & FILEUTILS_VERBOSE) {
- printf("removed %s'%s'\n", isdir ? "directory: " : "", fileName);
+ printf("removed %s'%s'\n", isdir ? "directory: " : "", state->fileName);
}
return TRUE;
diff --git a/modutils/depmod.c b/modutils/depmod.c
index bb42bbefe..4118dc215 100644
--- a/modutils/depmod.c
+++ b/modutils/depmod.c
@@ -33,7 +33,6 @@
*/
static int FAST_FUNC parse_module(struct recursive_state *state,
- const char *fname,
struct stat *sb UNUSED_PARAM)
{
module_db *modules = state->userData;
@@ -43,13 +42,13 @@ static int FAST_FUNC parse_module(struct recursive_state *state,
/* Arbitrary. Was sb->st_size, but that breaks .gz etc */
size_t len = (64*1024*1024 - 4096);
- if (strrstr(fname, ".ko") == NULL)
+ if (strrstr(state->fileName, ".ko") == NULL)
return TRUE;
- image = xmalloc_open_zipped_read_close(fname, &len);
+ image = xmalloc_open_zipped_read_close(state->fileName, &len);
- e = moddb_get_or_create(modules, bb_get_last_path_component_nostrip(fname));
- e->name = xstrdup(fname + 2); /* skip "./" */
+ e = moddb_get_or_create(modules, bb_get_last_path_component_nostrip(state->fileName));
+ e->name = xstrdup(state->fileName + 2); /* skip "./" */
for (ptr = image; ptr < image + len - 10; ptr++) {
if (is_prefixed_with(ptr, "depends=")) {
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c
index 31a215a29..2928985d0 100644
--- a/modutils/modprobe-small.c
+++ b/modutils/modprobe-small.c
@@ -379,7 +379,6 @@ static int parse_module(module_info *info, const char *pathname)
}
static FAST_FUNC int fileAction(struct recursive_state *state,
- const char *pathname,
struct stat *sb UNUSED_PARAM)
{
const char *modname_to_match = state->userData;
@@ -388,7 +387,7 @@ static FAST_FUNC int fileAction(struct recursive_state *state,
bool is_remove = (ENABLE_RMMOD && ONLY_APPLET)
|| ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r));
- pathname += 2; /* skip "./" */
+ char *pathname = state->fileName + 2; /* skip "./" */
fname = bb_get_last_path_component_nostrip(pathname);
if (!strrstr(fname, ".ko")) {
dbg1_error_msg("'%s' is not a module", pathname);
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index f890abe53..f9cec8241 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -236,7 +236,6 @@ static void add_probe(const char *name)
}
static int FAST_FUNC config_file_action(struct recursive_state *state,
- const char *filename,
struct stat *statbuf UNUSED_PARAM)
{
char *tokens[3];
@@ -246,7 +245,7 @@ static int FAST_FUNC config_file_action(struct recursive_state *state,
const char *base;
/* Skip files that begin with a "." */
- base = bb_basename(filename);
+ base = bb_basename(state->fileName);
if (base[0] == '.')
goto error;
@@ -268,7 +267,7 @@ static int FAST_FUNC config_file_action(struct recursive_state *state,
goto error;
}
- p = config_open2(filename, fopen_for_read);
+ p = config_open2(state->fileName, fopen_for_read);
if (p == NULL) {
rc = FALSE;
goto error;
diff --git a/networking/netstat.c b/networking/netstat.c
index 807800a62..f6dbff1ca 100644
--- a/networking/netstat.c
+++ b/networking/netstat.c
@@ -273,13 +273,12 @@ static long extract_socket_inode(const char *lname)
}
static int FAST_FUNC add_to_prg_cache_if_socket(struct recursive_state *state,
- const char *fileName,
struct stat *statbuf UNUSED_PARAM)
{
char *linkname;
long inode;
- linkname = xmalloc_readlink(fileName);
+ linkname = xmalloc_readlink(state->fileName);
if (linkname != NULL) {
inode = extract_socket_inode(linkname);
free(linkname);
@@ -292,7 +291,6 @@ static int FAST_FUNC add_to_prg_cache_if_socket(struct recursive_state *state,
}
static int FAST_FUNC dir_act(struct recursive_state *state,
- const char *fileName,
struct stat *statbuf UNUSED_PARAM)
{
const char *pid;
@@ -304,11 +302,11 @@ static int FAST_FUNC dir_act(struct recursive_state *state,
if (state->depth == 0) /* "/proc" itself */
return TRUE; /* continue looking one level below /proc */
- pid = fileName + sizeof("/proc/")-1; /* point after "/proc/" */
+ pid = state->fileName + sizeof("/proc/")-1; /* point after "/proc/" */
if (!isdigit(pid[0])) /* skip /proc entries which aren't processes */
return SKIP;
- len = snprintf(proc_pid_fname, sizeof(proc_pid_fname), "%s/cmdline", fileName);
+ len = snprintf(proc_pid_fname, sizeof(proc_pid_fname), "%s/cmdline", state->fileName);
n = open_read_close(proc_pid_fname, cmdline_buf, sizeof(cmdline_buf) - 1);
if (n < 0)
return FALSE;
diff --git a/selinux/chcon.c b/selinux/chcon.c
index e1778a36a..39b362847 100644
--- a/selinux/chcon.c
+++ b/selinux/chcon.c
@@ -63,7 +63,6 @@ static char *range = NULL;
static char *specified_context = NULL;
static int FAST_FUNC change_filedir_context(struct recursive_state *state UNUSED_PARAM,
- const char *fname,
struct stat *stbuf UNUSED_PARAM)
{
context_t context = NULL;
@@ -73,18 +72,18 @@ static int FAST_FUNC change_filedir_context(struct recursive_state *state UNUSED
int status = 0;
if (option_mask32 & OPT_NODEREFERENCE) {
- status = lgetfilecon(fname, &file_context);
+ status = lgetfilecon(state->fileName, &file_context);
} else {
- status = getfilecon(fname, &file_context);
+ status = getfilecon(state->fileName, &file_context);
}
if (status < 0 && errno != ENODATA) {
if ((option_mask32 & OPT_QUIET) == 0)
- bb_error_msg("can't obtain security context: %s", fname);
+ bb_error_msg("can't obtain security context: %s", state->fileName);
goto skip;
}
if (file_context == NULL && specified_context == NULL) {
- bb_error_msg("can't apply partial context to unlabeled file %s", fname);
+ bb_error_msg("can't apply partial context to unlabeled file %s", state->fileName);
goto skip;
}
@@ -113,25 +112,25 @@ static int FAST_FUNC change_filedir_context(struct recursive_state *state UNUSED
int fail;
if (option_mask32 & OPT_NODEREFERENCE) {
- fail = lsetfilecon(fname, context_string);
+ fail = lsetfilecon(state->fileName, context_string);
} else {
- fail = setfilecon(fname, context_string);
+ fail = setfilecon(state->fileName, context_string);
}
if ((option_mask32 & OPT_VERBOSE) || ((option_mask32 & OPT_CHANHES) && !fail)) {
printf(!fail
? "context of %s changed to %s\n"
: "can't change context of %s to %s\n",
- fname, context_string);
+ state->fileName, context_string);
}
if (!fail) {
rc = TRUE;
} else if ((option_mask32 & OPT_QUIET) == 0) {
bb_error_msg("can't change context of %s to %s",
- fname, context_string);
+ state->fileName, context_string);
}
} else {
if (option_mask32 & OPT_VERBOSE) {
- printf("context of %s retained as %s\n", fname, context_string);
+ printf("context of %s retained as %s\n", state->fileName, context_string);
}
rc = TRUE;
}
diff --git a/selinux/setfiles.c b/selinux/setfiles.c
index 70e68a666..a43e06bfd 100644
--- a/selinux/setfiles.c
+++ b/selinux/setfiles.c
@@ -463,8 +463,7 @@ static int restore(const char *file)
* This function is called by recursive_action on each file during
* the directory traversal.
*/
-static int FAST_FUNC apply_spec(struct recursive_state *state UNUSED_PARAM,
- const char *file,
+static int FAST_FUNC apply_spec(struct recursive_state *state,
struct stat *sb)
{
if (!follow_mounts) {
@@ -473,7 +472,7 @@ static int FAST_FUNC apply_spec(struct recursive_state *state UNUSED_PARAM,
return SKIP;
}
}
- errors |= restore(file);
+ errors |= restore(state->file);
if (abort_on_error && errors)
return FALSE;
return TRUE;
diff --git a/util-linux/lspci.c b/util-linux/lspci.c
index 25be23a01..cc8d677bf 100644
--- a/util-linux/lspci.c
+++ b/util-linux/lspci.c
@@ -37,8 +37,7 @@ enum {
/*
* PCI_SLOT_NAME PCI_CLASS: PCI_VID:PCI_DID [PCI_SUBSYS_VID:PCI_SUBSYS_DID] [DRIVER]
*/
-static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
- const char *fileName,
+static int FAST_FUNC fileAction(struct recursive_state *state,
struct stat *statbuf UNUSED_PARAM)
{
parser_t *parser;
@@ -47,7 +46,7 @@ static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
int pci_class = 0, pci_vid = 0, pci_did = 0;
int pci_subsys_vid = 0, pci_subsys_did = 0;
- char *uevent_filename = concat_path_file(fileName, "uevent");
+ char *uevent_filename = concat_path_file(state->fileName, "uevent");
parser = config_open2(uevent_filename, fopen_for_read);
free(uevent_filename);
diff --git a/util-linux/lsusb.c b/util-linux/lsusb.c
index f7d0de32d..f5823c17d 100644
--- a/util-linux/lsusb.c
+++ b/util-linux/lsusb.c
@@ -42,15 +42,14 @@ static char * FAST_FUNC add_sysfs_prop(const char *dir, const char *suffix,
return trim(buf);
}
-static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
- const char *fileName,
+static int FAST_FUNC fileAction(struct recursive_state *state,
struct stat *statbuf UNUSED_PARAM)
{
parser_t *parser;
char *tokens[4];
char *busnum = NULL, *devnum = NULL;
int product_vid = 0, product_did = 0;
- char *uevent_filename = concat_path_file(fileName, "uevent");
+ char *uevent_filename = concat_path_file(state->fileName, "uevent");
parser = config_open2(uevent_filename, fopen_for_read);
free(uevent_filename);
@@ -81,10 +80,10 @@ static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
if (busnum) {
char name[256], *p;
- p = add_sysfs_prop(fileName, "/manufacturer", name, sizeof(name) - 1);
+ p = add_sysfs_prop(state->fileName, "/manufacturer", name, sizeof(name) - 1);
if (p != name)
p = stpcpy(p, " ");
- add_sysfs_prop(fileName, "/product", p, name + sizeof(name) - p);
+ add_sysfs_prop(state->fileName, "/product", p, name + sizeof(name) - p);
printf("Bus %s Device %s: ID %04x:%04x %s\n", busnum, devnum,
product_vid, product_did, name);
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index e98d46743..230f6b133 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -845,19 +845,18 @@ static ssize_t readlink2(char *buf, size_t bufsize)
* We act only on "/sys/.../dev" (pseudo)file
*/
static int FAST_FUNC fileAction(struct recursive_state *state,
- const char *fileName,
struct stat *statbuf UNUSED_PARAM)
{
- size_t len = strlen(fileName) - 4; /* can't underflow */
+ size_t len = strlen(state->fileName) - 4; /* can't underflow */
char *path = state->userData; /* char array[PATH_MAX + SCRATCH_SIZE] */
char subsys[PATH_MAX];
int res;
/* Is it a ".../dev" file? (len check is for paranoid reasons) */
- if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX - 32)
+ if (strcmp(state->fileName + len, "/dev") != 0 || len >= PATH_MAX - 32)
return FALSE; /* not .../dev */
- strcpy(path, fileName);
+ strcpy(path, state->fileName);
path[len] = '\0';
/* Read ".../subsystem" symlink in the same directory where ".../dev" is */
@@ -887,7 +886,6 @@ static int FAST_FUNC fileAction(struct recursive_state *state,
/* Directory callback for /sys/ traversal */
static int FAST_FUNC dirAction(struct recursive_state *state,
- const char *fileName UNUSED_PARAM,
struct stat *statbuf UNUSED_PARAM)
{
return (state->depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c
index 00cfb2826..4a227781e 100644
--- a/util-linux/volume_id/get_devname.c
+++ b/util-linux/volume_id/get_devname.c
@@ -102,14 +102,13 @@ uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *uu
* add a cache entry for this device.
* If device node does not exist, it will be temporarily created. */
static int FAST_FUNC
-uuidcache_check_device(struct recursive_state *state UNUSED_PARAM,
- const char *device,
+uuidcache_check_device(struct recursive_state *state,
struct stat *statbuf)
{
/* note: this check rejects links to devices, among other nodes */
if (!S_ISBLK(statbuf->st_mode)
#if ENABLE_FEATURE_VOLUMEID_UBIFS
- && !(S_ISCHR(statbuf->st_mode) && strncmp(bb_basename(device), "ubi", 3) == 0)
+ && !(S_ISCHR(statbuf->st_mode) && strncmp(bb_basename(state->fileName), "ubi", 3) == 0)
#endif
)
return TRUE;
@@ -122,7 +121,7 @@ uuidcache_check_device(struct recursive_state *state UNUSED_PARAM,
if (major(statbuf->st_rdev) == 2)
return TRUE;
- add_to_uuid_cache(device);
+ add_to_uuid_cache(state->fileName);
return TRUE;
}
--
2.52.0
_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox