@@ -196,28 +196,44 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
196
196
return res ;
197
197
}
198
198
199
+ struct compat_resume_swap_area {
200
+ compat_loff_t offset ;
201
+ u32 dev ;
202
+ } __packed ;
203
+
199
204
static int snapshot_set_swap_area (struct snapshot_data * data ,
200
205
void __user * argp )
201
206
{
202
- struct resume_swap_area swap_area ;
203
207
sector_t offset ;
204
208
dev_t swdev ;
205
209
206
210
if (swsusp_swap_in_use ())
207
211
return - EPERM ;
208
- if (copy_from_user (& swap_area , argp , sizeof (swap_area )))
209
- return - EFAULT ;
212
+
213
+ if (in_compat_syscall ()) {
214
+ struct compat_resume_swap_area swap_area ;
215
+
216
+ if (copy_from_user (& swap_area , argp , sizeof (swap_area )))
217
+ return - EFAULT ;
218
+ swdev = new_decode_dev (swap_area .dev );
219
+ offset = swap_area .offset ;
220
+ } else {
221
+ struct resume_swap_area swap_area ;
222
+
223
+ if (copy_from_user (& swap_area , argp , sizeof (swap_area )))
224
+ return - EFAULT ;
225
+ swdev = new_decode_dev (swap_area .dev );
226
+ offset = swap_area .offset ;
227
+ }
210
228
211
229
/*
212
230
* User space encodes device types as two-byte values,
213
231
* so we need to recode them
214
232
*/
215
- swdev = new_decode_dev (swap_area .dev );
216
233
if (!swdev ) {
217
234
data -> swap = -1 ;
218
235
return - EINVAL ;
219
236
}
220
- offset = swap_area .offset ;
221
237
data -> swap = swap_type_of (swdev , offset , NULL );
222
238
if (data -> swap < 0 )
223
239
return - ENODEV ;
@@ -394,12 +410,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
394
410
}
395
411
396
412
#ifdef CONFIG_COMPAT
397
-
398
- struct compat_resume_swap_area {
399
- compat_loff_t offset ;
400
- u32 dev ;
401
- } __packed ;
402
-
403
413
static long
404
414
snapshot_compat_ioctl (struct file * file , unsigned int cmd , unsigned long arg )
405
415
{
@@ -410,33 +420,13 @@ snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
410
420
case SNAPSHOT_AVAIL_SWAP_SIZE :
411
421
case SNAPSHOT_ALLOC_SWAP_PAGE :
412
422
case SNAPSHOT_CREATE_IMAGE :
423
+ case SNAPSHOT_SET_SWAP_AREA :
413
424
return snapshot_ioctl (file , cmd ,
414
425
(unsigned long ) compat_ptr (arg ));
415
-
416
- case SNAPSHOT_SET_SWAP_AREA : {
417
- struct compat_resume_swap_area __user * u_swap_area =
418
- compat_ptr (arg );
419
- struct resume_swap_area swap_area ;
420
- mm_segment_t old_fs ;
421
- int err ;
422
-
423
- err = get_user (swap_area .offset , & u_swap_area -> offset );
424
- err |= get_user (swap_area .dev , & u_swap_area -> dev );
425
- if (err )
426
- return - EFAULT ;
427
- old_fs = get_fs ();
428
- set_fs (KERNEL_DS );
429
- err = snapshot_ioctl (file , SNAPSHOT_SET_SWAP_AREA ,
430
- (unsigned long ) & swap_area );
431
- set_fs (old_fs );
432
- return err ;
433
- }
434
-
435
426
default :
436
427
return snapshot_ioctl (file , cmd , arg );
437
428
}
438
429
}
439
-
440
430
#endif /* CONFIG_COMPAT */
441
431
442
432
static const struct file_operations snapshot_fops = {
0 commit comments