/** * 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(constchar *str, int str_len)
{ int i; int len = 0; constchar *p = str; char *cp; char *cp0;
if (!p) return NULL; for (i = 0; i < str_len; i++) { constunsignedchar c = p[i];
if (c == '\\')
len += 2; elseif (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++) { constunsignedchar c = p[i];
/** * 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(constchar *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.
*/ staticchar *tomoyo_get_absolute_path(conststruct path *path, char * const buffer, constint 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);
/** * 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.
*/ staticchar *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer, constint buflen)
{ char *pos = ERR_PTR(-ENOMEM);
/** * 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.
*/ staticchar *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, constint 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;
/** * 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 0x20 < c < 0x7F 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(conststruct path *path)
{ char *buf = NULL; char *name = NULL; unsignedint 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(constchar *pathname)
{ struct path path;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.