linux applications using old linux threads (pre-NPTL) use signal 32 (linux SIGRTMIN) for communication between thread-processes. If such an linux application is installed suid or sgid and security.bsd.conservative_signals=1 (default), then permission will be denied to send such a signal and the application will freeze. Please see http://docs.freebsd.org/cgi/getmsg.cgi?fetch=13492+0+archive/2004/freebsd-emulation/20041017.freebsd-emulation for an example and detailed investigation of such case. Fix: 1. either add signal 32 (linux SIGRTMIN) to list of "common signals" in cr_cansignal() 2. or detect the described situation in cr_cansignal() and produce a warning message explaining the situation and suggesting setting security.bsd.conservative_signals=0 How-To-Repeat: using the same environment as mine 1. make any threaded linux application suid 2. run it so that it really changes privileges 3. see it freeze
Responsible Changed From-To: freebsd-bugs->emulation Over to mailing list.
State Changed From-To: open->closed Fix comitted, thank you for reporting!
State Changed From-To: closed->open Sorry, but the solution is not that simple as it appeares. The following explains the complexity: On Fri, 11 Feb 2005, Maxim Sobolev wrote:
Andriy, Can you please test the following patch and let me know if it help or not. http://www.pbxpress.com/~sobomax/72922.diff -Maxim
State Changed From-To: open->closed Should be fixed in the recent -current. Please test and let me know if the problem persists.
on 20.02.2005 19:21 Maxim Sobolev said the following: > Andriy, > > Can you please test the following patch and let me know if it help or not. > > http://www.pbxpress.com/~sobomax/72922.diff Maxim, sorry that it took me so long to try this patch, I could do reboot only on the past weekend and, ufortunately, this patch didn't fix the problem with MQ, strmqm command still hangs if conservative_signals=1. I am not sure if you commited exactly this patch or something different in current (unfortunately I am not able to test current), but this patch apparently does not work in this particular case. I am not sure if I will be able to help you with debugging kernel stuff (linux kld - most probably yes, kernel - most propbably not), but I can definitely provide you information about this particular program, strmqm, if you need it and if you tell me what to check for. -- Andriy Gapon
Andriy Gapon wrote: > on 20.02.2005 19:21 Maxim Sobolev said the following: > >>Andriy, >> >>Can you please test the following patch and let me know if it help or not. >> >>http://www.pbxpress.com/~sobomax/72922.diff > > > Maxim, > sorry that it took me so long to try this patch, I could do reboot only > on the past weekend and, ufortunately, this patch didn't fix the > problem with MQ, strmqm command still hangs if conservative_signals=1. I > am not sure if you commited exactly this patch or something different in > current (unfortunately I am not able to test current), but this patch > apparently does not work in this particular case. I am not sure if I > will be able to help you with debugging kernel stuff (linux kld - most > probably yes, kernel - most propbably not), but I can definitely provide > you information about this particular program, strmqm, if you need it > and if you tell me what to check for. Hmm, that's pretty strange. Can you please fetch the following Linux binary, make it suid root and try to run as ordinary user on your system? I've used it to verify that my patch is in fact works - after the change has been made it stopped hanging at my system. http://www.pbxpress.com/~sobomax/aqueue_linux It will make sense to execute that strmqm program under ktrace(8) with -i flag (use ports/devel/linux_kdump to decode resulting trace) and send me the output of linux_kdump. Maybe your version of linuxthreads uses some different set of flags in linux_clone(), so that my heuristics fails. -Maxim
on 09.03.2005 11:59 Maxim Sobolev said the following: > Hmm, that's pretty strange. Can you please fetch the following Linux > binary, make it suid root and try to run as ordinary user on your > system? I've used it to verify that my patch is in fact works - after > the change has been made it stopped hanging at my system. > > http://www.pbxpress.com/~sobomax/aqueue_linux > > It will make sense to execute that strmqm program under ktrace(8) with > -i flag (use ports/devel/linux_kdump to decode resulting trace) and send > me the output of linux_kdump. Maybe your version of linuxthreads uses > some different set of flags in linux_clone(), so that my heuristics fails. Maxim, 1. I've tried to follow your advice, but a new strange thing happened (or maybe it is not strange, but I never payed attention before): "-i" in "ktrace -i" doesn't work on suid/sgid applications, when run as normal user: # chmod 6550 ~/tmp/aqueue_linux # ls -l ~/tmp/aqueue_linux -r-sr-s--- 1 avg topspin 16804 9 ÂÅÒ 13:47 /home/avg/tmp/aqueue_linux $ ktrace -i ~avg/tmp/aqueue_linux -n 100 pusher started poper started $ linux_kdump > kdump.out $ cat kdump.out 16103 ktrace RET linux_brk 0 16103 ktrace CALL linux_olduname(0xbfbfea4e,0xbfbfe95c,0xbfbfe96c) 16103 ktrace NAMI "/home/avg/tmp/aqueue_linux" 16103 ktrace NAMI "/compat/linux/lib/ld-linux.so.2" If I set permission back to normal executable, "-i" works again. 2. "ktrace -i" works if executed as super-user and strmqm still hangs. Here's some relevant info, whcih makes things quite obvious: # egrep 'fork|exec|clone|kill|signal' kdump.out 79953 strmqm CALL linux_clone(0xf00,0x8099370) 79953 strmqm RET linux_clone 79954/0x13852 79954 strmqm RET linux_fork 0 79954 strmqm CALL linux_clone(0xf21,0xbf3ffbd0) 79954 strmqm RET linux_clone 79955/0x13853 79955 strmqm RET linux_fork 0 79954 strmqm CALL linux_kill(0x13851,0x20) 79954 strmqm RET linux_kill 0 79955 strmqm CALL linux_kill(0x13851,0x20) 79955 strmqm RET linux_kill 0 79955 strmqm CALL linux_kill(0x13851,0x20) 79955 strmqm RET linux_kill 0 79955 strmqm CALL linux_kill(0x13851,0x20) 79955 strmqm RET linux_kill 0 uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico 79954 strmqm CALL linux_clone(0xf21,0xbf1ffbd0) 79954 strmqm RET linux_clone 79956/0x13854 79956 strmqm RET linux_fork 0 79954 strmqm CALL linux_kill(0x13851,0x20) 79954 strmqm RET linux_kill 0 79956 strmqm CALL linux_kill(0x13851,0x20) 79956 strmqm RET linux_kill 0 79953 strmqm CALL linux_kill(0x13854,0x20) 79953 strmqm RET linux_kill 0 79956 strmqm CALL linux_kill(0x13851,0x20) 79956 strmqm RET linux_kill 0 79956 strmqm CALL linux_kill(0x13851,0x20) 79956 strmqm RET linux_kill 0 79953 strmqm CALL linux_kill(0x13853,0x1c) 79953 strmqm RET linux_kill RESTART permitted' from pthread_kill.) | ('1 - Operation not permitted' from pthread_kill.) | " "| Comment1 :- '1 - Operation not permitted' from pthread_kill. | 79954 strmqm CALL linux_kill(0x13854,0x21) 79954 strmqm RET linux_kill RESTART 79954 strmqm CALL linux_kill(0x13853,0x21) 79954 strmqm RET linux_kill RESTART Looks like signal 32 is OK, but there are 28 and 33 in addition to it. 33 seems to be another Linux real-time signal and is probably used with linux threads for some purpose. Here's what I read in signal(7) Linux man page: <<< Linux supports real-time signals as originally defined in the POSIX.4 real-time extensions (and now included in POSIX 1003.1-2001). Linux supports 32 real-time signals, numbered from 32 (SIGRTMIN) to 63 (SIGRTMAX). (Programs should always refer to real-time signals using notation SIGRTMIN+n, since the range of real-time signal numbers varies across Unices.) Unlike standard signals, real-time signals have no predefined meanings: the entire set of real-time signals can be used for application-defined purposes. (Note, however, that the LinuxThreads implementation uses the first three real-time signals.) >>>> So probably 32,33,34 should be subject to your patch. I am not sure what signal 28 (SIGWINCH?) is used for (in this case), but most probably it is not thread-related and not application critical, because execution continues after that signal, but an error message is logged. -- Andriy Gapon
I see. Try to replace the following line in kern_prot.c: if (signum == SIGTHR && td->td_proc->p_leader != NULL && with the following: if (signum >= SIGTHR && td->td_proc->p_leader != NULL && And let me know if it helps. BTW, would be be interested in getting FreeBSD commit bit, so that you can do the work by yourself? ;-) -Maxim Andriy Gapon wrote: > on 09.03.2005 11:59 Maxim Sobolev said the following: > >>Hmm, that's pretty strange. Can you please fetch the following Linux >>binary, make it suid root and try to run as ordinary user on your >>system? I've used it to verify that my patch is in fact works - after >>the change has been made it stopped hanging at my system. >> >>http://www.pbxpress.com/~sobomax/aqueue_linux >> >>It will make sense to execute that strmqm program under ktrace(8) with >>-i flag (use ports/devel/linux_kdump to decode resulting trace) and send >>me the output of linux_kdump. Maybe your version of linuxthreads uses >>some different set of flags in linux_clone(), so that my heuristics fails. > > > Maxim, > > 1. I've tried to follow your advice, but a new strange thing happened > (or maybe it is not strange, but I never payed attention before): "-i" > in "ktrace -i" doesn't work on suid/sgid applications, when run as > normal user: > > # chmod 6550 ~/tmp/aqueue_linux > # ls -l ~/tmp/aqueue_linux > -r-sr-s--- 1 avg topspin 16804 9 ÂÅÒ 13:47 /home/avg/tmp/aqueue_linux > > > $ ktrace -i ~avg/tmp/aqueue_linux -n 100 > pusher started > poper started > $ linux_kdump > kdump.out > $ cat kdump.out > 16103 ktrace RET linux_brk 0 > 16103 ktrace CALL linux_olduname(0xbfbfea4e,0xbfbfe95c,0xbfbfe96c) > 16103 ktrace NAMI "/home/avg/tmp/aqueue_linux" > 16103 ktrace NAMI "/compat/linux/lib/ld-linux.so.2" > > If I set permission back to normal executable, "-i" works again. > > > 2. "ktrace -i" works if executed as super-user and strmqm still hangs. > Here's some relevant info, whcih makes things quite obvious: > > # egrep 'fork|exec|clone|kill|signal' kdump.out > 79953 strmqm CALL linux_clone(0xf00,0x8099370) > 79953 strmqm RET linux_clone 79954/0x13852 > 79954 strmqm RET linux_fork 0 > 79954 strmqm CALL linux_clone(0xf21,0xbf3ffbd0) > 79954 strmqm RET linux_clone 79955/0x13853 > 79955 strmqm RET linux_fork 0 > 79954 strmqm CALL linux_kill(0x13851,0x20) > 79954 strmqm RET linux_kill 0 > 79955 strmqm CALL linux_kill(0x13851,0x20) > 79955 strmqm RET linux_kill 0 > 79955 strmqm CALL linux_kill(0x13851,0x20) > 79955 strmqm RET linux_kill 0 > 79955 strmqm CALL linux_kill(0x13851,0x20) > 79955 strmqm RET linux_kill 0 > uucp:*:66:66:UUCP > pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico > 79954 strmqm CALL linux_clone(0xf21,0xbf1ffbd0) > 79954 strmqm RET linux_clone 79956/0x13854 > 79956 strmqm RET linux_fork 0 > 79954 strmqm CALL linux_kill(0x13851,0x20) > 79954 strmqm RET linux_kill 0 > 79956 strmqm CALL linux_kill(0x13851,0x20) > 79956 strmqm RET linux_kill 0 > 79953 strmqm CALL linux_kill(0x13854,0x20) > 79953 strmqm RET linux_kill 0 > 79956 strmqm CALL linux_kill(0x13851,0x20) > 79956 strmqm RET linux_kill 0 > 79956 strmqm CALL linux_kill(0x13851,0x20) > 79956 strmqm RET linux_kill 0 > 79953 strmqm CALL linux_kill(0x13853,0x1c) > 79953 strmqm RET linux_kill RESTART > permitted' from pthread_kill.) > | ('1 - Operation not permitted' from pthread_kill.) > | " > "| Comment1 :- '1 - Operation not permitted' from > pthread_kill. | > 79954 strmqm CALL linux_kill(0x13854,0x21) > 79954 strmqm RET linux_kill RESTART > 79954 strmqm CALL linux_kill(0x13853,0x21) > 79954 strmqm RET linux_kill RESTART > > Looks like signal 32 is OK, but there are 28 and 33 in addition to it. > 33 seems to be another Linux real-time signal and is probably used with > linux threads for some purpose. Here's what I read in signal(7) Linux > man page: > <<< > Linux supports real-time signals as originally defined in the POSIX.4 > real-time extensions (and now included in POSIX 1003.1-2001). Linux > supports 32 real-time signals, numbered from 32 (SIGRTMIN) to 63 > (SIGRTMAX). (Programs should always refer to real-time signals using > notation SIGRTMIN+n, since the range of real-time signal numbers varies > across Unices.) > > Unlike standard signals, real-time signals have no predefined meanings: > the entire set of real-time signals can be used for application-defined > purposes. > > (Note, however, that the LinuxThreads implementation uses the first > three real-time signals.) > > So probably 32,33,34 should be subject to your patch. > > I am not sure what signal 28 (SIGWINCH?) is used for (in this case), but > most probably it is not thread-related and not application critical, > because execution continues after that signal, but an error message is > logged. >
on 10.03.2005 14:56 Maxim Sobolev said the following: > I see. Try to replace the following line in kern_prot.c: > > if (signum == SIGTHR && td->td_proc->p_leader != NULL && > > with the following: > > if (signum >= SIGTHR && td->td_proc->p_leader != NULL && > > And let me know if it helps. that's what came to my mind too, but unfortunately I will only be able to try it in a week or two. > BTW, would be be interested in getting FreeBSD commit bit, so that you > can do the work by yourself? ;-) I have always dreamt about it, but I feel like it is more responsibility than I can take now. Unfortunately, I am also too short of capabilities to test kernel changes. Thank you, maybe later. -- Andriy Gapon
on 10.03.2005 14:56 Maxim Sobolev said the following: > I see. Try to replace the following line in kern_prot.c: > > if (signum == SIGTHR && td->td_proc->p_leader != NULL && > > with the following: > > if (signum >= SIGTHR && td->td_proc->p_leader != NULL && > > And let me know if it helps. > Maxim, this has fixed the problem completely, thank you. As to your other question, I need to gather my thoughts on it :-) -- Andriy Gapon