syscall_linux.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright (c) 2013, Suryandaru Triandana <[email protected]>
  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 int
  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. func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
  35. _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
  36. if e1 != 0 {
  37. err = e1
  38. }
  39. return
  40. }
  41. const (
  42. vfsXattrName = "security.capability"
  43. vfsCapVerMask = 0xff000000
  44. vfsCapVer1 = 0x01000000
  45. vfsCapVer2 = 0x02000000
  46. vfsCapFlagMask = ^vfsCapVerMask
  47. vfsCapFlageffective = 0x000001
  48. vfscapDataSizeV1 = 4 * (1 + 2*1)
  49. vfscapDataSizeV2 = 4 * (1 + 2*2)
  50. )
  51. type vfscapData struct {
  52. magic uint32
  53. data [2]struct {
  54. permitted uint32
  55. inheritable uint32
  56. }
  57. effective [2]uint32
  58. version int8
  59. }
  60. var (
  61. _vfsXattrName *byte
  62. )
  63. func init() {
  64. _vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName)
  65. }
  66. func getVfsCap(path string, dest *vfscapData) (err error) {
  67. var _p0 *byte
  68. _p0, err = syscall.BytePtrFromString(path)
  69. if err != nil {
  70. return
  71. }
  72. r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0)
  73. if e1 != 0 {
  74. if e1 == syscall.ENODATA {
  75. dest.version = 2
  76. return
  77. }
  78. err = e1
  79. }
  80. switch dest.magic & vfsCapVerMask {
  81. case vfsCapVer1:
  82. dest.version = 1
  83. if r0 != vfscapDataSizeV1 {
  84. return syscall.EINVAL
  85. }
  86. dest.data[1].permitted = 0
  87. dest.data[1].inheritable = 0
  88. case vfsCapVer2:
  89. dest.version = 2
  90. if r0 != vfscapDataSizeV2 {
  91. return syscall.EINVAL
  92. }
  93. default:
  94. return syscall.EINVAL
  95. }
  96. if dest.magic&vfsCapFlageffective != 0 {
  97. dest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable
  98. dest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable
  99. } else {
  100. dest.effective[0] = 0
  101. dest.effective[1] = 0
  102. }
  103. return
  104. }
  105. func setVfsCap(path string, data *vfscapData) (err error) {
  106. var _p0 *byte
  107. _p0, err = syscall.BytePtrFromString(path)
  108. if err != nil {
  109. return
  110. }
  111. var size uintptr
  112. if data.version == 1 {
  113. data.magic = vfsCapVer1
  114. size = vfscapDataSizeV1
  115. } else if data.version == 2 {
  116. data.magic = vfsCapVer2
  117. if data.effective[0] != 0 || data.effective[1] != 0 {
  118. data.magic |= vfsCapFlageffective
  119. }
  120. size = vfscapDataSizeV2
  121. } else {
  122. return syscall.EINVAL
  123. }
  124. _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0)
  125. if e1 != 0 {
  126. err = e1
  127. }
  128. return
  129. }