syscall_linux.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
  2. // All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style license that can be
  5. // found in the LICENSE file.
  6. package capability
  7. import (
  8. "syscall"
  9. "unsafe"
  10. )
  11. type capHeader struct {
  12. version uint32
  13. pid int32
  14. }
  15. type capData struct {
  16. effective uint32
  17. permitted uint32
  18. inheritable uint32
  19. }
  20. func capget(hdr *capHeader, data *capData) (err error) {
  21. _, _, e1 := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)
  22. if e1 != 0 {
  23. err = e1
  24. }
  25. return
  26. }
  27. func capset(hdr *capHeader, data *capData) (err error) {
  28. _, _, e1 := syscall.Syscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)
  29. if e1 != 0 {
  30. err = e1
  31. }
  32. return
  33. }
  34. // not yet in syscall
  35. const (
  36. pr_CAP_AMBIENT = 47
  37. pr_CAP_AMBIENT_IS_SET = uintptr(1)
  38. pr_CAP_AMBIENT_RAISE = uintptr(2)
  39. pr_CAP_AMBIENT_LOWER = uintptr(3)
  40. pr_CAP_AMBIENT_CLEAR_ALL = uintptr(4)
  41. )
  42. func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
  43. _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
  44. if e1 != 0 {
  45. err = e1
  46. }
  47. return
  48. }
  49. const (
  50. vfsXattrName = "security.capability"
  51. vfsCapVerMask = 0xff000000
  52. vfsCapVer1 = 0x01000000
  53. vfsCapVer2 = 0x02000000
  54. vfsCapFlagMask = ^vfsCapVerMask
  55. vfsCapFlageffective = 0x000001
  56. vfscapDataSizeV1 = 4 * (1 + 2*1)
  57. vfscapDataSizeV2 = 4 * (1 + 2*2)
  58. )
  59. type vfscapData struct {
  60. magic uint32
  61. data [2]struct {
  62. permitted uint32
  63. inheritable uint32
  64. }
  65. effective [2]uint32
  66. version int8
  67. }
  68. var (
  69. _vfsXattrName *byte
  70. )
  71. func init() {
  72. _vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName)
  73. }
  74. func getVfsCap(path string, dest *vfscapData) (err error) {
  75. var _p0 *byte
  76. _p0, err = syscall.BytePtrFromString(path)
  77. if err != nil {
  78. return
  79. }
  80. r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0)
  81. if e1 != 0 {
  82. if e1 == syscall.ENODATA {
  83. dest.version = 2
  84. return
  85. }
  86. err = e1
  87. }
  88. switch dest.magic & vfsCapVerMask {
  89. case vfsCapVer1:
  90. dest.version = 1
  91. if r0 != vfscapDataSizeV1 {
  92. return syscall.EINVAL
  93. }
  94. dest.data[1].permitted = 0
  95. dest.data[1].inheritable = 0
  96. case vfsCapVer2:
  97. dest.version = 2
  98. if r0 != vfscapDataSizeV2 {
  99. return syscall.EINVAL
  100. }
  101. default:
  102. return syscall.EINVAL
  103. }
  104. if dest.magic&vfsCapFlageffective != 0 {
  105. dest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable
  106. dest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable
  107. } else {
  108. dest.effective[0] = 0
  109. dest.effective[1] = 0
  110. }
  111. return
  112. }
  113. func setVfsCap(path string, data *vfscapData) (err error) {
  114. var _p0 *byte
  115. _p0, err = syscall.BytePtrFromString(path)
  116. if err != nil {
  117. return
  118. }
  119. var size uintptr
  120. if data.version == 1 {
  121. data.magic = vfsCapVer1
  122. size = vfscapDataSizeV1
  123. } else if data.version == 2 {
  124. data.magic = vfsCapVer2
  125. if data.effective[0] != 0 || data.effective[1] != 0 {
  126. data.magic |= vfsCapFlageffective
  127. }
  128. size = vfscapDataSizeV2
  129. } else {
  130. return syscall.EINVAL
  131. }
  132. _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0)
  133. if e1 != 0 {
  134. err = e1
  135. }
  136. return
  137. }