shell bypass 403

Cubjrnet7 Shell


name : thread_safe_path.h
/**
@file    thread_safe_path.h
@brief	 Thread safe accessor to the 'struct path'
@details Copyright (c) 2022 Acronis International GmbH
@author  Denis Kopyrin ([email protected])
@since   $Id: $
*/

#pragma once

#include <linux/path.h>
#include <linux/spinlock.h>
#include <linux/types.h>	// bool, [u]int(8|16|32|64)_t, pid_t, size_t

// This structure is made to avoid the limitations of 'struct path'
// It is only allowed to call 'path_put' and 'path_get' in the same
// thread.
// With this limitation it is not allowed to just use ref counting
// and there must be an explicit 'path_put' from the same thread
// that had 'struct path' created.

typedef struct {
	spinlock_t spinlock;
	struct path path;
} thread_safe_path_t;

static inline
void thread_safe_path_init(thread_safe_path_t *sp)
{
	spin_lock_init(&sp->spinlock);
	sp->path = (struct path){};
}

// No 'deinit', caller must explicitly invoke 'thread_safe_path_clear' as 'thread_safe_path_store_*'

// Performs 'move' semantic and write directly to the 'path' assuming it is empty currently
static inline
void thread_safe_path_store_move_directly(thread_safe_path_t *sp, struct path *newpath)
{
	spin_lock(&sp->spinlock);
	sp->path = *newpath;
	*newpath = (struct path){};
	spin_unlock(&sp->spinlock);
}

// Same as method above but uses 'copy' semantics instead
static inline
void thread_safe_path_store_copy_directly(thread_safe_path_t *sp, const struct path *newpath)
{
	spin_lock(&sp->spinlock);
	sp->path = *newpath;
	path_get(&sp->path);
	spin_unlock(&sp->spinlock);
}

// Clears the path stored, must be called from the same thread as 'thread_safe_path_store_*'
static inline
void thread_safe_path_clear(thread_safe_path_t *sp)
{
	struct path cleared_path;
	spin_lock(&sp->spinlock);
	cleared_path = sp->path;
	sp->path = (struct path){};
	spin_unlock(&sp->spinlock);

	// 'path_put' might sleep, do NOT call inside the 'spin_lock'
	path_put(&cleared_path);
}

// Loads the path from 'thread_safe_path'. Must be 'path_put' after use in the same thread.
static inline
void thread_safe_path_load(thread_safe_path_t *sp, struct path *to)
{
	spin_lock(&sp->spinlock);
	*to = sp->path;
	// 'path_get' can be safely called under the 'spin_lock'.
	// It is the only place where 'path_get' can be reliable get
	path_get(to);
	spin_unlock(&sp->spinlock);
}

© 2025 Cubjrnet7