Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

frv: fix address verification holes in setup_frame/setup_rt_frame

a) sa_handler might be maliciously set to point to kernel memory;
blindly dereferencing it in FDPIC case is a Bad Idea(tm).

b) I'm not sure you need that set_fs(USER_DS) there at all, but if you
do, you'd better do it *before* checking the frame you've decided to
use with access_ok(), lest sigaltstack() becomes a convenient
roothole.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Al Viro and committed by
Linus Torvalds
5f4ad04a 20cd514d

+22 -16
+22 -16
arch/frv/kernel/signal.c
··· 253 253 struct sigframe __user *frame; 254 254 int rsig; 255 255 256 + set_fs(USER_DS); 257 + 256 258 frame = get_sigframe(ka, sizeof(*frame)); 257 259 258 260 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) ··· 298 296 (unsigned long) (frame->retcode + 2)); 299 297 } 300 298 301 - /* set up registers for signal handler */ 302 - __frame->sp = (unsigned long) frame; 303 - __frame->lr = (unsigned long) &frame->retcode; 304 - __frame->gr8 = sig; 305 - 299 + /* Set up registers for the signal handler */ 306 300 if (current->personality & FDPIC_FUNCPTRS) { 307 301 struct fdpic_func_descriptor __user *funcptr = 308 302 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 309 - __get_user(__frame->pc, &funcptr->text); 310 - __get_user(__frame->gr15, &funcptr->GOT); 303 + struct fdpic_func_descriptor desc; 304 + if (copy_from_user(&desc, funcptr, sizeof(desc))) 305 + goto give_sigsegv; 306 + __frame->pc = desc.text; 307 + __frame->gr15 = desc.GOT; 311 308 } else { 312 309 __frame->pc = (unsigned long) ka->sa.sa_handler; 313 310 __frame->gr15 = 0; 314 311 } 315 312 316 - set_fs(USER_DS); 313 + __frame->sp = (unsigned long) frame; 314 + __frame->lr = (unsigned long) &frame->retcode; 315 + __frame->gr8 = sig; 317 316 318 317 /* the tracer may want to single-step inside the handler */ 319 318 if (test_thread_flag(TIF_SINGLESTEP)) ··· 343 340 { 344 341 struct rt_sigframe __user *frame; 345 342 int rsig; 343 + 344 + set_fs(USER_DS); 346 345 347 346 frame = get_sigframe(ka, sizeof(*frame)); 348 347 ··· 400 395 } 401 396 402 397 /* Set up registers for signal handler */ 403 - __frame->sp = (unsigned long) frame; 404 - __frame->lr = (unsigned long) &frame->retcode; 405 - __frame->gr8 = sig; 406 - __frame->gr9 = (unsigned long) &frame->info; 407 - 408 398 if (current->personality & FDPIC_FUNCPTRS) { 409 399 struct fdpic_func_descriptor __user *funcptr = 410 400 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 411 - __get_user(__frame->pc, &funcptr->text); 412 - __get_user(__frame->gr15, &funcptr->GOT); 401 + struct fdpic_func_descriptor desc; 402 + if (copy_from_user(&desc, funcptr, sizeof(desc))) 403 + goto give_sigsegv; 404 + __frame->pc = desc.text; 405 + __frame->gr15 = desc.GOT; 413 406 } else { 414 407 __frame->pc = (unsigned long) ka->sa.sa_handler; 415 408 __frame->gr15 = 0; 416 409 } 417 410 418 - set_fs(USER_DS); 411 + __frame->sp = (unsigned long) frame; 412 + __frame->lr = (unsigned long) &frame->retcode; 413 + __frame->gr8 = sig; 414 + __frame->gr9 = (unsigned long) &frame->info; 419 415 420 416 /* the tracer may want to single-step inside the handler */ 421 417 if (test_thread_flag(TIF_SINGLESTEP))