shell bypass 403

Cubjrnet7 Shell

: /usr/src/file_protector-1.1-1538/ [ drwxr-xr-x ]

name : module_rundown_protection.c
/**
 @file     module_rundown_protection.c
 @brief    Global module rundown protection used for safe syscalls handling
 @details  Copyright (c) 2022 Acronis International GmbH
 @author   Denis Kopyrin ([email protected])
 @since    $Id: $
 */

#include "module_rundown_protection.h"

#include "rundown_protection.h"

#include "module_ref.h"

#include <linux/module.h>
#include <linux/spinlock.h>

typedef struct {
	rundown_protection_t rundown_protection;

	// 'spinlock' protects flags below
	spinlock_t spinlock;
	bool active;
	bool referenced;
} mod_rundown_protection_t;
static mod_rundown_protection_t mod_rundown_protection;

static void mod_rundown_protection_finalizer(void *ctx) {
	bool active, referenced;
	mod_rundown_protection_t *mrp = (mod_rundown_protection_t*) ctx;

	IPRINTF("");
	spin_lock(&mrp->spinlock);
	active = mrp->active;
	referenced = mrp->referenced;
	if (!active) {
		mrp->referenced = false;
	}
	spin_unlock(&mrp->spinlock);

	IPRINTF("active=%d, referenced=%d", active, referenced);
	if (active) {
		IPRINTF("mod is currently active, doing nothing and considering finalizer spurious");
		return;
	}

	if (referenced) {
		MODULE_PUT();
	} else {
		IPRINTF("module is not referenced already");
	}
}

void __init mod_rundown_protection_init(bool ready) {
	rundown_protection_init(&mod_rundown_protection.rundown_protection, mod_rundown_protection_finalizer, &mod_rundown_protection, ready);
	spin_lock_init(&mod_rundown_protection.spinlock);
	mod_rundown_protection.referenced = false;
	mod_rundown_protection.active = false;
}

bool mod_rundown_protection_lock(void) {
	return rundown_protection_lock(&mod_rundown_protection.rundown_protection);
}

void mod_rundown_protection_unlock(void) {
	return rundown_protection_unlock(&mod_rundown_protection.rundown_protection);
}

void mod_rundown_protection_set_rundown_active(void) {
	int64_t pending_count = 0;
	bool need_unreference = false;

	IPRINTF("");
	// Notice that during 'set_rundown_active' spurious finalizer might be called
	rundown_protection_set_rundown_active(&mod_rundown_protection.rundown_protection);

	// Because 'mod_rundown_protection.active=false' is set after 'set_rundown_active' is done, finalizer might be missed.
	// In this case, we might have to unreference from here too if 'get_pending_count' is 0.
	spin_lock(&mod_rundown_protection.spinlock);
	mod_rundown_protection.active = false;
	pending_count = rundown_protection_get_pending_count(&mod_rundown_protection.rundown_protection);
	if (0 == pending_count) {
		need_unreference = mod_rundown_protection.referenced;
		mod_rundown_protection.referenced = false;
	}
	spin_unlock(&mod_rundown_protection.spinlock);

	IPRINTF("pending_count=%lld need_unreference=%d", pending_count, need_unreference);
	if (need_unreference) {
		MODULE_PUT();
	}
}

void mod_rundown_protection_wait_for_rundown(void) {
	return rundown_protection_wait_for_rundown(&mod_rundown_protection.rundown_protection);
}

bool mod_rundown_protection_wait_for_rundown_timeout(unsigned long timeout_jiffies) {
	return rundown_protection_wait_for_rundown_timeout(&mod_rundown_protection.rundown_protection, timeout_jiffies);
}

void mod_rundown_protection_set_ready(void) {
	bool module_was_already_referenced;

	IPRINTF("");
	MODULE_GET();

	spin_lock(&mod_rundown_protection.spinlock);
	mod_rundown_protection.active = true;
	module_was_already_referenced = mod_rundown_protection.referenced;
	mod_rundown_protection.referenced = true;
	spin_unlock(&mod_rundown_protection.spinlock);

	rundown_protection_set_ready(&mod_rundown_protection.rundown_protection);

	IPRINTF("module_was_already_referenced=%d", module_was_already_referenced);
	if (module_was_already_referenced) {
		MODULE_PUT();
	}
}

© 2025 Cubjrnet7