capability_linux.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  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. "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 = int32(pid)
  92. c = p
  93. case linuxCapVer2, linuxCapVer3:
  94. p := new(capsV3)
  95. p.hdr.version = capVers
  96. p.hdr.pid = int32(pid)
  97. c = p
  98. default:
  99. err = errUnknownVers
  100. return
  101. }
  102. return
  103. }
  104. type capsV1 struct {
  105. hdr capHeader
  106. data capData
  107. }
  108. func (c *capsV1) Get(which CapType, what Cap) bool {
  109. if what > 32 {
  110. return false
  111. }
  112. switch which {
  113. case EFFECTIVE:
  114. return (1<<uint(what))&c.data.effective != 0
  115. case PERMITTED:
  116. return (1<<uint(what))&c.data.permitted != 0
  117. case INHERITABLE:
  118. return (1<<uint(what))&c.data.inheritable != 0
  119. }
  120. return false
  121. }
  122. func (c *capsV1) getData(which CapType) (ret uint32) {
  123. switch which {
  124. case EFFECTIVE:
  125. ret = c.data.effective
  126. case PERMITTED:
  127. ret = c.data.permitted
  128. case INHERITABLE:
  129. ret = c.data.inheritable
  130. }
  131. return
  132. }
  133. func (c *capsV1) Empty(which CapType) bool {
  134. return c.getData(which) == 0
  135. }
  136. func (c *capsV1) Full(which CapType) bool {
  137. return (c.getData(which) & 0x7fffffff) == 0x7fffffff
  138. }
  139. func (c *capsV1) Set(which CapType, caps ...Cap) {
  140. for _, what := range caps {
  141. if what > 32 {
  142. continue
  143. }
  144. if which&EFFECTIVE != 0 {
  145. c.data.effective |= 1 << uint(what)
  146. }
  147. if which&PERMITTED != 0 {
  148. c.data.permitted |= 1 << uint(what)
  149. }
  150. if which&INHERITABLE != 0 {
  151. c.data.inheritable |= 1 << uint(what)
  152. }
  153. }
  154. }
  155. func (c *capsV1) Unset(which CapType, caps ...Cap) {
  156. for _, what := range caps {
  157. if what > 32 {
  158. continue
  159. }
  160. if which&EFFECTIVE != 0 {
  161. c.data.effective &= ^(1 << uint(what))
  162. }
  163. if which&PERMITTED != 0 {
  164. c.data.permitted &= ^(1 << uint(what))
  165. }
  166. if which&INHERITABLE != 0 {
  167. c.data.inheritable &= ^(1 << uint(what))
  168. }
  169. }
  170. }
  171. func (c *capsV1) Fill(kind CapType) {
  172. if kind&CAPS == CAPS {
  173. c.data.effective = 0x7fffffff
  174. c.data.permitted = 0x7fffffff
  175. c.data.inheritable = 0
  176. }
  177. }
  178. func (c *capsV1) Clear(kind CapType) {
  179. if kind&CAPS == CAPS {
  180. c.data.effective = 0
  181. c.data.permitted = 0
  182. c.data.inheritable = 0
  183. }
  184. }
  185. func (c *capsV1) StringCap(which CapType) (ret string) {
  186. return mkStringCap(c, which)
  187. }
  188. func (c *capsV1) String() (ret string) {
  189. return mkString(c, BOUNDING)
  190. }
  191. func (c *capsV1) Load() (err error) {
  192. return capget(&c.hdr, &c.data)
  193. }
  194. func (c *capsV1) Apply(kind CapType) error {
  195. if kind&CAPS == CAPS {
  196. return capset(&c.hdr, &c.data)
  197. }
  198. return nil
  199. }
  200. type capsV3 struct {
  201. hdr capHeader
  202. data [2]capData
  203. bounds [2]uint32
  204. ambient [2]uint32
  205. }
  206. func (c *capsV3) Get(which CapType, what Cap) bool {
  207. var i uint
  208. if what > 31 {
  209. i = uint(what) >> 5
  210. what %= 32
  211. }
  212. switch which {
  213. case EFFECTIVE:
  214. return (1<<uint(what))&c.data[i].effective != 0
  215. case PERMITTED:
  216. return (1<<uint(what))&c.data[i].permitted != 0
  217. case INHERITABLE:
  218. return (1<<uint(what))&c.data[i].inheritable != 0
  219. case BOUNDING:
  220. return (1<<uint(what))&c.bounds[i] != 0
  221. case AMBIENT:
  222. return (1<<uint(what))&c.ambient[i] != 0
  223. }
  224. return false
  225. }
  226. func (c *capsV3) getData(which CapType, dest []uint32) {
  227. switch which {
  228. case EFFECTIVE:
  229. dest[0] = c.data[0].effective
  230. dest[1] = c.data[1].effective
  231. case PERMITTED:
  232. dest[0] = c.data[0].permitted
  233. dest[1] = c.data[1].permitted
  234. case INHERITABLE:
  235. dest[0] = c.data[0].inheritable
  236. dest[1] = c.data[1].inheritable
  237. case BOUNDING:
  238. dest[0] = c.bounds[0]
  239. dest[1] = c.bounds[1]
  240. case AMBIENT:
  241. dest[0] = c.ambient[0]
  242. dest[1] = c.ambient[1]
  243. }
  244. }
  245. func (c *capsV3) Empty(which CapType) bool {
  246. var data [2]uint32
  247. c.getData(which, data[:])
  248. return data[0] == 0 && data[1] == 0
  249. }
  250. func (c *capsV3) Full(which CapType) bool {
  251. var data [2]uint32
  252. c.getData(which, data[:])
  253. if (data[0] & 0xffffffff) != 0xffffffff {
  254. return false
  255. }
  256. return (data[1] & capUpperMask) == capUpperMask
  257. }
  258. func (c *capsV3) Set(which CapType, caps ...Cap) {
  259. for _, what := range caps {
  260. var i uint
  261. if what > 31 {
  262. i = uint(what) >> 5
  263. what %= 32
  264. }
  265. if which&EFFECTIVE != 0 {
  266. c.data[i].effective |= 1 << uint(what)
  267. }
  268. if which&PERMITTED != 0 {
  269. c.data[i].permitted |= 1 << uint(what)
  270. }
  271. if which&INHERITABLE != 0 {
  272. c.data[i].inheritable |= 1 << uint(what)
  273. }
  274. if which&BOUNDING != 0 {
  275. c.bounds[i] |= 1 << uint(what)
  276. }
  277. if which&AMBIENT != 0 {
  278. c.ambient[i] |= 1 << uint(what)
  279. }
  280. }
  281. }
  282. func (c *capsV3) Unset(which CapType, caps ...Cap) {
  283. for _, what := range caps {
  284. var i uint
  285. if what > 31 {
  286. i = uint(what) >> 5
  287. what %= 32
  288. }
  289. if which&EFFECTIVE != 0 {
  290. c.data[i].effective &= ^(1 << uint(what))
  291. }
  292. if which&PERMITTED != 0 {
  293. c.data[i].permitted &= ^(1 << uint(what))
  294. }
  295. if which&INHERITABLE != 0 {
  296. c.data[i].inheritable &= ^(1 << uint(what))
  297. }
  298. if which&BOUNDING != 0 {
  299. c.bounds[i] &= ^(1 << uint(what))
  300. }
  301. if which&AMBIENT != 0 {
  302. c.ambient[i] &= ^(1 << uint(what))
  303. }
  304. }
  305. }
  306. func (c *capsV3) Fill(kind CapType) {
  307. if kind&CAPS == CAPS {
  308. c.data[0].effective = 0xffffffff
  309. c.data[0].permitted = 0xffffffff
  310. c.data[0].inheritable = 0
  311. c.data[1].effective = 0xffffffff
  312. c.data[1].permitted = 0xffffffff
  313. c.data[1].inheritable = 0
  314. }
  315. if kind&BOUNDS == BOUNDS {
  316. c.bounds[0] = 0xffffffff
  317. c.bounds[1] = 0xffffffff
  318. }
  319. if kind&AMBS == AMBS {
  320. c.ambient[0] = 0xffffffff
  321. c.ambient[1] = 0xffffffff
  322. }
  323. }
  324. func (c *capsV3) Clear(kind CapType) {
  325. if kind&CAPS == CAPS {
  326. c.data[0].effective = 0
  327. c.data[0].permitted = 0
  328. c.data[0].inheritable = 0
  329. c.data[1].effective = 0
  330. c.data[1].permitted = 0
  331. c.data[1].inheritable = 0
  332. }
  333. if kind&BOUNDS == BOUNDS {
  334. c.bounds[0] = 0
  335. c.bounds[1] = 0
  336. }
  337. if kind&AMBS == AMBS {
  338. c.ambient[0] = 0
  339. c.ambient[1] = 0
  340. }
  341. }
  342. func (c *capsV3) StringCap(which CapType) (ret string) {
  343. return mkStringCap(c, which)
  344. }
  345. func (c *capsV3) String() (ret string) {
  346. return mkString(c, BOUNDING)
  347. }
  348. func (c *capsV3) Load() (err error) {
  349. err = capget(&c.hdr, &c.data[0])
  350. if err != nil {
  351. return
  352. }
  353. var status_path string
  354. if c.hdr.pid == 0 {
  355. status_path = fmt.Sprintf("/proc/self/status")
  356. } else {
  357. status_path = fmt.Sprintf("/proc/%d/status", c.hdr.pid)
  358. }
  359. f, err := os.Open(status_path)
  360. if err != nil {
  361. return
  362. }
  363. b := bufio.NewReader(f)
  364. for {
  365. line, e := b.ReadString('\n')
  366. if e != nil {
  367. if e != io.EOF {
  368. err = e
  369. }
  370. break
  371. }
  372. if strings.HasPrefix(line, "CapB") {
  373. fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0])
  374. continue
  375. }
  376. if strings.HasPrefix(line, "CapA") {
  377. fmt.Sscanf(line[4:], "mb: %08x%08x", &c.ambient[1], &c.ambient[0])
  378. continue
  379. }
  380. }
  381. f.Close()
  382. return
  383. }
  384. func (c *capsV3) Apply(kind CapType) (err error) {
  385. if kind&BOUNDS == BOUNDS {
  386. var data [2]capData
  387. err = capget(&c.hdr, &data[0])
  388. if err != nil {
  389. return
  390. }
  391. if (1<<uint(CAP_SETPCAP))&data[0].effective != 0 {
  392. for i := Cap(0); i <= CAP_LAST_CAP; i++ {
  393. if c.Get(BOUNDING, i) {
  394. continue
  395. }
  396. err = prctl(syscall.PR_CAPBSET_DROP, uintptr(i), 0, 0, 0)
  397. if err != nil {
  398. // Ignore EINVAL since the capability may not be supported in this system.
  399. if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
  400. err = nil
  401. continue
  402. }
  403. return
  404. }
  405. }
  406. }
  407. }
  408. if kind&CAPS == CAPS {
  409. err = capset(&c.hdr, &c.data[0])
  410. if err != nil {
  411. return
  412. }
  413. }
  414. if kind&AMBS == AMBS {
  415. for i := Cap(0); i <= CAP_LAST_CAP; i++ {
  416. action := pr_CAP_AMBIENT_LOWER
  417. if c.Get(AMBIENT, i) {
  418. action = pr_CAP_AMBIENT_RAISE
  419. }
  420. err := prctl(pr_CAP_AMBIENT, action, uintptr(i), 0, 0)
  421. // Ignore EINVAL as not supported on kernels before 4.3
  422. if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
  423. err = nil
  424. continue
  425. }
  426. }
  427. }
  428. return
  429. }
  430. func newFile(path string) (c Capabilities, err error) {
  431. c = &capsFile{path: path}
  432. return
  433. }
  434. type capsFile struct {
  435. path string
  436. data vfscapData
  437. }
  438. func (c *capsFile) Get(which CapType, what Cap) bool {
  439. var i uint
  440. if what > 31 {
  441. if c.data.version == 1 {
  442. return false
  443. }
  444. i = uint(what) >> 5
  445. what %= 32
  446. }
  447. switch which {
  448. case EFFECTIVE:
  449. return (1<<uint(what))&c.data.effective[i] != 0
  450. case PERMITTED:
  451. return (1<<uint(what))&c.data.data[i].permitted != 0
  452. case INHERITABLE:
  453. return (1<<uint(what))&c.data.data[i].inheritable != 0
  454. }
  455. return false
  456. }
  457. func (c *capsFile) getData(which CapType, dest []uint32) {
  458. switch which {
  459. case EFFECTIVE:
  460. dest[0] = c.data.effective[0]
  461. dest[1] = c.data.effective[1]
  462. case PERMITTED:
  463. dest[0] = c.data.data[0].permitted
  464. dest[1] = c.data.data[1].permitted
  465. case INHERITABLE:
  466. dest[0] = c.data.data[0].inheritable
  467. dest[1] = c.data.data[1].inheritable
  468. }
  469. }
  470. func (c *capsFile) Empty(which CapType) bool {
  471. var data [2]uint32
  472. c.getData(which, data[:])
  473. return data[0] == 0 && data[1] == 0
  474. }
  475. func (c *capsFile) Full(which CapType) bool {
  476. var data [2]uint32
  477. c.getData(which, data[:])
  478. if c.data.version == 0 {
  479. return (data[0] & 0x7fffffff) == 0x7fffffff
  480. }
  481. if (data[0] & 0xffffffff) != 0xffffffff {
  482. return false
  483. }
  484. return (data[1] & capUpperMask) == capUpperMask
  485. }
  486. func (c *capsFile) Set(which CapType, caps ...Cap) {
  487. for _, what := range caps {
  488. var i uint
  489. if what > 31 {
  490. if c.data.version == 1 {
  491. continue
  492. }
  493. i = uint(what) >> 5
  494. what %= 32
  495. }
  496. if which&EFFECTIVE != 0 {
  497. c.data.effective[i] |= 1 << uint(what)
  498. }
  499. if which&PERMITTED != 0 {
  500. c.data.data[i].permitted |= 1 << uint(what)
  501. }
  502. if which&INHERITABLE != 0 {
  503. c.data.data[i].inheritable |= 1 << uint(what)
  504. }
  505. }
  506. }
  507. func (c *capsFile) Unset(which CapType, caps ...Cap) {
  508. for _, what := range caps {
  509. var i uint
  510. if what > 31 {
  511. if c.data.version == 1 {
  512. continue
  513. }
  514. i = uint(what) >> 5
  515. what %= 32
  516. }
  517. if which&EFFECTIVE != 0 {
  518. c.data.effective[i] &= ^(1 << uint(what))
  519. }
  520. if which&PERMITTED != 0 {
  521. c.data.data[i].permitted &= ^(1 << uint(what))
  522. }
  523. if which&INHERITABLE != 0 {
  524. c.data.data[i].inheritable &= ^(1 << uint(what))
  525. }
  526. }
  527. }
  528. func (c *capsFile) Fill(kind CapType) {
  529. if kind&CAPS == CAPS {
  530. c.data.effective[0] = 0xffffffff
  531. c.data.data[0].permitted = 0xffffffff
  532. c.data.data[0].inheritable = 0
  533. if c.data.version == 2 {
  534. c.data.effective[1] = 0xffffffff
  535. c.data.data[1].permitted = 0xffffffff
  536. c.data.data[1].inheritable = 0
  537. }
  538. }
  539. }
  540. func (c *capsFile) Clear(kind CapType) {
  541. if kind&CAPS == CAPS {
  542. c.data.effective[0] = 0
  543. c.data.data[0].permitted = 0
  544. c.data.data[0].inheritable = 0
  545. if c.data.version == 2 {
  546. c.data.effective[1] = 0
  547. c.data.data[1].permitted = 0
  548. c.data.data[1].inheritable = 0
  549. }
  550. }
  551. }
  552. func (c *capsFile) StringCap(which CapType) (ret string) {
  553. return mkStringCap(c, which)
  554. }
  555. func (c *capsFile) String() (ret string) {
  556. return mkString(c, INHERITABLE)
  557. }
  558. func (c *capsFile) Load() (err error) {
  559. return getVfsCap(c.path, &c.data)
  560. }
  561. func (c *capsFile) Apply(kind CapType) (err error) {
  562. if kind&CAPS == CAPS {
  563. return setVfsCap(c.path, &c.data)
  564. }
  565. return
  566. }