SSL realpath.c
Interaktion und PortierbarkeitC
// SPDX-License-Identifier: GPL-2.0
/*
* security / tomoyo / realpath . c
*
* Copyright ( C ) 2005 - 2011 NTT DATA CORPORATION
*/
#include "common.h"
#include <linux/magic.h>
#include <linux/proc_fs.h>
/**
* tomoyo_encode2 - Encode binary string to ascii string .
*
* @ str : String in binary format .
* @ str_len : Size of @ str in byte .
*
* Returns pointer to @ str in ascii format on success , NULL otherwise .
*
* This function uses kzalloc ( ) , so caller must kfree ( ) if this function
* didn ' t return NULL .
*/
char *tomoyo_encode2(const char *str, int str_len)
{
int i;
int len = 0 ;
const char *p = str;
char *cp;
char *cp0;
if (!p)
return NULL;
for (i = 0 ; i < str_len; i++) {
const unsigned char c = p[i];
if (c == '\\' )
len += 2 ;
else if (c > ' ' && c < 127 )
len++;
else
len += 4 ;
}
len++;
/* Reserve space for appending "/". */
cp = kzalloc(len + 10 , GFP_NOFS);
if (!cp)
return NULL;
cp0 = cp;
p = str;
for (i = 0 ; i < str_len; i++) {
const unsigned char c = p[i];
if (c == '\\' ) {
*cp++ = '\\' ;
*cp++ = '\\' ;
} else if (c > ' ' && c < 127 ) {
*cp++ = c;
} else {
*cp++ = '\\' ;
*cp++ = (c >> 6 ) + '0' ;
*cp++ = ((c >> 3 ) & 7 ) + '0' ;
*cp++ = (c & 7 ) + '0' ;
}
}
return cp0;
}
/**
* tomoyo_encode - Encode binary string to ascii string .
*
* @ str : String in binary format .
*
* Returns pointer to @ str in ascii format on success , NULL otherwise .
*
* This function uses kzalloc ( ) , so caller must kfree ( ) if this function
* didn ' t return NULL .
*/
char *tomoyo_encode(const char *str)
{
return str ? tomoyo_encode2(str, strlen(str)) : NULL;
}
/**
* tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot ' ed root .
*
* @ path : Pointer to " struct path " .
* @ buffer : Pointer to buffer to return value in .
* @ buflen : Sizeof @ buffer .
*
* Returns the buffer on success , an error code otherwise .
*
* If dentry is a directory , trailing ' / ' is appended .
*/
static char *tomoyo_get_absolute_path(const struct path *path, char * const buffer,
const int buflen)
{
char *pos = ERR_PTR(-ENOMEM);
if (buflen >= 256 ) {
/* go to whatever namespace root we are under */
pos = d_absolute_path(path, buffer, buflen - 1 );
if (!IS_ERR(pos) && *pos == '/' && pos[1 ]) {
struct inode *inode = d_backing_inode(path->dentry);
if (inode && S_ISDIR(inode->i_mode)) {
buffer[buflen - 2 ] = '/' ;
buffer[buflen - 1 ] = '\0' ;
}
}
}
return pos;
}
/**
* tomoyo_get_dentry_path - Get the path of a dentry .
*
* @ dentry : Pointer to " struct dentry " .
* @ buffer : Pointer to buffer to return value in .
* @ buflen : Sizeof @ buffer .
*
* Returns the buffer on success , an error code otherwise .
*
* If dentry is a directory , trailing ' / ' is appended .
*/
static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer,
const int buflen)
{
char *pos = ERR_PTR(-ENOMEM);
if (buflen >= 256 ) {
pos = dentry_path_raw(dentry, buffer, buflen - 1 );
if (!IS_ERR(pos) && *pos == '/' && pos[1 ]) {
struct inode *inode = d_backing_inode(dentry);
if (inode && S_ISDIR(inode->i_mode)) {
buffer[buflen - 2 ] = '/' ;
buffer[buflen - 1 ] = '\0' ;
}
}
}
return pos;
}
/**
* tomoyo_get_local_path - Get the path of a dentry .
*
* @ dentry : Pointer to " struct dentry " .
* @ buffer : Pointer to buffer to return value in .
* @ buflen : Sizeof @ buffer .
*
* Returns the buffer on success , an error code otherwise .
*/
static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer,
const int buflen)
{
struct super_block *sb = dentry->d_sb;
char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen);
if (IS_ERR(pos))
return pos;
/* Convert from $PID to self if $PID is current thread. */
if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/' ) {
char *ep;
const pid_t pid = (pid_t) simple_strtoul(pos + 1 , &ep, 10 );
struct pid_namespace *proc_pidns = proc_pid_ns(sb);
if (*ep == '/' && pid && pid ==
task_tgid_nr_ns(current, proc_pidns)) {
pos = ep - 5 ;
if (pos < buffer)
goto out;
memmove(pos, "/self" , 5 );
}
goto prepend_filesystem_name;
}
/* Use filesystem name for unnamed devices. */
if (!MAJOR(sb->s_dev))
goto prepend_filesystem_name;
{
struct inode *inode = d_backing_inode(sb->s_root);
/*
* Use filesystem name if filesystem does not support rename ( )
* operation .
*/
if (!inode->i_op->rename)
goto prepend_filesystem_name;
}
/* Prepend device name. */
{
char name[64 ];
int name_len;
const dev_t dev = sb->s_dev;
name[sizeof (name) - 1 ] = '\0' ;
snprintf(name, sizeof (name) - 1 , "dev(%u,%u):" , MAJOR(dev),
MINOR(dev));
name_len = strlen(name);
pos -= name_len;
if (pos < buffer)
goto out;
memmove(pos, name, name_len);
return pos;
}
/* Prepend filesystem name. */
prepend_filesystem_name:
{
const char *name = sb->s_type->name;
const int name_len = strlen(name);
pos -= name_len + 1 ;
if (pos < buffer)
goto out;
memmove(pos, name, name_len);
pos[name_len] = ':' ;
}
return pos;
out:
return ERR_PTR(-ENOMEM);
}
/**
* tomoyo_realpath_from_path - Returns realpath ( 3 ) of the given pathname but ignores chroot ' ed root .
*
* @ path : Pointer to " struct path " .
*
* Returns the realpath of the given @ path on success , NULL otherwise .
*
* If dentry is a directory , trailing ' / ' is appended .
* Characters out of 0 x20 < c < 0 x7F range are converted to
* \ ooo style octal string .
* Character \ is converted to \ \ string .
*
* These functions use kzalloc ( ) , so the caller must call kfree ( )
* if these functions didn ' t return NULL .
*/
char *tomoyo_realpath_from_path(const struct path *path)
{
char *buf = NULL;
char *name = NULL;
unsigned int buf_len = PAGE_SIZE / 2 ;
struct dentry *dentry = path->dentry;
struct super_block *sb = dentry->d_sb;
while (1 ) {
char *pos;
struct inode *inode;
buf_len <<= 1 ;
kfree(buf);
buf = kmalloc(buf_len, GFP_NOFS);
if (!buf)
break ;
/* To make sure that pos is '\0' terminated. */
buf[buf_len - 1 ] = '\0' ;
/* For "pipe:[\$]" and "socket:[\$]". */
if (dentry->d_op && dentry->d_op->d_dname) {
pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1 );
goto encode;
}
inode = d_backing_inode(sb->s_root);
/*
* Get local name for filesystems without rename ( ) operation
*/
if ((!inode->i_op->rename &&
!(sb->s_type->fs_flags & FS_REQUIRES_DEV)))
pos = tomoyo_get_local_path(path->dentry, buf,
buf_len - 1 );
/* Get absolute name for the rest. */
else {
pos = tomoyo_get_absolute_path(path, buf, buf_len - 1 );
/*
* Fall back to local name if absolute name is not
* available .
*/
if (pos == ERR_PTR(-EINVAL))
pos = tomoyo_get_local_path(path->dentry, buf,
buf_len - 1 );
}
encode:
if (IS_ERR(pos))
continue ;
name = tomoyo_encode(pos);
break ;
}
kfree(buf);
if (!name)
tomoyo_warn_oom(__func__);
return name;
}
/**
* tomoyo_realpath_nofollow - Get realpath of a pathname .
*
* @ pathname : The pathname to solve .
*
* Returns the realpath of @ pathname on success , NULL otherwise .
*/
char *tomoyo_realpath_nofollow(const char *pathname)
{
struct path path;
if (pathname && kern_path(pathname, 0 , &path) == 0 ) {
char *buf = tomoyo_realpath_from_path(&path);
path_put(&path);
return buf;
}
return NULL;
}
Messung V0.5 in Prozent C=94 H=86 G=89
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.14Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-29)
¤
*Eine klare Vorstellung vom Zielzustand
2026-10-10
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1126438
#Domains=1897691