コード例 #1
0
void *prlfs_get_path(struct dentry *dentry, void *buf, int *plen)
{
	int len;
	char *p;

	DPRINTK("ENTER\n");
	len = *plen;
	p = buf;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
	if ((dentry->d_name.len > NAME_MAX) || (len < 2)) {
		p = ERR_PTR(-ENAMETOOLONG);
		goto out;
	}
	p += --len;
	*p = '\0';
	spin_lock(&dcache_lock);
	while (!IS_ROOT(dentry)) {
		int nlen;
		struct dentry *parent;

                parent = dentry->d_parent;
		prefetch(parent);
		nlen = dentry->d_name.len;
		if (len < nlen + 1) {
			p = ERR_PTR(-ENAMETOOLONG);
			goto out_lock;
		}
		len -= nlen + 1;
		p -= nlen;
		memcpy(p, dentry->d_name.name, nlen);
		*(--p) = '/';
		dentry = parent;
	}
	if (*p != '/') {
		*(--p) = '/';
		--len;
	}
out_lock:
	spin_unlock(&dcache_lock);
	if (!IS_ERR(p))
		*plen -= len;
out:
#else
	p = dentry_path_raw(dentry, p, len);
	*plen = strnlen(p, PAGE_SIZE-1) + 1;
#endif
	DPRINTK("EXIT returning %p\n", p);
	return p;
}
コード例 #2
0
ファイル: realpath.c プロジェクト: 33d/linux-2.6.21-hh20
/**
 * 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 = dentry->d_inode;
			if (inode && S_ISDIR(inode->i_mode)) {
				buffer[buflen - 2] = '/';
				buffer[buflen - 1] = '\0';
			}
		}
	}
	return pos;
}
コード例 #3
0
ファイル: kWatch.c プロジェクト: himanshujindal/kWatch
/*
 * Function that takes in a file desc
 * And checks recursively if any of its parent
 * is under watch
 * Also takes the int bMap which specifies what changes
 * were made
 */
void process_file_desc(unsigned int fd, int *bMap)
{
    unsigned long parentInodeNo;
    struct file *curFile = NULL;
    char *path = NULL;
    char *path_buf = NULL;

    if (fd < 3) {
        goto OUT;
    }

    curFile = fget(fd);
    if (!curFile) {
        curFile = NULL;
        goto OUT;
    }

    path_buf = kmalloc(_MAX_PATH_LEN_, GFP_KERNEL);
    if (path_buf == NULL) {
        goto OUT;
    }
    path = dentry_path_raw(curFile->f_path.dentry, path_buf,
                           _MAX_PATH_LEN_);
    if (NULL != path) {
        if (path_filter(path)) {
            goto OUT;
        }
    }

    parentInodeNo = check_if_any_parent_is_watched_filp(curFile);
    if (parentInodeNo > 0) {
        add_data_to_obj(parentInodeNo,
                        curFile->f_path.dentry->d_inode->i_ino,
                        bMap);
    }

OUT:
    if (curFile) {
        fput(curFile);
        curFile = NULL;
    }

    if (path_buf) {
        kfree(path_buf);
        path_buf = NULL;
    }
}
コード例 #4
0
ファイル: realpath.c プロジェクト: HONO/Bell_V20f_kernel_mod
/**
 * ccs_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.
 *
 * Based on dentry_path() in fs/dcache.c
 *
 * If dentry is a directory, trailing '/' is appended.
 */
static char *ccs_get_dentry_path(struct dentry *dentry, char * const buffer,
				 const int buflen)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
	char *pos = ERR_PTR(-ENOMEM);
	if (buflen >= 256) {
		/* rename_lock is locked/unlocked by dentry_path_raw(). */
		pos = dentry_path_raw(dentry, buffer, buflen - 1);
		if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
			struct inode *inode = dentry->d_inode;
			if (inode && S_ISDIR(inode->i_mode)) {
				buffer[buflen - 2] = '/';
				buffer[buflen - 1] = '\0';
			}
		}
	}
	return pos;
#else
	char *pos = buffer + buflen - 1;
	if (buflen < 256)
		return ERR_PTR(-ENOMEM);
	*pos = '\0';
	if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
		*--pos = '/';
	spin_lock(&dcache_lock);
	while (!IS_ROOT(dentry)) {
		struct dentry *parent = dentry->d_parent;
		const char *name = dentry->d_name.name;
		const int len = dentry->d_name.len;
		pos -= len;
		if (pos <= buffer) {
			pos = ERR_PTR(-ENOMEM);
			break;
		}
		memmove(pos, name, len);
		*--pos = '/';
		dentry = parent;
	}
	spin_unlock(&dcache_lock);
	return pos;
#endif
}
コード例 #5
0
/**
 * d_namespace_path - lookup a name associated with a given path
 * @path: path to lookup  (NOT NULL)
 * @buf:  buffer to store path to  (NOT NULL)
 * @buflen: length of @buf
 * @name: Returns - pointer for start of path name with in @buf (NOT NULL)
 * @flags: flags controlling path lookup
 *
 * Handle path name lookup.
 *
 * Returns: %0 else error code if path lookup fails
 *          When no error the path name is returned in @name which points to
 *          to a position in @buf
 */
