capability_linux.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  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 = 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. ambient [2]uint32
  209. }
  210. func (c *capsV3) Get(which CapType, what Cap) bool {
  211. var i uint
  212. if what > 31 {
  213. i = uint(what) >> 5
  214. what %= 32
  215. }
  216. switch which {
  217. case EFFECTIVE:
  218. return (1<<uint(what))&c.data[i].effective != 0
  219. case PERMITTED:
  220. return (1<<uint(what))&c.data[i].permitted != 0
  221. case INHERITABLE:
  222. return (1<<uint(what))&c.data[i].inheritable != 0
  223. case BOUNDING:
  224. return (1<<uint(what))&c.bounds[i] != 0
  225. case AMBIENT:
  226. return (1<<uint(what))&c.ambient[i] != 0
  227. }
  228. return false
  229. }
  230. func (c *capsV3) getData(which CapType, dest []uint32) {
  231. switch which {
  232. case EFFECTIVE:
  233. dest[0] = c.data[0].effective
  234. dest[1] = c.data[1].effective
  235. case PERMITTED:
  236. dest[0] = c.data[0].permitted
  237. dest[1] = c.data[1].permitted
  238. case INHERITABLE:
  239. dest[0] = c.data[0].inheritable
  240. dest[1] = c.data[1].inheritable
  241. case BOUNDING:
  242. dest[0] = c.bounds[0]
  243. dest[1] = c.bounds[1]
  244. case AMBIENT:
  245. dest[0] = c.ambient[0]
  246. dest[1] = c.ambient[1]
  247. }
  248. }
  249. func (c *capsV3) Empty(which CapType) bool {
  250. var data [2]uint32
  251. c.getData(which, data[:])
  252. return data[0] == 0 && data[1] == 0
  253. }
  254. func (c *capsV3) Full(which CapType) bool {
  255. var data [2]uint32
  256. c.getData(which, data[:])
  257. if (data[0] & 0xffffffff) != 0xffffffff {
  258. return false
  259. }
  260. return (data[1] & capUpperMask) == capUpperMask
  261. }
  262. func (c *capsV3) Set(which CapType, caps ...Cap) {
  263. for _, what := range caps {
  264. var i uint
  265. if what > 31 {
  266. i = uint(what) >> 5
  267. what %= 32
  268. }
  269. if which&EFFECTIVE != 0 {
  270. c.data[i].effective |= 1 << uint(what)
  271. }
  272. if which&PERMITTED != 0 {
  273. c.data[i].permitted |= 1 << uint(what)
  274. }
  275. if which&INHERITABLE != 0 {
  276. c.data[i].inheritable |= 1 << uint(what)
  277. }
  278. if which&BOUNDING != 0 {
  279. c.bounds[i] |= 1 << uint(what)
  280. }
  281. if which&AMBIENT != 0 {
  282. c.ambient[i] |= 1 << uint(what)
  283. }
  284. }
  285. }
  286. func (c *capsV3) Unset(which CapType, caps ...Cap) {
  287. for _, what := range caps {
  288. var i uint
  289. if what > 31 {
  290. i = uint(what) >> 5
  291. what %= 32
  292. }
  293. if which&EFFECTIVE != 0 {
  294. c.data[i].effective &= ^(1 << uint(what))
  295. }
  296. if which&PERMITTED != 0 {
  297. c.data[i].permitted &= ^(1 << uint(what))
  298. }
  299. if which&INHERITABLE != 0 {
  300. c.data[i].inheritable &= ^(1 << uint(what))
  301. }
  302. if which&BOUNDING != 0 {
  303. c.bounds[i] &= ^(1 << uint(what))
  304. }
  305. if which&AMBIENT != 0 {
  306. c.ambient[i] &= ^(1 << uint(what))
  307. }
  308. }
  309. }
  310. func (c *capsV3) Fill(kind CapType) {
  311. if kind&CAPS == CAPS {
  312. c.data[0].effective = 0xffffffff
  313. c.data[0].permitted = 0xffffffff
  314. c.data[0].inheritable = 0
  315. c.data[1].effective = 0xffffffff
  316. c.data[1].permitted = 0xffffffff
  317. c.data[1].inheritable = 0
  318. }
  319. if kind&BOUNDS == BOUNDS {
  320. c.bounds[0] = 0xffffffff
  321. c.bounds[1] = 0xffffffff
  322. }
  323. if kind&AMBS == AMBS {
  324. c.ambient[0] = 0xffffffff
  325. c.ambient[1] = 0xffffffff
  326. }
  327. }
  328. func (c *capsV3) Clear(kind CapType) {
  329. if kind&CAPS == CAPS {
  330. c.data[0].effective = 0
  331. c.data[0].permitted = 0
  332. c.data[0].inheritable = 0
  333. c.data[1].effective = 0
  334. c.data[1].permitted = 0
  335. c.data[1].inheritable = 0
  336. }
  337. if kind&BOUNDS == BOUNDS {
  338. c.bounds[0] = 0
  339. c.bounds[1] = 0
  340. }
  341. if kind&AMBS == AMBS {
  342. c.ambient[0] = 0
  343. c.ambient[1] = 0
  344. }
  345. }
  346. func (c *capsV3) StringCap(which CapType) (ret string) {
  347. return mkStringCap(c, which)
  348. }
  349. func (c *capsV3) String() (ret string) {
  350. return mkString(c, BOUNDING)
  351. }
  352. func (c *capsV3) Load() (err error) {
  353. err = capget(&c.hdr, &c.data[0])
  354. if err != nil {
  355. return
  356. }
  357. var status_path string
  358. if c.hdr.pid == 0 {
  359. status_path = fmt.Sprintf("/proc/self/status")
  360. } else {
  361. status_path = fmt.Sprintf("/proc/%d/status", c.hdr.pid)
  362. }
  363. f, err := os.Open(status_path)
  364. if err != nil {
  365. return
  366. }
  367. b := bufio.NewReader(f)
  368. for {
  369. line, e := b.ReadString('\n')
  370. if e != nil {
  371. if e != io.EOF {
  372. err = e
  373. }
  374. break
  375. }
  376. if strings.HasPrefix(line, "CapB") {
  377. fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0])
  378. break
  379. }
  380. if strings.HasPrefix(line, "CapA") {
  381. fmt.Sscanf(line[4:], "mb: %08x%08x", &c.ambient[1], &c.ambient[0])
  382. break
  383. }
  384. }
  385. f.Close()
  386. return
  387. }
  388. func (c *capsV3) Apply(kind CapType) (err error) {
  389. if kind&BOUNDS == BOUNDS {
  390. var data [2]capData
  391. err = capget(&c.hdr, &data[0])
  392. if err != nil {
  393. return
  394. }
  395. if (1<<uint(CAP_SETPCAP))&data[0].effective != 0 {
  396. for i := Cap(0); i <= CAP_LAST_CAP; i++ {
  397. if c.Get(BOUNDING, i) {
  398. continue
  399. }
  400. err = prctl(syscall.PR_CAPBSET_DROP, uintptr(i), 0, 0, 0)
  401. if err != nil {
  402. // Ignore EINVAL since the capability may not be supported in this system.
  403. if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
  404. err = nil
  405. continue
  406. }
  407. return
  408. }
  409. }
  410. }
  411. }
  412. if kind&CAPS == CAPS {
  413. err = capset(&c.hdr, &c.data[0])
  414. if err != nil {
  415. return
  416. }
  417. }
  418. if kind&AMBS == AMBS {
  419. for i := Cap(0); i <= CAP_LAST_CAP; i++ {
  420. action := pr_CAP_AMBIENT_LOWER
  421. if c.Get(AMBIENT, i) {
  422. action = pr_CAP_AMBIENT_RAISE
  423. }
  424. err := prctl(pr_CAP_AMBIENT, action, uintptr(i), 0, 0)
  425. // Ignore EINVAL as not supported on kernels before 4.3
  426. if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
  427. err = nil
  428. continue
  429. }
  430. }
  431. }
  432. return
  433. }
  434. func newFile(path string) (c Capabilities, err error) {
  435. c = &capsFile{path: path}
  436. err = c.Load()
  437. if err != nil {
  438. c = nil
  439. }
  440. return
  441. }
  442. type capsFile struct {
  443. path string
  444. data vfscapData
  445. }
  446. func (c *capsFile) Get(which CapType, what Cap) bool {
  447. var i uint
  448. if what > 31 {
  449. if c.data.version == 1 {
  450. return false
  451. }
  452. i = uint(what) >> 5
  453. what %= 32
  454. }
  455. switch which {
  456. case EFFECTIVE:
  457. return (1<<uint(what))&c.data.effective[i] != 0
  458. case PERMITTED:
  459. return (1<<uint(what))&c.data.data[i].permitted != 0
  460. case INHERITABLE:
  461. return (1<<uint(what))&c.data.data[i].inheritable != 0
  462. }
  463. return false
  464. }
  465. func (c *capsFile) getData(which CapType, dest []uint32) {
  466. switch which {
  467. case EFFECTIVE:
  468. dest[0] = c.data.effective[0]
  469. dest[1] = c.data.effective[1]
  470. case PERMITTED:
  471. dest[0] = c.data.data[0].permitted
  472. dest[1] = c.data.data[1].permitted
  473. case INHERITABLE:
  474. dest[0] = c.data.data[0].inheritable
  475. dest[1] = c.data.data[1].inheritable
  476. }
  477. }
  478. func (c *capsFile) Empty(which CapType) bool {
  479. var data [2]uint32
  480. c.getData(which, data[:])
  481. return data[0] == 0 && data[1] == 0
  482. }
  483. func (c *capsFile) Full(which CapType) bool {
  484. var data [2]uint32
  485. c.getData(which, data[:])
  486. if c.data.version == 0 {
  487. return (data[0] & 0x7fffffff) == 0x7fffffff
  488. }
  489. if (data[0] & 0xffffffff) != 0xffffffff {
  490. return false
  491. }
  492. return (data[1] & capUpperMask) == capUpperMask
  493. }
  494. func (c *capsFile) Set(which CapType, caps ...Cap) {
  495. for _, what := range caps {
  496. var i uint
  497. if what > 31 {
  498. if c.data.version == 1 {
  499. continue
  500. }
  501. i = uint(what) >> 5
  502. what %= 32
  503. }
  504. if which&EFFECTIVE != 0 {
  505. c.data.effective[i] |= 1 << uint(what)
  506. }
  507. if which&PERMITTED != 0 {
  508. c.data.data[i].permitted |= 1 << uint(what)
  509. }
  510. if which&INHERITABLE != 0 {
  511. c.data.data[i].inheritable |= 1 << uint(what)
  512. }
  513. }
  514. }
  515. func (c *capsFile) Unset(which CapType, caps ...Cap) {
  516. for _, what := range caps {
  517. var i uint
  518. if what > 31 {
  519. if c.data.version == 1 {
  520. continue
  521. }
  522. i = uint(what) >> 5
  523. what %= 32
  524. }
  525. if which&EFFECTIVE != 0 {
  526. c.data.effective[i] &= ^(1 << uint(what))
  527. }
  528. if which&PERMITTED != 0 {
  529. c.data.data[i].permitted &= ^(1 << uint(what))
  530. }
  531. if which&INHERITABLE != 0 {
  532. c.data.data[i].inheritable &= ^(1 << uint(what))
  533. }
  534. }
  535. }
  536. func (c *capsFile) Fill(kind CapType) {
  537. if kind&CAPS == CAPS {
  538. c.data.effective[0] = 0xffffffff
  539. c.data.data[0].permitted = 0xffffffff
  540. c.data.data[0].inheritable = 0
  541. if c.data.version == 2 {
  542. c.data.effective[1] = 0xffffffff
  543. c.data.data[1].permitted = 0xffffffff
  544. c.data.data[1].inheritable = 0
  545. }
  546. }
  547. }
  548. func (c *capsFile) Clear(kind CapType) {
  549. if kind&CAPS == CAPS {
  550. c.data.effective[0] = 0
  551. c.data.data[0].permitted = 0
  552. c.data.data[0].inheritable = 0
  553. if c.data.version == 2 {
  554. c.data.effective[1] = 0
  555. c.data.data[1].permitted = 0
  556. c.data.data[1].inheritable = 0
  557. }
  558. }
  559. }
  560. func (c *capsFile) StringCap(which CapType) (ret string) {
  561. return mkStringCap(c, which)
  562. }
  563. func (c *capsFile) String() (ret string) {
  564. return mkString(c, INHERITABLE)
  565. }
  566. func (c *capsFile) Load() (err error) {
  567. return getVfsCap(c.path, &c.data)
  568. }
  569. func (c *capsFile) Apply(kind CapType) (err error) {
  570. if kind&CAPS == CAPS {
  571. return setVfsCap(c.path, &c.data)
  572. }
  573. return
  574. }