diff options
Diffstat (limited to 'arch/um/drivers/mconsole_kern.c')
| -rw-r--r-- | arch/um/drivers/mconsole_kern.c | 49 |
1 files changed, 18 insertions, 31 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 51069245b79a..3b3c36601a7b 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
| @@ -125,50 +125,36 @@ void mconsole_log(struct mc_request *req) | |||
| 125 | void mconsole_proc(struct mc_request *req) | 125 | void mconsole_proc(struct mc_request *req) |
| 126 | { | 126 | { |
| 127 | struct nameidata nd; | 127 | struct nameidata nd; |
| 128 | struct file_system_type *proc; | 128 | struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt; |
| 129 | struct super_block *super; | ||
| 130 | struct file *file; | 129 | struct file *file; |
| 131 | int n, err; | 130 | int n, err; |
| 132 | char *ptr = req->request.data, *buf; | 131 | char *ptr = req->request.data, *buf; |
| 132 | mm_segment_t old_fs = get_fs(); | ||
| 133 | 133 | ||
| 134 | ptr += strlen("proc"); | 134 | ptr += strlen("proc"); |
| 135 | ptr = skip_spaces(ptr); | 135 | ptr = skip_spaces(ptr); |
| 136 | 136 | ||
| 137 | proc = get_fs_type("proc"); | 137 | err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd); |
| 138 | if (proc == NULL) { | 138 | if (err) { |
| 139 | mconsole_reply(req, "procfs not registered", 1, 0); | 139 | mconsole_reply(req, "Failed to look up file", 1, 0); |
| 140 | goto out; | 140 | goto out; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | super = (*proc->get_sb)(proc, 0, NULL, NULL); | 143 | err = may_open(&nd.path, MAY_READ, FMODE_READ); |
| 144 | put_filesystem(proc); | 144 | if (result) { |
| 145 | if (super == NULL) { | 145 | mconsole_reply(req, "Failed to open file", 1, 0); |
| 146 | mconsole_reply(req, "Failed to get procfs superblock", 1, 0); | 146 | path_put(&nd.path); |
| 147 | goto out; | 147 | goto out; |
| 148 | } | 148 | } |
| 149 | up_write(&super->s_umount); | ||
| 150 | |||
| 151 | nd.path.dentry = super->s_root; | ||
| 152 | nd.path.mnt = NULL; | ||
| 153 | nd.flags = O_RDONLY + 1; | ||
| 154 | nd.last_type = LAST_ROOT; | ||
| 155 | |||
| 156 | /* START: it was experienced that the stability problems are closed | ||
| 157 | * if commenting out these two calls + the below read cycle. To | ||
| 158 | * make UML crash again, it was enough to readd either one.*/ | ||
| 159 | err = link_path_walk(ptr, &nd); | ||
| 160 | if (err) { | ||
| 161 | mconsole_reply(req, "Failed to look up file", 1, 0); | ||
| 162 | goto out_kill; | ||
| 163 | } | ||
| 164 | 149 | ||
| 165 | file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, | 150 | file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, |
| 166 | current_cred()); | 151 | current_cred()); |
| 152 | err = PTR_ERR(file); | ||
| 167 | if (IS_ERR(file)) { | 153 | if (IS_ERR(file)) { |
| 168 | mconsole_reply(req, "Failed to open file", 1, 0); | 154 | mconsole_reply(req, "Failed to open file", 1, 0); |
| 169 | goto out_kill; | 155 | path_put(&nd.path); |
| 156 | goto out; | ||
| 170 | } | 157 | } |
| 171 | /*END*/ | ||
| 172 | 158 | ||
| 173 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 159 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 174 | if (buf == NULL) { | 160 | if (buf == NULL) { |
| @@ -176,10 +162,13 @@ void mconsole_proc(struct mc_request *req) | |||
| 176 | goto out_fput; | 162 | goto out_fput; |
| 177 | } | 163 | } |
| 178 | 164 | ||
| 179 | if ((file->f_op != NULL) && (file->f_op->read != NULL)) { | 165 | if (file->f_op->read) { |
| 180 | do { | 166 | do { |
| 181 | n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, | 167 | loff_t pos; |
| 182 | &file->f_pos); | 168 | set_fs(KERNEL_DS); |
| 169 | n = vfs_read(file, buf, PAGE_SIZE - 1, &pos); | ||
| 170 | file_pos_write(file, pos); | ||
| 171 | set_fs(old_fs); | ||
| 183 | if (n >= 0) { | 172 | if (n >= 0) { |
| 184 | buf[n] = '\0'; | 173 | buf[n] = '\0'; |
| 185 | mconsole_reply(req, buf, 0, (n > 0)); | 174 | mconsole_reply(req, buf, 0, (n > 0)); |
| @@ -197,8 +186,6 @@ void mconsole_proc(struct mc_request *req) | |||
| 197 | kfree(buf); | 186 | kfree(buf); |
| 198 | out_fput: | 187 | out_fput: |
| 199 | fput(file); | 188 | fput(file); |
| 200 | out_kill: | ||
| 201 | deactivate_super(super); | ||
| 202 | out: ; | 189 | out: ; |
| 203 | } | 190 | } |
| 204 | #endif | 191 | #endif |