static int d_namespace_path(struct path *path, char *buf, int buflen,
			    char **name, int flags)
{
	char *res;
	int error = 0;
	int connected = 1;

	if (path->mnt->mnt_flags & MNT_INTERNAL) {
		/* it's not mounted anywhere */
		res = dentry_path(path->dentry, buf, buflen);
		*name = res;
		if (IS_ERR(res)) {
			*name = buf;
			return PTR_ERR(res);
		}
		if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
		    strncmp(*name, "/sys/", 5) == 0) {
			/* TODO: convert over to using a per namespace
			 * control instead of hard coded /proc
			 */
			return prepend(name, *name - buf, "/proc", 5);
		}
		return 0;
	}

	/* resolve paths relative to chroot?*/
	if (flags & PATH_CHROOT_REL) {
		struct path root;
		get_fs_root(current->fs, &root);
		res = __d_path(path, &root, buf, buflen);
		path_put(&root);
	} else {
		res = d_absolute_path(path, buf, buflen);
		if (!our_mnt(path->mnt))
			connected = 0;
	}

	/* handle error conditions - and still allow a partial path to
	 * be returned.
	 */
	if (!res || IS_ERR(res)) {
		connected = 0;
		res = dentry_path_raw(path->dentry, buf, buflen);
		if (IS_ERR(res)) {
			error = PTR_ERR(res);
			*name = buf;
			goto out;
		};
	} else if (!our_mnt(path->mnt))
		connected = 0;

	*name = res;

	/* Handle two cases:
	 * 1. A deleted dentry && profile is not allowing mediation of deleted
	 * 2. On some filesystems, newly allocated dentries appear to the
	 *    security_path hooks as a deleted dentry except without an inode
	 *    allocated.
	 */
	if (d_unlinked(path->dentry) && path->dentry->d_inode &&
	    !(flags & PATH_MEDIATE_DELETED)) {
			error = -ENOENT;
			goto out;
	}

	/* If the path is not connected to the expected root,
	 * check if it is a sysctl and handle specially else remove any
	 * leading / that __d_path may have returned.
	 * Unless
	 *     specifically directed to connect the path,
	 * OR
	 *     if in a chroot and doing chroot relative paths and the path
	 *     resolves to the namespace root (would be connected outside
	 *     of chroot) and specifically directed to connect paths to
	 *     namespace root.
	 */
	if (!connected) {
		if (!(flags & PATH_CONNECT_PATH) &&
			   !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
			     our_mnt(path->mnt))) {
			/* disconnected path, don't return pathname starting
			 * with '/'
			 */
			error = -ESTALE;
			if (*res == '/')
				*name = res + 1;
		}
	}

out:
	return error;
}
コード例 #6
0
static int dp_debugfs_init(struct data_path *dp)
{
	char buf[256];
	char path[256];

	dp->dentry = debugfs_create_dir(dp->name ? dp->name : "dp",
		dp_debugfs_root_dir);
	if (!dp->dentry)
		return -ENOMEM;

	snprintf(path, sizeof(path), "../../../%s",
		dentry_path_raw(dp->rbctl->rbdir, buf, sizeof(buf)));

	if (IS_ERR_OR_NULL(debugfs_create_symlink(
				"shm", dp->dentry, path)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_file(
				"tx_q", S_IRUGO, dp->dentry,
				dp, &fops_tx_q)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_file(
				"stat", S_IRUGO, dp->dentry,
				dp, &fops_stat)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_file(
				"wm", S_IRUGO | S_IWUSR, dp->dentry,
				dp, &fops_wm)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_bool(
				"enable_piggyback", S_IRUGO | S_IWUSR,
				dp->dentry, &dp->enable_piggyback)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_bool(
				"is_tx_stopped", S_IRUGO | S_IWUSR,
				dp->dentry, &dp->is_tx_stopped)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_u32(
				"tx_q_max_len", S_IRUGO | S_IWUSR,
				dp->dentry, &dp->tx_q_max_len)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_u16(
				"max_tx_shots", S_IRUGO | S_IWUSR,
				dp->dentry, &dp->max_tx_shots)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_u16(
				"max_rx_shots", S_IRUGO | S_IWUSR,
				dp->dentry, &dp->max_rx_shots)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_u16(
				"tx_sched_delay_in_ms", S_IRUGO | S_IWUSR,
				dp->dentry, &dp->tx_sched_delay_in_ms)))
		goto error;

	if (IS_ERR_OR_NULL(debugfs_create_u16(
				"tx_q_min_sched_len", S_IRUGO | S_IWUSR,
				dp->dentry, &dp->tx_q_min_sched_len)))
		goto error;

	return 0;

error:
	debugfs_remove_recursive(dp->dentry);
	dp->dentry = NULL;
	return -1;
}