capability_linux.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  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. "bufio"
  9. "errors"
  10. "fmt"
  11. "io"
  12. "os"
  13. "strings"
  14. "syscall"
  15. )
  16. var errUnknownVers = errors.New("unknown capability version")
  17. const (
  18. linuxCapVer1 = 0x19980330
  19. linuxCapVer2 = 0x20071026
  20. linuxCapVer3 = 0x20080522
  21. )
  22. var (
  23. capVers uint32
  24. capLastCap Cap
  25. )
  26. func init() {
  27. var hdr capHeader
  28. capget(&hdr, nil)
  29. capVers = hdr.version
  30. if initLastCap() == nil {
  31. CAP_LAST_CAP = capLastCap
  32. if capLastCap > 31 {
  33. capUpperMask = (uint32(1) << (uint(capLastCap) - 31)) - 1
  34. } else {
  35. capUpperMask = 0
  36. }
  37. }
  38. }
  39. func initLastCap() error {
  40. if capLastCap != 0 {
  41. return nil
  42. }
  43. f, err := os.Open("/proc/sys/kernel/cap_last_cap")
  44. if err != nil {
  45. return err
  46. }
  47. defer f.Close()
  48. var b []byte = make([]byte, 11)
  49. _, err = f.Read(b)
  50. if err != nil {
  51. return err
  52. }
  53. fmt.Sscanf(string(b), "%d", &capLastCap)
  54. return nil
  55. }
  56. func mkStringCap(c Capabilities, which CapType) (ret string) {
  57. for i, first := Cap(0), true; i <= CAP_LAST_CAP; i++ {
  58. if !c.Get(which, i) {
  59. continue
  60. }
  61. if first {
  62. first = false
  63. } else {
  64. ret += ", "
  65. }
  66. ret += i.String()
  67. }
  68. return
  69. }
  70. func mkString(c Capabilities, max CapType) (ret string) {
  71. ret = "{"
  72. for i := CapType(1); i <= max; i <<= 1 {
  73. ret += " " + i.String() + "=\""
  74. if c.Empty(i) {
  75. ret += "empty"
  76. } else if c.Full(i) {
  77. ret += "full"
  78. } else {
  79. ret += c.StringCap(i)
  80. }
  81. ret += "\""
  82. }
  83. ret += " }"
  84. return
  85. }
  86. func newPid(pid int) (c Capabilities, err error) {
  87. switch capVers {
  88. case linuxCapVer1:
  89. p := new(capsV1)
  90. p.hdr.version = capVers
  91. p.hdr.pid = pid
  92. c = p
  93. case linuxCapVer2, linuxCapVer3:
  94. p := new(capsV3)
  95. p.hdr.version = capVers
  96. p.hdr.pid = pid
  97. c = p
  98. default:
  99. err = errUnknownVers
  100. return
  101. }
  102. err = c.Load()
  103. if err != nil {
  104. c = nil
  105. }
  106. return
  107. }
  108. type capsV1 struct {
  109. hdr capHeader
  110. data capData
  111. }
  112. func (c *capsV1) Get(which CapType, what Cap) bool {
  113. if what > 32 {
  114. return false
  115. }
  116. switch which {
  117. case EFFECTIVE:
  118. return (1<<uint(what))&c.data.effective != 0
  119. case PERMITTED:
  120. return (1<<uint(what))&c.data.permitted != 0
  121. case INHERITABLE:
  122. return (1<<uint(what))&c.data.inheritable != 0
  123. }
  124. return false
  125. }
  126. func (c *capsV1) getData(which CapType) (ret uint32) {
  127. switch which {
  128. case EFFECTIVE:
  129. ret = c.data.effective
  130. case PERMITTED:
  131. ret = c.data.permitted
  132. case INHERITABLE:
  133. ret = c.data.inheritable
  134. }
  135. return
  136. }
  137. func (c *capsV1) Empty(which CapType) bool {
  138. return c.getData(which) == 0
  139. }
  140. func (c *capsV1) Full(which CapType) bool {
  141. return (c.getData(which) & 0x7fffffff) == 0x7fffffff
  142. }
  143. func (c *capsV1) Set(which CapType, caps ...Cap) {
  144. for _, what := range caps {
  145. if what > 32 {
  146. continue
  147. }
  148. if which&EFFECTIVE != 0 {
  149. c.data.effective |= 1 << uint(what)
  150. }
  151. if which&PERMITTED != 0 {
  152. c.data.permitted |= 1 << uint(what)
  153. }
  154. if which&INHERITABLE != 0 {
  155. c.data.inheritable |= 1 << uint(what)
  156. }
  157. }
  158. }
  159. func (c *capsV1) Unset(which CapType, caps ...Cap) {
  160. for _, what := range caps {
  161. if what > 32 {
  162. continue
  163. }
  164. if which&EFFECTIVE != 0 {
  165. c.data.effective &= ^(1 << uint(what))
  166. }
  167. if which&PERMITTED != 0 {
  168. c.data.permitted &= ^(1 << uint(what))
  169. }
  170. if which&INHERITABLE != 0 {
  171. c.data.inheritable &= ^(1 << uint(what))
  172. }
  173. }
  174. }
  175. func (c *capsV1) Fill(kind CapType) {
  176. if kind&CAPS == CAPS {
  177. c.data.effective = 0x7fffffff
  178. c.data.permitted = 0x7fffffff
  179. c.data.inheritable = 0
  180. }
  181. }
  182. func (c *capsV1) Clear(kind CapType) {
  183. if kind&CAPS == CAPS {
  184. c.data.effective = 0
  185. c.data.permitted = 0
  186. c.data.inheritable = 0
  187. }
  188. }
  189. func (c *capsV1) StringCap(which CapType) (ret string) {
  190. return mkStringCap(c, which)
  191. }
  192. func (c *capsV1) String() (ret string) {
  193. return mkString(c, BOUNDING)
  194. }
  195. func (c *capsV1) Load() (err error) {
  196. return capget(&c.hdr, &c.data)
  197. }
  198. func (c *capsV1) Apply(kind CapType) error {
  199. if kind&CAPS == CAPS {
  200. return capset(&c.hdr, &c.data)
  201. }
  202. return nil
  203. }
  204. type capsV3 struct {
  205. hdr capHeader
  206. data [2]capData
  207. bounds [2]uint32
  208. }
  209. func (c *capsV3) Get(which CapType, what Cap) bool {
  210. var i uint
  211. if what > 31 {
  212. i = uint(what) >> 5
  213. what %= 32
  214. }
  215. switch which {
  216. case EFFECTIVE:
  217. return (1<<uint(what))&c.data[i].effective != 0
  218. case PERMITTED:
  219. return (1<<uint(what))&c.data[i].permitted != 0
  220. case INHERITABLE:
  221. return (1<<uint(what))&c.data[i].inheritable != 0
  222. case BOUNDING:
  223. return (1<<uint(what))&c.bounds[i] != 0
  224. }
  225. return false
  226. }
  227. func (c *capsV3) getData(which CapType, dest []uint32) {
  228. switch which {
  229. case EFFECTIVE:
  230. dest[0] = c.data[0].effective
  231. dest[1] = c.data[1].effective
  232. case PERMITTED:
  233. dest[0] = c.data[0].permitted
  234. dest[1] = c.data[1].permitted
  235. case INHERITABLE:
  236. dest[0] = c.data[0].inheritable
  237. dest[1] = c.data[1].inheritable
  238. case BOUNDING:
  239. dest[0] = c.bounds[0]
  240. dest[1] = c.bounds[1]
  241. }
  242. }
  243. func (c *capsV3) Empty(which CapType) bool {
  244. var data [2]uint32
  245. c.getData(which, data[:])
  246. return data[0] == 0 && data[1] == 0
  247. }
  248. func (c *capsV3) Full(which CapType) bool {
  249. var data [2]uint32
  250. c.getData(which, data[:])
  251. if (data[0] & 0xffffffff) != 0xffffffff {
  252. return false
  253. }
  254. return (data[1] & capUpperMask) == capUpperMask
  255. }
  256. func (c *capsV3) Set(which CapType, caps ...Cap) {
  257. for _, what := range caps {
  258. var i uint
  259. if what > 31 {
  260. i = uint(what) >> 5
  261. what %= 32
  262. }
  263. if which&EFFECTIVE != 0 {
  264. c.data[i].effective |= 1 << uint(what)
  265. }
  266. if which&PERMITTED != 0 {
  267. c.data[i].permitted |= 1 << uint(what)
  268. }
  269. if which&INHERITABLE != 0 {
  270. c.data[i].inheritable |= 1 << uint(what)
  271. }
  272. if which&BOUNDING != 0 {
  273. c.bounds[i] |= 1 << uint(what)
  274. }
  275. }
  276. }
  277. func (c *capsV3) Unset(which CapType, caps ...Cap) {
  278. for _, what := range caps {
  279. var i uint
  280. if what > 31 {
  281. i = uint(what) >> 5
  282. what %= 32
  283. }
  284. if which&EFFECTIVE != 0 {
  285. c.data[i].effective &= ^(1 << uint(what))
  286. }
  287. if which&PERMITTED != 0 {
  288. c.data[i].permitted &= ^(1 << uint(what))
  289. }
  290. if which&INHERITABLE != 0 {
  291. c.data[i].inheritable &= ^(1 << uint(what))
  292. }
  293. if which&BOUNDING != 0 {
  294. c.bounds[i] &= ^(1 << uint(what))
  295. }
  296. }
  297. }
  298. func (c *capsV3) Fill(kind CapType) {
  299. if kind&CAPS == CAPS {
  300. c.data[0].effective = 0xffffffff
  301. c.data[0].permitted = 0xffffffff
  302. c.data[0].inheritable = 0
  303. c.data[1].effective = 0xffffffff
  304. c.data[1].permitted = 0xffffffff
  305. c.data[1].inheritable = 0
  306. }
  307. if kind&BOUNDS == BOUNDS {
  308. c.bounds[0] = 0xffffffff
  309. c.bounds[1] = 0xffffffff
  310. }
  311. }
  312. func (c *capsV3) Clear(kind CapType) {
  313. if kind&CAPS == CAPS {
  314. c.data[0].effective = 0
  315. c.data[0].permitted = 0
  316. c.data[0].inheritable = 0
  317. c.data[1].effective = 0
  318. c.data[1].permitted = 0
  319. c.data[1].inheritable = 0
  320. }
  321. if kind&BOUNDS == BOUNDS {
  322. c.bounds[0] = 0
  323. c.bounds[1] = 0
  324. }
  325. }
  326. func (c *capsV3) StringCap(which CapType) (ret string) {
  327. return mkStringCap(c, which)
  328. }
  329. func (c *capsV3) String() (ret string) {
  330. return mkString(c, BOUNDING)
  331. }
  332. func (c *capsV3) Load() (err error) {
  333. err = capget(&c.hdr, &c.data[0])
  334. if err != nil {
  335. return
  336. }
  337. var status_path string
  338. if c.hdr.pid == 0 {
  339. status_path = fmt.Sprintf("/proc/self/status")
  340. } else {
  341. status_path = fmt.Sprintf("/proc/%d/status", c.hdr.pid)
  342. }
  343. f, err := os.Open(status_path)
  344. if err != nil {
  345. return
  346. }
  347. b := bufio.NewReader(f)
  348. for {
  349. line, e := b.ReadString('\n')
  350. if e != nil {
  351. if e != io.EOF {
  352. err = e
  353. }
  354. break
  355. }
  356. if strings.HasPrefix(line, "CapB") {
  357. fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0])
  358. break
  359. }
  360. }
  361. f.Close()
  362. return
  363. }
  364. func (c *capsV3) Apply(kind CapType) (err error) {
  365. if kind&BOUNDS == BOUNDS {
  366. var data [2]capData
  367. err = capget(&c.hdr, &data[0])
  368. if err != nil {
  369. return
  370. }
  371. if (1<<uint(CAP_SETPCAP))&data[0].effective != 0 {
  372. for i := Cap(0); i <= CAP_LAST_CAP; i++ {
  373. if c.Get(BOUNDING, i) {
  374. continue
  375. }
  376. err = prctl(syscall.PR_CAPBSET_DROP, uintptr(i), 0, 0, 0)
  377. if err != nil {
  378. // Ignore EINVAL since the capability may not be supported in this system.
  379. if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
  380. err = nil
  381. continue
  382. }
  383. return
  384. }
  385. }
  386. }
  387. }
  388. if kind&CAPS == CAPS {
  389. return capset(&c.hdr, &c.data[0])
  390. }
  391. return
  392. }
  393. func newFile(path string) (c Capabilities, err error) {
  394. c = &capsFile{path: path}
  395. err = c.Load()
  396. if err != nil {
  397. c = nil
  398. }
  399. return
  400. }
  401. type capsFile struct {
  402. path string
  403. data vfscapData
  404. }
  405. func (c *capsFile) Get(which CapType, what Cap) bool {
  406. var i uint
  407. if what > 31 {
  408. if c.data.version == 1 {
  409. return false
  410. }
  411. i = uint(what) >> 5
  412. what %= 32
  413. }
  414. switch which {
  415. case EFFECTIVE:
  416. return (1<<uint(what))&c.data.effective[i] != 0
  417. case PERMITTED:
  418. return (1<<uint(what))&c.data.data[i].permitted != 0
  419. case INHERITABLE:
  420. return (1<<uint(what))&c.data.data[i].inheritable != 0
  421. }
  422. return false
  423. }
  424. func (c *capsFile) getData(which CapType, dest []uint32) {
  425. switch which {
  426. case EFFECTIVE:
  427. dest[0] = c.data.effective[0]
  428. dest[1] = c.data.effective[1]
  429. case PERMITTED:
  430. dest[0] = c.data.data[0].permitted
  431. dest[1] = c.data.data[1].permitted
  432. case INHERITABLE:
  433. dest[0] = c.data.data[0].inheritable
  434. dest[1] = c.data.data[1].inheritable
  435. }
  436. }
  437. func (c *capsFile) Empty(which CapType) bool {
  438. var data [2]uint32
  439. c.getData(which, data[:])
  440. return data[0] == 0 && data[1] == 0
  441. }
  442. func (c *capsFile) Full(which CapType) bool {
  443. var data [2]uint32
  444. c.getData(which, data[:])
  445. if c.data.version == 0 {
  446. return (data[0] & 0x7fffffff) == 0x7fffffff
  447. }
  448. if (data[0] & 0xffffffff) != 0xffffffff {
  449. return false
  450. }
  451. return (data[1] & capUpperMask) == capUpperMask
  452. }
  453. func (c *capsFile) Set(which CapType, caps ...Cap) {
  454. for _, what := range caps {
  455. var i uint
  456. if what > 31 {
  457. if c.data.version == 1 {
  458. continue
  459. }
  460. i = uint(what) >> 5
  461. what %= 32
  462. }
  463. if which&EFFECTIVE != 0 {
  464. c.data.effective[i] |= 1 << uint(what)
  465. }
  466. if which&PERMITTED != 0 {
  467. c.data.data[i].permitted |= 1 << uint(what)
  468. }
  469. if which&INHERITABLE != 0 {
  470. c.data.data[i].inheritable |= 1 << uint(what)
  471. }
  472. }
  473. }
  474. func (c *capsFile) Unset(which CapType, caps ...Cap) {
  475. for _, what := range caps {
  476. var i uint
  477. if what > 31 {
  478. if c.data.version == 1 {
  479. continue
  480. }
  481. i = uint(what) >> 5
  482. what %= 32
  483. }
  484. if which&EFFECTIVE != 0 {
  485. c.data.effective[i] &= ^(1 << uint(what))
  486. }
  487. if which&PERMITTED != 0 {
  488. c.data.data[i].permitted &= ^(1 << uint(what))
  489. }
  490. if which&INHERITABLE != 0 {
  491. c.data.data[i].inheritable &= ^(1 << uint(what))
  492. }
  493. }
  494. }
  495. func (c *capsFile) Fill(kind CapType) {
  496. if kind&CAPS == CAPS {
  497. c.data.effective[0] = 0xffffffff
  498. c.data.data[0].permitted = 0xffffffff
  499. c.data.data[0].inheritable = 0
  500. if c.data.version == 2 {
  501. c.data.effective[1] = 0xffffffff
  502. c.data.data[1].permitted = 0xffffffff
  503. c.data.data[1].inheritable = 0
  504. }
  505. }
  506. }
  507. func (c *capsFile) Clear(kind CapType) {
  508. if kind&CAPS == CAPS {
  509. c.data.effective[0] = 0
  510. c.data.data[0].permitted = 0
  511. c.data.data[0].inheritable = 0
  512. if c.data.version == 2 {
  513. c.data.effective[1] = 0
  514. c.data.data[1].permitted = 0
  515. c.data.data[1].inheritable = 0
  516. }
  517. }
  518. }
  519. func (c *capsFile) StringCap(which CapType) (ret string) {
  520. return mkStringCap(c, which)
  521. }
  522. func (c *capsFile) String() (ret string) {
  523. return mkString(c, INHERITABLE)
  524. }
  525. func (c *capsFile) Load() (err error) {
  526. return getVfsCap(c.path, &c.data)
  527. }
  528. func (c *capsFile) Apply(kind CapType) (err error) {
  529. if kind&CAPS == CAPS {
  530. return setVfsCap(c.path, &c.data)
  531. }
  532. return
  533. }