summaryrefslogtreecommitdiff
diff options
-rw-r--r--debian/changelog21
-rw-r--r--lockscreen/LockScreenController.cpp9
-rw-r--r--lockscreen/LockScreenController.h1
-rw-r--r--lockscreen/LockScreenPanel.cpp7
-rw-r--r--lockscreen/LockScreenShield.cpp1
-rw-r--r--plugins/unityshell/src/unityshell.cpp28
-rw-r--r--services/panel-service.c25
-rw-r--r--shutdown/SessionController.cpp12
-rw-r--r--tests/test_session_controller.cpp3
9 files changed, 86 insertions, 21 deletions
diff --git a/debian/changelog b/debian/changelog
index f7ad1616f..27977c2b6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,24 @@
+unity (7.2.0+14.04.20140423-0ubuntu1.2) trusty-security; urgency=medium
+
+ * SECURITY UPDATE: more lock screen bypass issues, and regression with
+ shutdown dialog (LP: #1314247)
+ - debian/patches/lp1314247.patch: improve popup menu handling in
+ lockscreen/LockScreenShield.cpp, lockscreen/LockScreenPanel.cpp,
+ services/panel-service.c, plugins/unityshell/src/unityshell.cpp,
+ lockscreen/LockScreenController.*, shutdown/SessionController.cpp,
+ tests/test_session_controller.cpp.
+
+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Wed, 30 Apr 2014 11:11:18 -0400
+
+unity (7.2.0+14.04.20140423-0ubuntu1.1) trusty-security; urgency=medium
+
+ * SECURITY UPDATE: lock screen bypass (LP: #1313885)
+ - debian/patches/lp1313885.patch: improve lockscreen logic in
+ lockscreen/LockScreenController.cpp, lockscreen/LockScreenShield.*,
+ plugins/unityshell/src/unityshell.*.
+
+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Mon, 28 Apr 2014 22:29:13 -0400
+
unity (7.2.0+14.04.20140423-0ubuntu1) trusty; urgency=low
[ Chris Townsend ]
diff --git a/lockscreen/LockScreenController.cpp b/lockscreen/LockScreenController.cpp
index 20130ff03..0314cf6fd 100644
--- a/lockscreen/LockScreenController.cpp
+++ b/lockscreen/LockScreenController.cpp
@@ -69,9 +69,14 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
EnsureShields(monitors);
EnsureBlankWindow();
});
-
uscreen_connection_->block();
+ hidden_window_connection_ = nux::GetWindowCompositor().sigHiddenViewWindow.connect([this] (nux::BaseWindow*) {
+ // Another view (i.e. the shutdown dialog) might have taken the role of AlwaysOnFront window
+ nux::GetWindowCompositor().SetAlwaysOnFrontWindow(primary_shield_.GetPointer());
+ });
+ hidden_window_connection_->block();
+
suspend_connection_ = uscreen->suspending.connect([this] {
if (Settings::Instance().lock_on_suspend())
session_manager_->PromptLockScreen();
@@ -98,6 +103,7 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
motion_connection_->disconnect();
key_connection_->disconnect();
uscreen_connection_->block();
+ hidden_window_connection_->block();
session_manager_->unlocked.emit();
std::for_each(shields_.begin(), shields_.end(), [](nux::ObjectPtr<Shield> const& shield) {
@@ -402,6 +408,7 @@ void Controller::ShowShields()
WindowManager::Default().SaveInputFocus();
EnsureShields(UScreen::GetDefault()->GetMonitors());
uscreen_connection_->unblock();
+ hidden_window_connection_->unblock();
std::for_each(shields_.begin(), shields_.end(), [] (nux::ObjectPtr<Shield> const& shield) {
shield->SetOpacity(0.0f);
diff --git a/lockscreen/LockScreenController.h b/lockscreen/LockScreenController.h
index 434b95c13..1c43fa49a 100644
--- a/lockscreen/LockScreenController.h
+++ b/lockscreen/LockScreenController.h
@@ -86,6 +86,7 @@ private:
connection::Wrapper uscreen_connection_;
connection::Wrapper suspend_connection_;
+ connection::Wrapper hidden_window_connection_;
connection::Wrapper motion_connection_;
connection::Wrapper key_connection_;
diff --git a/lockscreen/LockScreenPanel.cpp b/lockscreen/LockScreenPanel.cpp
index 54fa9230e..c3b5a934d 100644
--- a/lockscreen/LockScreenPanel.cpp
+++ b/lockscreen/LockScreenPanel.cpp
@@ -192,6 +192,13 @@ void Panel::OnEntryActivated(std::string const& panel, std::string const& entry_
return;
bool active = !entry_id.empty();
+
+ if (active && !WindowManager::Default().IsScreenGrabbed())
+ {
+ // The menu didn't grab the keyboard, let's take it back.
+ nux::GetWindowCompositor().GrabKeyboardAdd(static_cast<nux::BaseWindow*>(GetTopLevelViewWindow()));
+ }
+
if (active && !track_menu_pointer_timeout_)
{
track_menu_pointer_timeout_.reset(new glib::Timeout(16));
diff --git a/lockscreen/LockScreenShield.cpp b/lockscreen/LockScreenShield.cpp
index c18e1415b..861beb176 100644
--- a/lockscreen/LockScreenShield.cpp
+++ b/lockscreen/LockScreenShield.cpp
@@ -149,6 +149,7 @@ Panel* Shield::CreatePanel()
{
if (active)
{
+ regrab_conn_->disconnect();
UnGrabPointer();
UnGrabKeyboard();
}
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 12590e813..10e09651e 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -3762,21 +3762,30 @@ void UnityScreen::OnDashRealized()
void UnityScreen::OnLockScreenRequested()
{
if (switcher_controller_->Visible())
- {
switcher_controller_->Hide(false);
- }
- else if (launcher_controller_->IsOverlayOpen())
- {
+
+ if (dash_controller_->IsVisible())
dash_controller_->HideDash();
+
+ if (hud_controller_->IsVisible())
hud_controller_->HideHud();
- }
launcher_controller_->ClearTooltips();
+ if (launcher_controller_->KeyNavIsActive())
+ launcher_controller_->KeyNavTerminate(false);
+
+ if (QuicklistManager::Default()->Current())
+ QuicklistManager::Default()->Current()->Hide();
+
auto& wm = WindowManager::Default();
+
if (wm.IsScaleActive())
wm.TerminateScale();
+ if (wm.IsExpoActive())
+ wm.TerminateExpo();
+
RaiseOSK();
}
@@ -3795,8 +3804,12 @@ void UnityScreen::OnScreenLocked()
}
}
- // We notify that super has been released, to avoid to leave unity in inconsistent state
+ for (auto& action : getActions())
+ screen->removeAction(&action);
+
+ // We notify that super/alt have been released, to avoid to leave unity in inconsistent state
showLauncherKeyTerminate(&optionGetShowLauncher(), CompAction::StateTermKey, getOptions());
+ showMenuBarTerminate(&optionGetShowMenuBar(), CompAction::StateTermKey, getOptions());
}
void UnityScreen::OnScreenUnlocked()
@@ -3808,6 +3821,9 @@ void UnityScreen::OnScreenUnlocked()
if (option.isAction())
screen->addAction(&option.value().action());
}
+
+ for (auto& action : getActions())
+ screen->addAction(&action);
}
void UnityScreen::SaveLockStamp(bool save)
diff --git a/services/panel-service.c b/services/panel-service.c
index 5c7102a8e..a161cacbd 100644
--- a/services/panel-service.c
+++ b/services/panel-service.c
@@ -2159,12 +2159,24 @@ panel_service_show_entry_common (PanelService *self,
g_signal_connect_after (priv->last_menu, "move-current",
G_CALLBACK (on_active_menu_move_current), self);
- gtk_menu_popup (priv->last_menu, NULL, NULL, positon_menu, self, 0, CurrentTime);
- gtk_menu_reposition (priv->last_menu);
+ gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (priv->last_menu), TRUE);
+ gtk_menu_popup (priv->last_menu, NULL, NULL, positon_menu, self, button, CurrentTime);
+ gboolean visible = gtk_widget_is_visible (GTK_WIDGET (priv->last_menu));
- GdkWindow *gdkwin = gtk_widget_get_window (GTK_WIDGET (priv->last_menu));
- if (gdkwin != NULL)
+ if (!visible)
{
+ /* If the menu is not visible at this point, it's very likely that's
+ * due to a keyboard grab, so let's try with a menu with no key-grab */
+ gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (priv->last_menu), FALSE);
+ gtk_menu_popup (priv->last_menu, NULL, NULL, positon_menu, self, button, CurrentTime);
+ visible = gtk_widget_is_visible (GTK_WIDGET (priv->last_menu));
+ }
+
+ if (visible)
+ {
+ gtk_menu_reposition (priv->last_menu);
+
+ GdkWindow *gdkwin = gtk_widget_get_window (GTK_WIDGET (priv->last_menu));
gint left=0, top=0, width=0, height=0;
gdk_window_get_geometry (gdkwin, NULL, NULL, &width, &height);
@@ -2182,10 +2194,7 @@ panel_service_show_entry_common (PanelService *self,
}
else
{
- priv->last_left = 0;
- priv->last_right = 0;
- priv->last_top = 0;
- priv->last_bottom = 0;
+ on_active_menu_hidden (priv->last_menu, self);
}
}
diff --git a/shutdown/SessionController.cpp b/shutdown/SessionController.cpp
index 5fc04a363..0aa8026a3 100644
--- a/shutdown/SessionController.cpp
+++ b/shutdown/SessionController.cpp
@@ -101,8 +101,8 @@ void Controller::Show(View::Mode mode, bool inhibitors)
view_->live_background = true;
view_window_->ShowWindow(true);
- view_window_->PushToFront();
view_window_->SetInputFocus();
+ nux::GetWindowCompositor().SetAlwaysOnFrontWindow(view_window_.GetPointer());
nux::GetWindowCompositor().SetKeyFocusArea(view_->key_focus_area());
animation::StartOrReverse(fade_animator_, animation::Direction::FORWARD);
}
@@ -175,17 +175,19 @@ void Controller::CancelAndHide()
void Controller::Hide()
{
- animation::StartOrReverse(fade_animator_, animation::Direction::BACKWARD);
+ if (view_window_)
+ animation::StartOrReverse(fade_animator_, animation::Direction::BACKWARD);
}
void Controller::CloseWindow()
{
- view_window_->PushToBack();
- view_window_->ShowWindow(false);
view_window_->UnGrabPointer();
view_window_->UnGrabKeyboard();
+ view_window_->ShowWindow(false);
view_window_->EnableInputWindow(false);
- view_->live_background = false;
+
+ view_ = nullptr;
+ view_window_ = nullptr;
nux::GetWindowCompositor().SetKeyFocusArea(nullptr);
WindowManager::Default().RestoreInputFocus();
diff --git a/tests/test_session_controller.cpp b/tests/test_session_controller.cpp
index ce63a1913..f780117c1 100644
--- a/tests/test_session_controller.cpp
+++ b/tests/test_session_controller.cpp
@@ -105,7 +105,8 @@ TEST_F(TestSessionController, Hide)
tick_source.tick(ANIMATION_DURATION);
EXPECT_FALSE(controller.Visible());
- EXPECT_FALSE(controller.view_->live_background());
+ EXPECT_FALSE(controller.view_window_.IsValid());
+ EXPECT_FALSE(controller.view_.IsValid());
}
struct Inhibited : TestSessionController, testing::WithParamInterface<bool> {};