
sochotnicky at redhat
Feb 15, 2011, 6:12 AM
Post #2 of 4
(1082 views)
Permalink
|
|
[PATCH] Fix curses running as root on tty of other user
[In reply to]
|
|
After doing "su -", ownership of current tty stays with original user. If we drop all capabilities we will not be able to open current tty to setup curses screen. So we keep ipc_lock together with dac_override capabilities until we open tty for R/W, then we drop dac_override capability. This patch also fixes second cap_set_proc call in lock_pool that was originally "cap_ipc_lock+p", but should probably be "cap_ipc_lock-e". Original call had no effect because ipc_lock capability was already permitted. Instead it was supposed to drop effective capability enabled in first call. See https://bugzilla.redhat.com/show_bug.cgi?id=676034 for details and reproducer --- pinentry/pinentry-curses.c | 25 ++++++++++++++++++++++++- secmem/secmem.c | 6 ++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/pinentry/pinentry-curses.c b/pinentry/pinentry-curses.c index 76ddbdd..bfc5013 100644 --- a/pinentry/pinentry-curses.c +++ b/pinentry/pinentry-curses.c @@ -93,6 +93,21 @@ struct dialog }; typedef struct dialog *dialog_t; +/* When pinentry-curses runs as root, current tty can be owned by + original user (before doing "su -"). We need to preserve + dac_override capability to be able to read/write on tty */ +static int tty_cap_setup(int init) +{ +#if defined(USE_CAPABILITIES) + if (init) + cap_set_proc( cap_from_text("cap_dac_override+ep") ); + else + cap_set_proc ( cap_from_text("cap_ipc_lock=p") ); +#endif + return 0; +} + + /* Return the next line up to MAXLEN columns wide in START and LEN. The first invocation should have 0 as *LEN. If the line ends with @@ -635,17 +650,25 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) /* Open the desired terminal if necessary. */ if (tty_name) { + tty_cap_setup(1); ttyfi = fopen (tty_name, "r"); if (!ttyfi) - return -1; + { + int err = errno; + tty_cap_setup(0); + errno = err; + return -1; + } ttyfo = fopen (tty_name, "w"); if (!ttyfo) { int err = errno; fclose (ttyfi); + tty_cap_setup(0); errno = err; return -1; } + tty_cap_setup(0); screen = newterm (tty_type, ttyfo, ttyfi); set_term (screen); } diff --git a/secmem/secmem.c b/secmem/secmem.c index fed7e97..b31e270 100644 --- a/secmem/secmem.c +++ b/secmem/secmem.c @@ -130,11 +130,13 @@ lock_pool( void *p, size_t n ) #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK) int err; - cap_set_proc( cap_from_text("cap_ipc_lock+ep") ); + /* we have to preserve dac_override to be able to open current tty + * even if it is owned by other user (usually after doing su) */ + cap_set_proc( cap_from_text("cap_ipc_lock+ep cap_dac_override+p") ); err = mlock( p, n ); if( err && errno ) err = errno; - cap_set_proc( cap_from_text("cap_ipc_lock+p") ); + cap_set_proc( cap_from_text("cap_ipc_lock-e cap_dac_override+p") ); if( err ) { if( errno != EPERM -- 1.7.4 _______________________________________________ Gpa-dev mailing list Gpa-dev [at] gnupg http://lists.gnupg.org/mailman/listinfo/gpa-dev
|