/* * /proc/self: */ static int proc_self_readlink(struct dentry *dentry, char __user *buffer, int buflen) { struct pid_namespace *ns = dentry->d_sb->s_fs_info; pid_t tgid = task_tgid_nr_ns(current, ns); char tmp[PROC_NUMBUF]; if (!tgid) return -ENOENT; sprintf(tmp, "%d", tgid); return readlink_copy(buffer, buflen, tmp); }
int xfs_readlink_by_handle( struct file *parfilp, xfs_fsop_handlereq_t *hreq) { struct dentry *dentry; __u32 olen; void *link; int error; if (!capable(CAP_SYS_ADMIN)) return -EPERM; dentry = xfs_handlereq_to_dentry(parfilp, hreq); if (IS_ERR(dentry)) return PTR_ERR(dentry); /* Restrict this handle operation to symlinks only. */ if (!d_is_symlink(dentry)) { error = -EINVAL; goto out_dput; } if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) { error = -EFAULT; goto out_dput; } link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); if (!link) { error = -ENOMEM; goto out_dput; } error = xfs_readlink(XFS_I(d_inode(dentry)), link); if (error) goto out_kfree; error = readlink_copy(hreq->ohandle, olen, link); if (error) goto out_kfree; out_kfree: kfree(link); out_dput: dput(dentry); return error; }
static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int buflen) { struct inode *inode = d_inode(dentry); const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; struct task_struct *task; char name[50]; int res = -EACCES; task = get_proc_task(inode); if (!task) return res; if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) { res = ns_get_name(name, sizeof(name), task, ns_ops); if (res >= 0) res = readlink_copy(buffer, buflen, name); } put_task_struct(task); return res; }