进一步阅读

进一步阅读

我正在调试一个程序,不太清楚为什么我不能放弃特权。

我有 root 权限sudo,可以调用,但不支持setgid/setuid该操作。[is]

重现的基本代码(golang):

package main

import (
    "fmt"
    "os"
    "strconv"
    "syscall"
)

func main() {
    if os.Getuid() != 0 {
        fmt.Println("run as root")
        os.Exit(1)
    }

    uid, err := strconv.Atoi(os.Getenv("SUDO_UID"))
    check("", err)

    gid, err := strconv.Atoi(os.Getenv("SUDO_GID"))
    check("", err)

    fmt.Printf("uid: %d, gid: %d\n", uid, gid)

    check("gid", syscall.Setgid(gid))
    check("uid", syscall.Setuid(uid))
}

func check(message string, err error) {
    if err != nil {
        fmt.Printf("%s: %s\n", message, err)
        os.Exit(1)
    }
}

输出示例:

$ sudo ./drop-sudo 
uid: 1000, gid: 1000
gid: operation not supported

系统信息:

$ uname -a
Linux user2460234 4.15.0-34-generic #37-Ubuntu SMP Mon Aug 27 15:21:48 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

答案1

你的编程语言根本不支持这些东西。

由于 Linux 的架构,在 Linux 上做这些事情很复杂。 C 库(例如 GNU 和 musl)隐藏了这种复杂性。它仍然是 Linux 上线程的已知问题之一。

Go 语言没有复制 C 库的机制。 目前这些功能的实现不是系统调用,也没有被自2014年起

进一步阅读

答案2

您可以检查库卡,它有一个官方围棋库例子。该示例用于psx.Syscall3(syscall.SYS_SETUID,...)设置 uid(如@JdeBP说,go 删除了 ) 的实现syscall.Setuid()。这PSX库是 libcap 的一部分。

psx 包提供了一个 CGo 支持的 API,用于调用系统调用,每个系统调用都镜像在组合 Go/CGo 运行时的所有 pthread 上。由于 Go 运行时将所有 pthread 视为可互换的,因此需要这样的功能来有意义地更改在 Linux 上运行的 Go 程序中的进程权限(包括删除权限)

答案3

作为去1.16syscall.Setuid()Linux下完全支持朋友们。

也就是说,本问题中提供的重现程序,使用 Linux 下的 go1.16 工具链编译,将构建一个按预期工作的程序。所有关于它不起作用的观察结果仅适用于 Linux 下的早期 go 工具链版本。

PSXpackage 也可以用来让类似的东西在早期的 go 工具链中工作(如 ivzhh 所指出的)。

相关内容