Skip to content

Commit 12870f4

Browse files
Copilotprobonopd
andcommitted
Address code review feedback - improve error handling and remove redundancy
Co-authored-by: probonopd <[email protected]>
1 parent c94df8e commit 12870f4

File tree

1 file changed

+40
-47
lines changed

1 file changed

+40
-47
lines changed

src/runtime/runtime.c

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,6 @@ extern int sqfs_opt_proc(void* data, const char* arg, int key, struct fuse_args*
7272

7373
const char* fusermountPath = NULL;
7474

75-
// Capability structures for namespace support
76-
#define _LINUX_CAPABILITY_VERSION_3 0x20080522
77-
78-
struct cap_header {
79-
uint32_t version;
80-
int pid;
81-
};
82-
83-
struct cap_data {
84-
uint32_t effective;
85-
uint32_t permitted;
86-
uint32_t inheritable;
87-
};
88-
8975
typedef struct {
9076
uint32_t lo;
9177
uint32_t hi;
@@ -434,38 +420,47 @@ int appimage_print_binary(char* fname, unsigned long offset, unsigned long lengt
434420
}
435421

436422
// Restore capabilities after entering user namespace
437-
void restore_capabilities(void) {
438-
struct cap_header caps = {
423+
void restore_capabilities(bool verbose) {
424+
struct __user_cap_header_struct caps = {
439425
.version = _LINUX_CAPABILITY_VERSION_3,
440426
.pid = 0
441427
};
442-
struct cap_data cap_data[2] = {{0, 0, 0}, {0, 0, 0}};
428+
struct __user_cap_data_struct cap_data[2] = {{0, 0, 0}, {0, 0, 0}};
443429

444-
if (syscall(SYS_capget, &caps, &cap_data) == 0) {
445-
FILE* f = fopen("/proc/sys/kernel/cap_last_cap", "r");
446-
uint32_t last_cap = 39; // default fallback
447-
if (f != NULL) {
448-
if (fscanf(f, "%u", &last_cap) != 1) {
449-
last_cap = 39;
450-
}
451-
fclose(f);
430+
if (syscall(SYS_capget, &caps, &cap_data) != 0) {
431+
if (verbose) {
432+
fprintf(stderr, "Warning: failed to get capabilities: %s\n", strerror(errno));
452433
}
453-
454-
uint64_t all_caps = (1ULL << (last_cap + 1)) - 1;
455-
cap_data[0].effective = (uint32_t)(all_caps & 0xFFFFFFFF);
456-
cap_data[0].permitted = (uint32_t)(all_caps & 0xFFFFFFFF);
457-
cap_data[0].inheritable = (uint32_t)(all_caps & 0xFFFFFFFF);
458-
cap_data[1].effective = (uint32_t)((all_caps >> 32) & 0xFFFFFFFF);
459-
cap_data[1].permitted = (uint32_t)((all_caps >> 32) & 0xFFFFFFFF);
460-
cap_data[1].inheritable = (uint32_t)((all_caps >> 32) & 0xFFFFFFFF);
461-
462-
syscall(SYS_capset, &caps, &cap_data);
463-
464-
for (uint32_t cap = 0; cap <= last_cap; cap++) {
465-
prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0);
434+
return;
435+
}
436+
437+
FILE* f = fopen("/proc/sys/kernel/cap_last_cap", "r");
438+
uint32_t last_cap = 39; // default fallback
439+
if (f != NULL) {
440+
if (fscanf(f, "%u", &last_cap) != 1) {
441+
last_cap = 39;
466442
}
467-
} else {
468-
fprintf(stderr, "Warning: failed to get capabilities: %s\n", strerror(errno));
443+
fclose(f);
444+
}
445+
446+
uint64_t all_caps = (1ULL << (last_cap + 1)) - 1;
447+
cap_data[0].effective = (uint32_t)(all_caps & 0xFFFFFFFF);
448+
cap_data[0].permitted = (uint32_t)(all_caps & 0xFFFFFFFF);
449+
cap_data[0].inheritable = (uint32_t)(all_caps & 0xFFFFFFFF);
450+
cap_data[1].effective = (uint32_t)((all_caps >> 32) & 0xFFFFFFFF);
451+
cap_data[1].permitted = (uint32_t)((all_caps >> 32) & 0xFFFFFFFF);
452+
cap_data[1].inheritable = (uint32_t)((all_caps >> 32) & 0xFFFFFFFF);
453+
454+
if (syscall(SYS_capset, &caps, &cap_data) != 0) {
455+
if (verbose) {
456+
fprintf(stderr, "Warning: failed to set capabilities: %s\n", strerror(errno));
457+
}
458+
return;
459+
}
460+
461+
for (uint32_t cap = 0; cap <= last_cap; cap++) {
462+
// Ignore failures for individual capabilities as some may not be available
463+
prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0);
469464
}
470465
}
471466

@@ -562,7 +557,7 @@ bool try_unshare(uid_t uid, gid_t gid, const char* unshare_uid, const char* unsh
562557
}
563558
fclose(f);
564559

565-
restore_capabilities();
560+
restore_capabilities(verbose);
566561

567562
if (!try_make_mount_private()) {
568563
fprintf(stderr, "Warning: failed to make mount private: %s\n", strerror(errno));
@@ -711,7 +706,10 @@ bool check_fuse(bool verbose, uid_t uid, gid_t gid, const char* unshare_uid_str,
711706
return true;
712707
}
713708

714-
return true; // Return true anyway to let FUSE try
709+
// Both SUID fusermount and unshare failed, but we still return true
710+
// to let FUSE mounting be attempted (it may work with non-SUID fusermount
711+
// or the user may have other FUSE setup we don't detect)
712+
return true;
715713
}
716714

717715
/* Exit status to use when launching an AppImage fails.
@@ -1960,11 +1958,6 @@ int main(int argc, char* argv[]) {
19601958
exit(EXIT_EXECERROR);
19611959
}
19621960

1963-
// Restore capabilities if we unshared successfully
1964-
if (unshare_succeeded) {
1965-
restore_capabilities();
1966-
}
1967-
19681961
int dir_fd, res;
19691962

19701963
size_t templen = strlen(temp_base);

0 commit comments

Comments
 (0)