services/device: Fix multiuser mode
In multiuser mode the security agent socket needs to be chown'ed
to the userid the app is running as by using the suidhelper.
Change-Id: Ia2c7f6c432fec9e3645a608caa4a2caad87835c6
diff --git a/services/device/deviced/doc.go b/services/device/deviced/doc.go
index b89a60b..efea027 100644
--- a/services/device/deviced/doc.go
+++ b/services/device/deviced/doc.go
@@ -41,6 +41,8 @@
generate a pairing token for the device manager that will need to be provided
when a device is claimed
+ -agentsock=
+ Path to the application's security agent socket.
-alsologtostderr=true
log to standard error as well as files
-chown=false
diff --git a/services/device/deviced/internal/impl/app_service.go b/services/device/deviced/internal/impl/app_service.go
index dca7113..56dd7bc 100644
--- a/services/device/deviced/internal/impl/app_service.go
+++ b/services/device/deviced/internal/impl/app_service.go
@@ -834,7 +834,7 @@
return instanceDir, instanceID, nil
}
-func genCmd(ctx *context.T, instanceDir string, nsRoot string) (*exec.Cmd, error) {
+func genCmd(ctx *context.T, instanceDir, nsRoot string, usingSocketAgent bool) (*exec.Cmd, error) {
systemName, err := readSystemNameForInstance(instanceDir)
if err != nil {
return nil, err
@@ -855,6 +855,11 @@
}
saArgs := suidAppCmdArgs{targetUser: systemName, binpath: binPath}
+ if usingSocketAgent {
+ if saArgs.sockPath, err = sockPath(instanceDir); err != nil {
+ return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("failed to obtain agent socket path: %v", err))
+ }
+ }
// Pass the displayed name of the program (argv0 as seen in ps output)
// Envelope data comes from the user so we sanitize it for safety
@@ -1053,13 +1058,17 @@
return pid, nil
}
+func (i *appRunner) usingSocketAgent() bool {
+ return i.securityAgent != nil && i.securityAgent.keyMgr != nil
+}
+
func (i *appRunner) run(ctx *context.T, instanceDir string) error {
if err := transitionInstance(instanceDir, device.InstanceStateNotRunning, device.InstanceStateLaunching); err != nil {
return err
}
var pid int
- cmd, err := genCmd(ctx, instanceDir, i.mtAddress)
+ cmd, err := genCmd(ctx, instanceDir, i.mtAddress, i.usingSocketAgent())
if err == nil {
pid, err = i.startCmd(ctx, instanceDir, cmd)
}
@@ -1736,7 +1745,7 @@
} else {
debugInfo.Info = info
}
- if cmd, err := genCmd(ctx, instanceDir, i.runner.mtAddress); err != nil {
+ if cmd, err := genCmd(ctx, instanceDir, i.runner.mtAddress, i.runner.usingSocketAgent()); err != nil {
return "", err
} else {
debugInfo.Cmd = cmd
diff --git a/services/device/deviced/internal/impl/helper_manager.go b/services/device/deviced/internal/impl/helper_manager.go
index 45829d0..2d65694 100644
--- a/services/device/deviced/internal/impl/helper_manager.go
+++ b/services/device/deviced/internal/impl/helper_manager.go
@@ -76,7 +76,7 @@
type suidAppCmdArgs struct {
// args to helper
- targetUser, progname, workspace, logdir, binpath string
+ targetUser, progname, workspace, logdir, binpath, sockPath string
// fields in exec.Cmd
env []string
stdout, stderr io.Writer
@@ -105,6 +105,9 @@
cmd.Args = append(cmd.Args, "--progname", a.progname)
cmd.Args = append(cmd.Args, "--workspace", a.workspace)
cmd.Args = append(cmd.Args, "--logdir", a.logdir)
+ if a.sockPath != "" {
+ cmd.Args = append(cmd.Args, "--agentsock", a.sockPath)
+ }
cmd.Args = append(cmd.Args, "--run", a.binpath)
cmd.Args = append(cmd.Args, "--")
diff --git a/services/device/internal/suid/args.go b/services/device/internal/suid/args.go
index 1473654..d9ab2fb 100644
--- a/services/device/internal/suid/args.go
+++ b/services/device/internal/suid/args.go
@@ -33,6 +33,7 @@
uid int
gid int
workspace string
+ agentsock string
logDir string
argv0 string
argv []string
@@ -54,9 +55,9 @@
const SavedArgs = "V23_SAVED_ARGS"
var (
- flagUsername, flagWorkspace, flagLogDir, flagRun, flagProgName *string
- flagMinimumUid *int64
- flagRemove, flagKill, flagChown, flagDryrun *bool
+ flagUsername, flagWorkspace, flagLogDir, flagRun, flagProgName, flagAgentSock *string
+ flagMinimumUid *int64
+ flagRemove, flagKill, flagChown, flagDryrun *bool
)
func init() {
@@ -67,6 +68,7 @@
const uidThreshold = 501
flagUsername = fs.String("username", "", "The UNIX user name used for the other functions of this tool.")
flagWorkspace = fs.String("workspace", "", "Path to the application's workspace directory.")
+ flagAgentSock = fs.String("agentsock", "", "Path to the application's security agent socket.")
flagLogDir = fs.String("logdir", "", "Path to the log directory.")
flagRun = fs.String("run", "", "Path to the application to exec.")
flagProgName = fs.String("progname", "unnamed_app", "Visible name of the application, used in argv[0]")
@@ -218,6 +220,7 @@
}
wp.workspace = *flagWorkspace
+ wp.agentsock = *flagAgentSock
wp.argv0 = *flagRun
wp.logDir = *flagLogDir
wp.argv = append([]string{*flagProgName}, fs.Args()...)
diff --git a/services/device/internal/suid/args_test.go b/services/device/internal/suid/args_test.go
index 491a171..d910b51 100644
--- a/services/device/internal/suid/args_test.go
+++ b/services/device/internal/suid/args_test.go
@@ -35,6 +35,7 @@
uid: testUid,
gid: testGid,
workspace: "",
+ agentsock: "",
logDir: "",
argv0: "",
argv: []string{"unnamed_app"},
@@ -49,13 +50,14 @@
{
[]string{"setuidhelper", "--minuid", "1", "--username", testUserName, "--workspace", "/hello",
- "--logdir", "/logging", "--run", "/bin/v23", "--", "one", "two"},
+ "--logdir", "/logging", "--agentsock", "/tmp/sXXXX", "--run", "/bin/v23", "--", "one", "two"},
[]string{"A=B"},
"",
WorkParameters{
uid: testUid,
gid: testGid,
workspace: "/hello",
+ agentsock: "/tmp/sXXXX",
logDir: "/logging",
argv0: "/bin/v23",
argv: []string{"unnamed_app", "one", "two"},
@@ -83,6 +85,7 @@
uid: 0,
gid: 0,
workspace: "",
+ agentsock: "",
logDir: "",
argv0: "",
argv: []string{"hello", "vanadium"},
@@ -103,6 +106,7 @@
uid: testUid,
gid: testGid,
workspace: "",
+ agentsock: "",
logDir: "",
argv0: "",
argv: []string{"/tmp/foo", "/tmp/bar"},
@@ -123,6 +127,7 @@
uid: 0,
gid: 0,
workspace: "",
+ agentsock: "",
logDir: "",
argv0: "",
argv: nil,
@@ -143,6 +148,7 @@
uid: 0,
gid: 0,
workspace: "",
+ agentsock: "",
logDir: "",
argv0: "",
argv: nil,
@@ -157,13 +163,14 @@
{
[]string{"setuidhelper", "--minuid", "1", "--username", testUserName, "--workspace", "/hello", "--progname", "binaryd/vanadium/app/testapp",
- "--logdir", "/logging", "--run", "/bin/v23", "--dryrun", "--", "one", "two"},
+ "--logdir", "/logging", "--agentsock", "/tmp/2981298123/s", "--run", "/bin/v23", "--dryrun", "--", "one", "two"},
[]string{"A=B"},
"",
WorkParameters{
uid: testUid,
gid: testGid,
workspace: "/hello",
+ agentsock: "/tmp/2981298123/s",
logDir: "/logging",
argv0: "/bin/v23",
argv: []string{"binaryd/vanadium/app/testapp", "one", "two"},
diff --git a/services/device/internal/suid/system.go b/services/device/internal/suid/system.go
index c647558..0b80e4d 100644
--- a/services/device/internal/suid/system.go
+++ b/services/device/internal/suid/system.go
@@ -42,9 +42,13 @@
chownPaths := hw.argv
if !hw.chown {
// Chown was invoked as part of regular suid execution, rather than directly
- // via --chown. In that case, we chown the workspace and log directory
+ // via --chown. In that case, we chown the workspace, log directory, and,
+ // if specified, the agent socket path
// TODO(rjkroege): Ensure that the device manager can read log entries.
chownPaths = []string{hw.workspace, hw.logDir}
+ if hw.agentsock != "" {
+ chownPaths = append(chownPaths, hw.agentsock)
+ }
}
for _, p := range chownPaths {