| .. | .. |
|---|
| 193 | 193 | return error ? -EFAULT : 0; |
|---|
| 194 | 194 | } |
|---|
| 195 | 195 | |
|---|
| 196 | | -int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat) |
|---|
| 196 | +int atm_getnames(void __user *buf, int __user *iobuf_len) |
|---|
| 197 | 197 | { |
|---|
| 198 | | - void __user *buf; |
|---|
| 199 | | - int error, len, number, size = 0; |
|---|
| 198 | + int error, len, size = 0; |
|---|
| 200 | 199 | struct atm_dev *dev; |
|---|
| 201 | 200 | struct list_head *p; |
|---|
| 202 | 201 | int *tmp_buf, *tmp_p; |
|---|
| 203 | | - int __user *sioc_len; |
|---|
| 204 | | - int __user *iobuf_len; |
|---|
| 205 | 202 | |
|---|
| 206 | | -#ifndef CONFIG_COMPAT |
|---|
| 207 | | - compat = 0; /* Just so the compiler _knows_ */ |
|---|
| 208 | | -#endif |
|---|
| 209 | | - |
|---|
| 210 | | - switch (cmd) { |
|---|
| 211 | | - case ATM_GETNAMES: |
|---|
| 212 | | - if (compat) { |
|---|
| 213 | | -#ifdef CONFIG_COMPAT |
|---|
| 214 | | - struct compat_atm_iobuf __user *ciobuf = arg; |
|---|
| 215 | | - compat_uptr_t cbuf; |
|---|
| 216 | | - iobuf_len = &ciobuf->length; |
|---|
| 217 | | - if (get_user(cbuf, &ciobuf->buffer)) |
|---|
| 218 | | - return -EFAULT; |
|---|
| 219 | | - buf = compat_ptr(cbuf); |
|---|
| 220 | | -#endif |
|---|
| 221 | | - } else { |
|---|
| 222 | | - struct atm_iobuf __user *iobuf = arg; |
|---|
| 223 | | - iobuf_len = &iobuf->length; |
|---|
| 224 | | - if (get_user(buf, &iobuf->buffer)) |
|---|
| 225 | | - return -EFAULT; |
|---|
| 226 | | - } |
|---|
| 227 | | - if (get_user(len, iobuf_len)) |
|---|
| 228 | | - return -EFAULT; |
|---|
| 229 | | - mutex_lock(&atm_dev_mutex); |
|---|
| 230 | | - list_for_each(p, &atm_devs) |
|---|
| 231 | | - size += sizeof(int); |
|---|
| 232 | | - if (size > len) { |
|---|
| 233 | | - mutex_unlock(&atm_dev_mutex); |
|---|
| 234 | | - return -E2BIG; |
|---|
| 235 | | - } |
|---|
| 236 | | - tmp_buf = kmalloc(size, GFP_ATOMIC); |
|---|
| 237 | | - if (!tmp_buf) { |
|---|
| 238 | | - mutex_unlock(&atm_dev_mutex); |
|---|
| 239 | | - return -ENOMEM; |
|---|
| 240 | | - } |
|---|
| 241 | | - tmp_p = tmp_buf; |
|---|
| 242 | | - list_for_each(p, &atm_devs) { |
|---|
| 243 | | - dev = list_entry(p, struct atm_dev, dev_list); |
|---|
| 244 | | - *tmp_p++ = dev->number; |
|---|
| 245 | | - } |
|---|
| 203 | + if (get_user(len, iobuf_len)) |
|---|
| 204 | + return -EFAULT; |
|---|
| 205 | + mutex_lock(&atm_dev_mutex); |
|---|
| 206 | + list_for_each(p, &atm_devs) |
|---|
| 207 | + size += sizeof(int); |
|---|
| 208 | + if (size > len) { |
|---|
| 246 | 209 | mutex_unlock(&atm_dev_mutex); |
|---|
| 247 | | - error = ((copy_to_user(buf, tmp_buf, size)) || |
|---|
| 248 | | - put_user(size, iobuf_len)) |
|---|
| 249 | | - ? -EFAULT : 0; |
|---|
| 250 | | - kfree(tmp_buf); |
|---|
| 251 | | - return error; |
|---|
| 252 | | - default: |
|---|
| 253 | | - break; |
|---|
| 210 | + return -E2BIG; |
|---|
| 254 | 211 | } |
|---|
| 255 | | - |
|---|
| 256 | | - if (compat) { |
|---|
| 257 | | -#ifdef CONFIG_COMPAT |
|---|
| 258 | | - struct compat_atmif_sioc __user *csioc = arg; |
|---|
| 259 | | - compat_uptr_t carg; |
|---|
| 260 | | - |
|---|
| 261 | | - sioc_len = &csioc->length; |
|---|
| 262 | | - if (get_user(carg, &csioc->arg)) |
|---|
| 263 | | - return -EFAULT; |
|---|
| 264 | | - buf = compat_ptr(carg); |
|---|
| 265 | | - |
|---|
| 266 | | - if (get_user(len, &csioc->length)) |
|---|
| 267 | | - return -EFAULT; |
|---|
| 268 | | - if (get_user(number, &csioc->number)) |
|---|
| 269 | | - return -EFAULT; |
|---|
| 270 | | -#endif |
|---|
| 271 | | - } else { |
|---|
| 272 | | - struct atmif_sioc __user *sioc = arg; |
|---|
| 273 | | - |
|---|
| 274 | | - sioc_len = &sioc->length; |
|---|
| 275 | | - if (get_user(buf, &sioc->arg)) |
|---|
| 276 | | - return -EFAULT; |
|---|
| 277 | | - if (get_user(len, &sioc->length)) |
|---|
| 278 | | - return -EFAULT; |
|---|
| 279 | | - if (get_user(number, &sioc->number)) |
|---|
| 280 | | - return -EFAULT; |
|---|
| 212 | + tmp_buf = kmalloc(size, GFP_ATOMIC); |
|---|
| 213 | + if (!tmp_buf) { |
|---|
| 214 | + mutex_unlock(&atm_dev_mutex); |
|---|
| 215 | + return -ENOMEM; |
|---|
| 281 | 216 | } |
|---|
| 217 | + tmp_p = tmp_buf; |
|---|
| 218 | + list_for_each(p, &atm_devs) { |
|---|
| 219 | + dev = list_entry(p, struct atm_dev, dev_list); |
|---|
| 220 | + *tmp_p++ = dev->number; |
|---|
| 221 | + } |
|---|
| 222 | + mutex_unlock(&atm_dev_mutex); |
|---|
| 223 | + error = ((copy_to_user(buf, tmp_buf, size)) || |
|---|
| 224 | + put_user(size, iobuf_len)) |
|---|
| 225 | + ? -EFAULT : 0; |
|---|
| 226 | + kfree(tmp_buf); |
|---|
| 227 | + return error; |
|---|
| 228 | +} |
|---|
| 229 | + |
|---|
| 230 | +int atm_dev_ioctl(unsigned int cmd, void __user *buf, int __user *sioc_len, |
|---|
| 231 | + int number, int compat) |
|---|
| 232 | +{ |
|---|
| 233 | + int error, len, size = 0; |
|---|
| 234 | + struct atm_dev *dev; |
|---|
| 235 | + |
|---|
| 236 | + if (get_user(len, sioc_len)) |
|---|
| 237 | + return -EFAULT; |
|---|
| 282 | 238 | |
|---|
| 283 | 239 | dev = try_then_request_module(atm_dev_lookup(number), "atm-device-%d", |
|---|
| 284 | 240 | number); |
|---|
| .. | .. |
|---|
| 310 | 266 | goto done; |
|---|
| 311 | 267 | } |
|---|
| 312 | 268 | } |
|---|
| 313 | | - /* fall through */ |
|---|
| 269 | + fallthrough; |
|---|
| 314 | 270 | case ATM_SETESIF: |
|---|
| 315 | 271 | { |
|---|
| 316 | 272 | unsigned char esi[ESI_LEN]; |
|---|
| .. | .. |
|---|
| 332 | 288 | error = -EPERM; |
|---|
| 333 | 289 | goto done; |
|---|
| 334 | 290 | } |
|---|
| 335 | | - /* fall through */ |
|---|
| 291 | + fallthrough; |
|---|
| 336 | 292 | case ATM_GETSTAT: |
|---|
| 337 | 293 | size = sizeof(struct atm_dev_stats); |
|---|
| 338 | 294 | error = fetch_stats(dev, buf, cmd == ATM_GETSTATZ); |
|---|
| .. | .. |
|---|
| 405 | 361 | error = -EINVAL; |
|---|
| 406 | 362 | goto done; |
|---|
| 407 | 363 | } |
|---|
| 408 | | - /* fall through */ |
|---|
| 364 | + fallthrough; |
|---|
| 409 | 365 | case ATM_SETCIRANGE: |
|---|
| 410 | 366 | case SONET_GETSTATZ: |
|---|
| 411 | 367 | case SONET_SETDIAG: |
|---|
| .. | .. |
|---|
| 415 | 371 | error = -EPERM; |
|---|
| 416 | 372 | goto done; |
|---|
| 417 | 373 | } |
|---|
| 418 | | - /* fall through */ |
|---|
| 374 | + fallthrough; |
|---|
| 419 | 375 | default: |
|---|
| 420 | | - if (compat) { |
|---|
| 376 | + if (IS_ENABLED(CONFIG_COMPAT) && compat) { |
|---|
| 421 | 377 | #ifdef CONFIG_COMPAT |
|---|
| 422 | 378 | if (!dev->ops->compat_ioctl) { |
|---|
| 423 | 379 | error = -EINVAL; |
|---|
| .. | .. |
|---|
| 447 | 403 | return error; |
|---|
| 448 | 404 | } |
|---|
| 449 | 405 | |
|---|
| 406 | +#ifdef CONFIG_PROC_FS |
|---|
| 450 | 407 | void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) |
|---|
| 451 | 408 | { |
|---|
| 452 | 409 | mutex_lock(&atm_dev_mutex); |
|---|
| .. | .. |
|---|
| 462 | 419 | { |
|---|
| 463 | 420 | return seq_list_next(v, &atm_devs, pos); |
|---|
| 464 | 421 | } |
|---|
| 422 | +#endif |
|---|