Skip to content

Commit 7e2d8c2

Browse files
arndbRussell King (Oracle)
authored andcommitted
ARM: 9111/1: oabi-compat: rework fcntl64() emulation
This is one of the last users of get_fs(), and this is fairly easy to change, since the infrastructure for it is already there. The replacement here is essentially a copy of the existing fcntl64() syscall entry function. Acked-by: Christoph Hellwig <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Russell King (Oracle) <[email protected]>
1 parent bdec014 commit 7e2d8c2

File tree

1 file changed

+60
-33
lines changed

1 file changed

+60
-33
lines changed

arch/arm/kernel/sys_oabi-compat.c

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -194,56 +194,83 @@ struct oabi_flock64 {
194194
pid_t l_pid;
195195
} __attribute__ ((packed,aligned(4)));
196196

197-
static long do_locks(unsigned int fd, unsigned int cmd,
198-
unsigned long arg)
197+
static int get_oabi_flock(struct flock64 *kernel, struct oabi_flock64 __user *arg)
199198
{
200-
struct flock64 kernel;
201199
struct oabi_flock64 user;
202-
mm_segment_t fs;
203-
long ret;
204200

205201
if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
206202
sizeof(user)))
207203
return -EFAULT;
208-
kernel.l_type = user.l_type;
209-
kernel.l_whence = user.l_whence;
210-
kernel.l_start = user.l_start;
211-
kernel.l_len = user.l_len;
212-
kernel.l_pid = user.l_pid;
213-
214-
fs = get_fs();
215-
set_fs(KERNEL_DS);
216-
ret = sys_fcntl64(fd, cmd, (unsigned long)&kernel);
217-
set_fs(fs);
218-
219-
if (!ret && (cmd == F_GETLK64 || cmd == F_OFD_GETLK)) {
220-
user.l_type = kernel.l_type;
221-
user.l_whence = kernel.l_whence;
222-
user.l_start = kernel.l_start;
223-
user.l_len = kernel.l_len;
224-
user.l_pid = kernel.l_pid;
225-
if (copy_to_user((struct oabi_flock64 __user *)arg,
226-
&user, sizeof(user)))
227-
ret = -EFAULT;
228-
}
229-
return ret;
204+
205+
kernel->l_type = user.l_type;
206+
kernel->l_whence = user.l_whence;
207+
kernel->l_start = user.l_start;
208+
kernel->l_len = user.l_len;
209+
kernel->l_pid = user.l_pid;
210+
211+
return 0;
212+
}
213+
214+
static int put_oabi_flock(struct flock64 *kernel, struct oabi_flock64 __user *arg)
215+
{
216+
struct oabi_flock64 user;
217+
218+
user.l_type = kernel->l_type;
219+
user.l_whence = kernel->l_whence;
220+
user.l_start = kernel->l_start;
221+
user.l_len = kernel->l_len;
222+
user.l_pid = kernel->l_pid;
223+
224+
if (copy_to_user((struct oabi_flock64 __user *)arg,
225+
&user, sizeof(user)))
226+
return -EFAULT;
227+
228+
return 0;
230229
}
231230

232231
asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
233232
unsigned long arg)
234233
{
234+
void __user *argp = (void __user *)arg;
235+
struct fd f = fdget_raw(fd);
236+
struct flock64 flock;
237+
long err = -EBADF;
238+
239+
if (!f.file)
240+
goto out;
241+
235242
switch (cmd) {
236-
case F_OFD_GETLK:
237-
case F_OFD_SETLK:
238-
case F_OFD_SETLKW:
239243
case F_GETLK64:
244+
case F_OFD_GETLK:
245+
err = security_file_fcntl(f.file, cmd, arg);
246+
if (err)
247+
break;
248+
err = get_oabi_flock(&flock, argp);
249+
if (err)
250+
break;
251+
err = fcntl_getlk64(f.file, cmd, &flock);
252+
if (!err)
253+
err = put_oabi_flock(&flock, argp);
254+
break;
240255
case F_SETLK64:
241256
case F_SETLKW64:
242-
return do_locks(fd, cmd, arg);
243-
257+
case F_OFD_SETLK:
258+
case F_OFD_SETLKW:
259+
err = security_file_fcntl(f.file, cmd, arg);
260+
if (err)
261+
break;
262+
err = get_oabi_flock(&flock, argp);
263+
if (err)
264+
break;
265+
err = fcntl_setlk64(fd, f.file, cmd, &flock);
266+
break;
244267
default:
245-
return sys_fcntl64(fd, cmd, arg);
268+
err = sys_fcntl64(fd, cmd, arg);
269+
break;
246270
}
271+
fdput(f);
272+
out:
273+
return err;
247274
}
248275

249276
struct oabi_epoll_event {

0 commit comments

Comments
 (0)