← Commit list

96b060730

Denys Vlasenko
Denys Vlasenko
2024-10-07
SUCCESS Duration: 155s

Subject

ash: cache more of uid/gid syscalls

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

coreutils/test.c+7 -4
@@ -638,7 +638,7 @@ static int binop(void)
static int is_a_group_member(gid_t gid)
{
/* Short-circuit if possible, maybe saving a call to getgroups(). */
- if (gid == getgid() || gid == getegid())
+ if (gid == get_cached_egid(&groupinfo->egid))
return 1;
return is_in_supplementary_groups(groupinfo, gid);
@@ -656,15 +656,16 @@ static int test_st_mode(struct stat *st, int mode)
//TODO if (mode == X_OK) {
// /* Do we already know with no extra syscalls? */
-// if (!S_ISREG(st->st_mode))
-// return 0; /* not a regular file */
+// //if (!S_ISREG(st->st_mode))
+// // return 0; /* not a regular file */
+// // ^^^ bash does not check this
// if ((st->st_mode & ANY_IX) == 0)
// return 0; /* no one can execute */
// if ((st->st_mode & ANY_IX) == ANY_IX)
// return 1; /* anyone can execute */
// }
- euid = geteuid();
+ euid = get_cached_euid(&groupinfo->euid);
if (euid == 0) {
/* Root can read or write any file. */
if (mode != X_OK)
@@ -1019,6 +1020,8 @@ int test_main(int argc, char **argv)
struct cached_groupinfo info;
int r;
+ info.euid = -1;
+ info.egid = -1;
info.ngroups = 0;
info.supplementary_array = NULL;
r = test_main2(&info, argc, argv);
include/libbb.h+4 -2
@@ -1206,11 +1206,13 @@ gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC;
* getgroups() is cached in supplementary_array[], to make successive calls faster.
*/
struct cached_groupinfo {
- //TODO? gid_t egid;
+ uid_t euid;
+ gid_t egid;
int ngroups;
gid_t *supplementary_array;
};
-//TODO? int FAST_FUNC get_cached_egid(gid_t *egid);
+uid_t FAST_FUNC get_cached_euid(uid_t *euid);
+gid_t FAST_FUNC get_cached_egid(gid_t *egid);
int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid);
#if ENABLE_FEATURE_UTMP
libbb/bb_getgroups.c+14 -0
@@ -46,6 +46,20 @@ gid_t* FAST_FUNC bb_getgroups(int *ngroups, gid_t *group_array)
return group_array;
}
+uid_t FAST_FUNC get_cached_euid(uid_t *euid)
+{
+ if (*euid == (uid_t)-1)
+ *euid = geteuid();
+ return *euid;
+}
+
+gid_t FAST_FUNC get_cached_egid(gid_t *egid)
+{
+ if (*egid == (gid_t)-1)
+ *egid = getegid();
+ return *egid;
+}
+
/* Return non-zero if GID is in our supplementary group list. */
int FAST_FUNC is_in_supplementary_groups(struct cached_groupinfo *groupinfo, gid_t gid)
{
shell/ash.c+5 -4
@@ -536,6 +536,8 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
curdir = nullstr; \
physdir = nullstr; \
trap_ptr = trap; \
+ groupinfo.euid = -1; \
+ groupinfo.egid = -1; \
} while (0)
@@ -2319,7 +2321,7 @@ initvar(void)
#if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
vps1.var_text = "PS1=\\w \\$ ";
#else
- if (!geteuid())
+ if (!get_cached_euid(&groupinfo.euid));
vps1.var_text = "PS1=# ";
#endif
vp = varinit;
@@ -13809,14 +13811,13 @@ static int test_exec(/*const char *fullname,*/ struct stat *statb)
/* Executability depends on our euid/egid/supplementary groups */
stmode = S_IXOTH;
- euid = geteuid();
-//TODO: cache euid?
+ euid = get_cached_euid(&groupinfo.euid);
if (euid == 0)
/* for root user, any X bit is good enough */
stmode = ANY_IX;
else if (statb->st_uid == euid)
stmode = S_IXUSR;
- else if (statb->st_gid == getegid())
+ else if (statb->st_gid == get_cached_egid(&groupinfo.egid))
stmode = S_IXGRP;
else if (is_in_supplementary_groups(&groupinfo, statb->st_gid))
stmode = S_IXGRP;