cipso_ipv4.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607
  1. /*
  2. * CIPSO - Commercial IP Security Option
  3. *
  4. * This is an implementation of the CIPSO 2.2 protocol as specified in
  5. * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
  6. * FIPS-188, copies of both documents can be found in the Documentation
  7. * directory. While CIPSO never became a full IETF RFC standard many vendors
  8. * have chosen to adopt the protocol and over the years it has become a
  9. * de-facto standard for labeled networking.
  10. *
  11. * Author: Paul Moore <paul.moore@hp.com>
  12. *
  13. */
  14. /*
  15. * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
  16. *
  17. * This program is free software; you can redistribute it and/or modify
  18. * it under the terms of the GNU General Public License as published by
  19. * the Free Software Foundation; either version 2 of the License, or
  20. * (at your option) any later version.
  21. *
  22. * This program is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  25. * the GNU General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU General Public License
  28. * along with this program; if not, write to the Free Software
  29. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  30. *
  31. */
  32. #include <linux/init.h>
  33. #include <linux/types.h>
  34. #include <linux/rcupdate.h>
  35. #include <linux/list.h>
  36. #include <linux/spinlock.h>
  37. #include <linux/string.h>
  38. #include <linux/jhash.h>
  39. #include <net/ip.h>
  40. #include <net/icmp.h>
  41. #include <net/tcp.h>
  42. #include <net/netlabel.h>
  43. #include <net/cipso_ipv4.h>
  44. #include <asm/bug.h>
  45. struct cipso_v4_domhsh_entry {
  46. char *domain;
  47. u32 valid;
  48. struct list_head list;
  49. struct rcu_head rcu;
  50. };
  51. /* List of available DOI definitions */
  52. /* XXX - Updates should be minimal so having a single lock for the
  53. * cipso_v4_doi_list and the cipso_v4_doi_list->dom_list should be
  54. * okay. */
  55. /* XXX - This currently assumes a minimal number of different DOIs in use,
  56. * if in practice there are a lot of different DOIs this list should
  57. * probably be turned into a hash table or something similar so we
  58. * can do quick lookups. */
  59. static DEFINE_SPINLOCK(cipso_v4_doi_list_lock);
  60. static struct list_head cipso_v4_doi_list = LIST_HEAD_INIT(cipso_v4_doi_list);
  61. /* Label mapping cache */
  62. int cipso_v4_cache_enabled = 1;
  63. int cipso_v4_cache_bucketsize = 10;
  64. #define CIPSO_V4_CACHE_BUCKETBITS 7
  65. #define CIPSO_V4_CACHE_BUCKETS (1 << CIPSO_V4_CACHE_BUCKETBITS)
  66. #define CIPSO_V4_CACHE_REORDERLIMIT 10
  67. struct cipso_v4_map_cache_bkt {
  68. spinlock_t lock;
  69. u32 size;
  70. struct list_head list;
  71. };
  72. struct cipso_v4_map_cache_entry {
  73. u32 hash;
  74. unsigned char *key;
  75. size_t key_len;
  76. struct netlbl_lsm_cache lsm_data;
  77. u32 activity;
  78. struct list_head list;
  79. };
  80. static struct cipso_v4_map_cache_bkt *cipso_v4_cache = NULL;
  81. /* Restricted bitmap (tag #1) flags */
  82. int cipso_v4_rbm_optfmt = 0;
  83. int cipso_v4_rbm_strictvalid = 1;
  84. /*
  85. * Helper Functions
  86. */
  87. /**
  88. * cipso_v4_bitmap_walk - Walk a bitmap looking for a bit
  89. * @bitmap: the bitmap
  90. * @bitmap_len: length in bits
  91. * @offset: starting offset
  92. * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit
  93. *
  94. * Description:
  95. * Starting at @offset, walk the bitmap from left to right until either the
  96. * desired bit is found or we reach the end. Return the bit offset, -1 if
  97. * not found, or -2 if error.
  98. */
  99. static int cipso_v4_bitmap_walk(const unsigned char *bitmap,
  100. u32 bitmap_len,
  101. u32 offset,
  102. u8 state)
  103. {
  104. u32 bit_spot;
  105. u32 byte_offset;
  106. unsigned char bitmask;
  107. unsigned char byte;
  108. /* gcc always rounds to zero when doing integer division */
  109. byte_offset = offset / 8;
  110. byte = bitmap[byte_offset];
  111. bit_spot = offset;
  112. bitmask = 0x80 >> (offset % 8);
  113. while (bit_spot < bitmap_len) {
  114. if ((state && (byte & bitmask) == bitmask) ||
  115. (state == 0 && (byte & bitmask) == 0))
  116. return bit_spot;
  117. bit_spot++;
  118. bitmask >>= 1;
  119. if (bitmask == 0) {
  120. byte = bitmap[++byte_offset];
  121. bitmask = 0x80;
  122. }
  123. }
  124. return -1;
  125. }
  126. /**
  127. * cipso_v4_bitmap_setbit - Sets a single bit in a bitmap
  128. * @bitmap: the bitmap
  129. * @bit: the bit
  130. * @state: if non-zero, set the bit (1) else clear the bit (0)
  131. *
  132. * Description:
  133. * Set a single bit in the bitmask. Returns zero on success, negative values
  134. * on error.
  135. */
  136. static void cipso_v4_bitmap_setbit(unsigned char *bitmap,
  137. u32 bit,
  138. u8 state)
  139. {
  140. u32 byte_spot;
  141. u8 bitmask;
  142. /* gcc always rounds to zero when doing integer division */
  143. byte_spot = bit / 8;
  144. bitmask = 0x80 >> (bit % 8);
  145. if (state)
  146. bitmap[byte_spot] |= bitmask;
  147. else
  148. bitmap[byte_spot] &= ~bitmask;
  149. }
  150. /**
  151. * cipso_v4_doi_domhsh_free - Frees a domain list entry
  152. * @entry: the entry's RCU field
  153. *
  154. * Description:
  155. * This function is designed to be used as a callback to the call_rcu()
  156. * function so that the memory allocated to a domain list entry can be released
  157. * safely.
  158. *
  159. */
  160. static void cipso_v4_doi_domhsh_free(struct rcu_head *entry)
  161. {
  162. struct cipso_v4_domhsh_entry *ptr;
  163. ptr = container_of(entry, struct cipso_v4_domhsh_entry, rcu);
  164. kfree(ptr->domain);
  165. kfree(ptr);
  166. }
  167. /**
  168. * cipso_v4_cache_entry_free - Frees a cache entry
  169. * @entry: the entry to free
  170. *
  171. * Description:
  172. * This function frees the memory associated with a cache entry.
  173. *
  174. */
  175. static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry)
  176. {
  177. if (entry->lsm_data.free)
  178. entry->lsm_data.free(entry->lsm_data.data);
  179. kfree(entry->key);
  180. kfree(entry);
  181. }
  182. /**
  183. * cipso_v4_map_cache_hash - Hashing function for the CIPSO cache
  184. * @key: the hash key
  185. * @key_len: the length of the key in bytes
  186. *
  187. * Description:
  188. * The CIPSO tag hashing function. Returns a 32-bit hash value.
  189. *
  190. */
  191. static u32 cipso_v4_map_cache_hash(const unsigned char *key, u32 key_len)
  192. {
  193. return jhash(key, key_len, 0);
  194. }
  195. /*
  196. * Label Mapping Cache Functions
  197. */
  198. /**
  199. * cipso_v4_cache_init - Initialize the CIPSO cache
  200. *
  201. * Description:
  202. * Initializes the CIPSO label mapping cache, this function should be called
  203. * before any of the other functions defined in this file. Returns zero on
  204. * success, negative values on error.
  205. *
  206. */
  207. static int cipso_v4_cache_init(void)
  208. {
  209. u32 iter;
  210. cipso_v4_cache = kcalloc(CIPSO_V4_CACHE_BUCKETS,
  211. sizeof(struct cipso_v4_map_cache_bkt),
  212. GFP_KERNEL);
  213. if (cipso_v4_cache == NULL)
  214. return -ENOMEM;
  215. for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
  216. spin_lock_init(&cipso_v4_cache[iter].lock);
  217. cipso_v4_cache[iter].size = 0;
  218. INIT_LIST_HEAD(&cipso_v4_cache[iter].list);
  219. }
  220. return 0;
  221. }
  222. /**
  223. * cipso_v4_cache_invalidate - Invalidates the current CIPSO cache
  224. *
  225. * Description:
  226. * Invalidates and frees any entries in the CIPSO cache. Returns zero on
  227. * success and negative values on failure.
  228. *
  229. */
  230. void cipso_v4_cache_invalidate(void)
  231. {
  232. struct cipso_v4_map_cache_entry *entry, *tmp_entry;
  233. u32 iter;
  234. for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
  235. spin_lock(&cipso_v4_cache[iter].lock);
  236. list_for_each_entry_safe(entry,
  237. tmp_entry,
  238. &cipso_v4_cache[iter].list, list) {
  239. list_del(&entry->list);
  240. cipso_v4_cache_entry_free(entry);
  241. }
  242. cipso_v4_cache[iter].size = 0;
  243. spin_unlock(&cipso_v4_cache[iter].lock);
  244. }
  245. return;
  246. }
  247. /**
  248. * cipso_v4_cache_check - Check the CIPSO cache for a label mapping
  249. * @key: the buffer to check
  250. * @key_len: buffer length in bytes
  251. * @secattr: the security attribute struct to use
  252. *
  253. * Description:
  254. * This function checks the cache to see if a label mapping already exists for
  255. * the given key. If there is a match then the cache is adjusted and the
  256. * @secattr struct is populated with the correct LSM security attributes. The
  257. * cache is adjusted in the following manner if the entry is not already the
  258. * first in the cache bucket:
  259. *
  260. * 1. The cache entry's activity counter is incremented
  261. * 2. The previous (higher ranking) entry's activity counter is decremented
  262. * 3. If the difference between the two activity counters is geater than
  263. * CIPSO_V4_CACHE_REORDERLIMIT the two entries are swapped
  264. *
  265. * Returns zero on success, -ENOENT for a cache miss, and other negative values
  266. * on error.
  267. *
  268. */
  269. static int cipso_v4_cache_check(const unsigned char *key,
  270. u32 key_len,
  271. struct netlbl_lsm_secattr *secattr)
  272. {
  273. u32 bkt;
  274. struct cipso_v4_map_cache_entry *entry;
  275. struct cipso_v4_map_cache_entry *prev_entry = NULL;
  276. u32 hash;
  277. if (!cipso_v4_cache_enabled)
  278. return -ENOENT;
  279. hash = cipso_v4_map_cache_hash(key, key_len);
  280. bkt = hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
  281. spin_lock(&cipso_v4_cache[bkt].lock);
  282. list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) {
  283. if (entry->hash == hash &&
  284. entry->key_len == key_len &&
  285. memcmp(entry->key, key, key_len) == 0) {
  286. entry->activity += 1;
  287. secattr->cache.free = entry->lsm_data.free;
  288. secattr->cache.data = entry->lsm_data.data;
  289. if (prev_entry == NULL) {
  290. spin_unlock(&cipso_v4_cache[bkt].lock);
  291. return 0;
  292. }
  293. if (prev_entry->activity > 0)
  294. prev_entry->activity -= 1;
  295. if (entry->activity > prev_entry->activity &&
  296. entry->activity - prev_entry->activity >
  297. CIPSO_V4_CACHE_REORDERLIMIT) {
  298. __list_del(entry->list.prev, entry->list.next);
  299. __list_add(&entry->list,
  300. prev_entry->list.prev,
  301. &prev_entry->list);
  302. }
  303. spin_unlock(&cipso_v4_cache[bkt].lock);
  304. return 0;
  305. }
  306. prev_entry = entry;
  307. }
  308. spin_unlock(&cipso_v4_cache[bkt].lock);
  309. return -ENOENT;
  310. }
  311. /**
  312. * cipso_v4_cache_add - Add an entry to the CIPSO cache
  313. * @skb: the packet
  314. * @secattr: the packet's security attributes
  315. *
  316. * Description:
  317. * Add a new entry into the CIPSO label mapping cache. Add the new entry to
  318. * head of the cache bucket's list, if the cache bucket is out of room remove
  319. * the last entry in the list first. It is important to note that there is
  320. * currently no checking for duplicate keys. Returns zero on success,
  321. * negative values on failure.
  322. *
  323. */
  324. int cipso_v4_cache_add(const struct sk_buff *skb,
  325. const struct netlbl_lsm_secattr *secattr)
  326. {
  327. int ret_val = -EPERM;
  328. u32 bkt;
  329. struct cipso_v4_map_cache_entry *entry = NULL;
  330. struct cipso_v4_map_cache_entry *old_entry = NULL;
  331. unsigned char *cipso_ptr;
  332. u32 cipso_ptr_len;
  333. if (!cipso_v4_cache_enabled || cipso_v4_cache_bucketsize <= 0)
  334. return 0;
  335. cipso_ptr = CIPSO_V4_OPTPTR(skb);
  336. cipso_ptr_len = cipso_ptr[1];
  337. entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
  338. if (entry == NULL)
  339. return -ENOMEM;
  340. entry->key = kmalloc(cipso_ptr_len, GFP_ATOMIC);
  341. if (entry->key == NULL) {
  342. ret_val = -ENOMEM;
  343. goto cache_add_failure;
  344. }
  345. memcpy(entry->key, cipso_ptr, cipso_ptr_len);
  346. entry->key_len = cipso_ptr_len;
  347. entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
  348. entry->lsm_data.free = secattr->cache.free;
  349. entry->lsm_data.data = secattr->cache.data;
  350. bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
  351. spin_lock(&cipso_v4_cache[bkt].lock);
  352. if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) {
  353. list_add(&entry->list, &cipso_v4_cache[bkt].list);
  354. cipso_v4_cache[bkt].size += 1;
  355. } else {
  356. old_entry = list_entry(cipso_v4_cache[bkt].list.prev,
  357. struct cipso_v4_map_cache_entry, list);
  358. list_del(&old_entry->list);
  359. list_add(&entry->list, &cipso_v4_cache[bkt].list);
  360. cipso_v4_cache_entry_free(old_entry);
  361. }
  362. spin_unlock(&cipso_v4_cache[bkt].lock);
  363. return 0;
  364. cache_add_failure:
  365. if (entry)
  366. cipso_v4_cache_entry_free(entry);
  367. return ret_val;
  368. }
  369. /*
  370. * DOI List Functions
  371. */
  372. /**
  373. * cipso_v4_doi_search - Searches for a DOI definition
  374. * @doi: the DOI to search for
  375. *
  376. * Description:
  377. * Search the DOI definition list for a DOI definition with a DOI value that
  378. * matches @doi. The caller is responsibile for calling rcu_read_[un]lock().
  379. * Returns a pointer to the DOI definition on success and NULL on failure.
  380. */
  381. static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
  382. {
  383. struct cipso_v4_doi *iter;
  384. list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
  385. if (iter->doi == doi && iter->valid)
  386. return iter;
  387. return NULL;
  388. }
  389. /**
  390. * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine
  391. * @doi_def: the DOI structure
  392. *
  393. * Description:
  394. * The caller defines a new DOI for use by the CIPSO engine and calls this
  395. * function to add it to the list of acceptable domains. The caller must
  396. * ensure that the mapping table specified in @doi_def->map meets all of the
  397. * requirements of the mapping type (see cipso_ipv4.h for details). Returns
  398. * zero on success and non-zero on failure.
  399. *
  400. */
  401. int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
  402. {
  403. if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
  404. return -EINVAL;
  405. doi_def->valid = 1;
  406. INIT_RCU_HEAD(&doi_def->rcu);
  407. INIT_LIST_HEAD(&doi_def->dom_list);
  408. rcu_read_lock();
  409. if (cipso_v4_doi_search(doi_def->doi) != NULL)
  410. goto doi_add_failure_rlock;
  411. spin_lock(&cipso_v4_doi_list_lock);
  412. if (cipso_v4_doi_search(doi_def->doi) != NULL)
  413. goto doi_add_failure_slock;
  414. list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
  415. spin_unlock(&cipso_v4_doi_list_lock);
  416. rcu_read_unlock();
  417. return 0;
  418. doi_add_failure_slock:
  419. spin_unlock(&cipso_v4_doi_list_lock);
  420. doi_add_failure_rlock:
  421. rcu_read_unlock();
  422. return -EEXIST;
  423. }
  424. /**
  425. * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
  426. * @doi: the DOI value
  427. * @callback: the DOI cleanup/free callback
  428. *
  429. * Description:
  430. * Removes a DOI definition from the CIPSO engine, @callback is called to
  431. * free any memory. The NetLabel routines will be called to release their own
  432. * LSM domain mappings as well as our own domain list. Returns zero on
  433. * success and negative values on failure.
  434. *
  435. */
  436. int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head))
  437. {
  438. struct cipso_v4_doi *doi_def;
  439. struct cipso_v4_domhsh_entry *dom_iter;
  440. rcu_read_lock();
  441. if (cipso_v4_doi_search(doi) != NULL) {
  442. spin_lock(&cipso_v4_doi_list_lock);
  443. doi_def = cipso_v4_doi_search(doi);
  444. if (doi_def == NULL) {
  445. spin_unlock(&cipso_v4_doi_list_lock);
  446. rcu_read_unlock();
  447. return -ENOENT;
  448. }
  449. doi_def->valid = 0;
  450. list_del_rcu(&doi_def->list);
  451. spin_unlock(&cipso_v4_doi_list_lock);
  452. list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
  453. if (dom_iter->valid)
  454. netlbl_domhsh_remove(dom_iter->domain);
  455. cipso_v4_cache_invalidate();
  456. rcu_read_unlock();
  457. call_rcu(&doi_def->rcu, callback);
  458. return 0;
  459. }
  460. rcu_read_unlock();
  461. return -ENOENT;
  462. }
  463. /**
  464. * cipso_v4_doi_getdef - Returns a pointer to a valid DOI definition
  465. * @doi: the DOI value
  466. *
  467. * Description:
  468. * Searches for a valid DOI definition and if one is found it is returned to
  469. * the caller. Otherwise NULL is returned. The caller must ensure that
  470. * rcu_read_lock() is held while accessing the returned definition.
  471. *
  472. */
  473. struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
  474. {
  475. return cipso_v4_doi_search(doi);
  476. }
  477. /**
  478. * cipso_v4_doi_dump_all - Dump all the CIPSO DOI definitions into a sk_buff
  479. * @headroom: the amount of headroom to allocate for the sk_buff
  480. *
  481. * Description:
  482. * Dump a list of all the configured DOI values into a sk_buff. The returned
  483. * sk_buff has room at the front of the sk_buff for @headroom bytes. See
  484. * net/netlabel/netlabel_cipso_v4.h for the LISTALL message format. This
  485. * function may fail if another process is changing the DOI list at the same
  486. * time. Returns a pointer to a sk_buff on success, NULL on error.
  487. *
  488. */
  489. struct sk_buff *cipso_v4_doi_dump_all(size_t headroom)
  490. {
  491. struct sk_buff *skb = NULL;
  492. struct cipso_v4_doi *iter;
  493. u32 doi_cnt = 0;
  494. ssize_t buf_len;
  495. buf_len = NETLBL_LEN_U32;
  496. rcu_read_lock();
  497. list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
  498. if (iter->valid) {
  499. doi_cnt += 1;
  500. buf_len += 2 * NETLBL_LEN_U32;
  501. }
  502. skb = netlbl_netlink_alloc_skb(headroom, buf_len, GFP_ATOMIC);
  503. if (skb == NULL)
  504. goto doi_dump_all_failure;
  505. if (nla_put_u32(skb, NLA_U32, doi_cnt) != 0)
  506. goto doi_dump_all_failure;
  507. buf_len -= NETLBL_LEN_U32;
  508. list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
  509. if (iter->valid) {
  510. if (buf_len < 2 * NETLBL_LEN_U32)
  511. goto doi_dump_all_failure;
  512. if (nla_put_u32(skb, NLA_U32, iter->doi) != 0)
  513. goto doi_dump_all_failure;
  514. if (nla_put_u32(skb, NLA_U32, iter->type) != 0)
  515. goto doi_dump_all_failure;
  516. buf_len -= 2 * NETLBL_LEN_U32;
  517. }
  518. rcu_read_unlock();
  519. return skb;
  520. doi_dump_all_failure:
  521. rcu_read_unlock();
  522. kfree(skb);
  523. return NULL;
  524. }
  525. /**
  526. * cipso_v4_doi_dump - Dump a CIPSO DOI definition into a sk_buff
  527. * @doi: the DOI value
  528. * @headroom: the amount of headroom to allocate for the sk_buff
  529. *
  530. * Description:
  531. * Lookup the DOI definition matching @doi and dump it's contents into a
  532. * sk_buff. The returned sk_buff has room at the front of the sk_buff for
  533. * @headroom bytes. See net/netlabel/netlabel_cipso_v4.h for the LIST message
  534. * format. This function may fail if another process is changing the DOI list
  535. * at the same time. Returns a pointer to a sk_buff on success, NULL on error.
  536. *
  537. */
  538. struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom)
  539. {
  540. struct sk_buff *skb = NULL;
  541. struct cipso_v4_doi *iter;
  542. u32 tag_cnt = 0;
  543. u32 lvl_cnt = 0;
  544. u32 cat_cnt = 0;
  545. ssize_t buf_len;
  546. ssize_t tmp;
  547. rcu_read_lock();
  548. iter = cipso_v4_doi_getdef(doi);
  549. if (iter == NULL)
  550. goto doi_dump_failure;
  551. buf_len = NETLBL_LEN_U32;
  552. switch (iter->type) {
  553. case CIPSO_V4_MAP_PASS:
  554. buf_len += NETLBL_LEN_U32;
  555. while(tag_cnt < CIPSO_V4_TAG_MAXCNT &&
  556. iter->tags[tag_cnt] != CIPSO_V4_TAG_INVALID) {
  557. tag_cnt += 1;
  558. buf_len += NETLBL_LEN_U8;
  559. }
  560. break;
  561. case CIPSO_V4_MAP_STD:
  562. buf_len += 3 * NETLBL_LEN_U32;
  563. while (tag_cnt < CIPSO_V4_TAG_MAXCNT &&
  564. iter->tags[tag_cnt] != CIPSO_V4_TAG_INVALID) {
  565. tag_cnt += 1;
  566. buf_len += NETLBL_LEN_U8;
  567. }
  568. for (tmp = 0; tmp < iter->map.std->lvl.local_size; tmp++)
  569. if (iter->map.std->lvl.local[tmp] !=
  570. CIPSO_V4_INV_LVL) {
  571. lvl_cnt += 1;
  572. buf_len += NETLBL_LEN_U32 + NETLBL_LEN_U8;
  573. }
  574. for (tmp = 0; tmp < iter->map.std->cat.local_size; tmp++)
  575. if (iter->map.std->cat.local[tmp] !=
  576. CIPSO_V4_INV_CAT) {
  577. cat_cnt += 1;
  578. buf_len += NETLBL_LEN_U32 + NETLBL_LEN_U16;
  579. }
  580. break;
  581. }
  582. skb = netlbl_netlink_alloc_skb(headroom, buf_len, GFP_ATOMIC);
  583. if (skb == NULL)
  584. goto doi_dump_failure;
  585. if (nla_put_u32(skb, NLA_U32, iter->type) != 0)
  586. goto doi_dump_failure;
  587. buf_len -= NETLBL_LEN_U32;
  588. if (iter != cipso_v4_doi_getdef(doi))
  589. goto doi_dump_failure;
  590. switch (iter->type) {
  591. case CIPSO_V4_MAP_PASS:
  592. if (nla_put_u32(skb, NLA_U32, tag_cnt) != 0)
  593. goto doi_dump_failure;
  594. buf_len -= NETLBL_LEN_U32;
  595. for (tmp = 0;
  596. tmp < CIPSO_V4_TAG_MAXCNT &&
  597. iter->tags[tmp] != CIPSO_V4_TAG_INVALID;
  598. tmp++) {
  599. if (buf_len < NETLBL_LEN_U8)
  600. goto doi_dump_failure;
  601. if (nla_put_u8(skb, NLA_U8, iter->tags[tmp]) != 0)
  602. goto doi_dump_failure;
  603. buf_len -= NETLBL_LEN_U8;
  604. }
  605. break;
  606. case CIPSO_V4_MAP_STD:
  607. if (nla_put_u32(skb, NLA_U32, tag_cnt) != 0)
  608. goto doi_dump_failure;
  609. if (nla_put_u32(skb, NLA_U32, lvl_cnt) != 0)
  610. goto doi_dump_failure;
  611. if (nla_put_u32(skb, NLA_U32, cat_cnt) != 0)
  612. goto doi_dump_failure;
  613. buf_len -= 3 * NETLBL_LEN_U32;
  614. for (tmp = 0;
  615. tmp < CIPSO_V4_TAG_MAXCNT &&
  616. iter->tags[tmp] != CIPSO_V4_TAG_INVALID;
  617. tmp++) {
  618. if (buf_len < NETLBL_LEN_U8)
  619. goto doi_dump_failure;
  620. if (nla_put_u8(skb, NLA_U8, iter->tags[tmp]) != 0)
  621. goto doi_dump_failure;
  622. buf_len -= NETLBL_LEN_U8;
  623. }
  624. for (tmp = 0; tmp < iter->map.std->lvl.local_size; tmp++)
  625. if (iter->map.std->lvl.local[tmp] !=
  626. CIPSO_V4_INV_LVL) {
  627. if (buf_len < NETLBL_LEN_U32 + NETLBL_LEN_U8)
  628. goto doi_dump_failure;
  629. if (nla_put_u32(skb, NLA_U32, tmp) != 0)
  630. goto doi_dump_failure;
  631. if (nla_put_u8(skb,
  632. NLA_U8,
  633. iter->map.std->lvl.local[tmp]) != 0)
  634. goto doi_dump_failure;
  635. buf_len -= NETLBL_LEN_U32 + NETLBL_LEN_U8;
  636. }
  637. for (tmp = 0; tmp < iter->map.std->cat.local_size; tmp++)
  638. if (iter->map.std->cat.local[tmp] !=
  639. CIPSO_V4_INV_CAT) {
  640. if (buf_len < NETLBL_LEN_U32 + NETLBL_LEN_U16)
  641. goto doi_dump_failure;
  642. if (nla_put_u32(skb, NLA_U32, tmp) != 0)
  643. goto doi_dump_failure;
  644. if (nla_put_u16(skb,
  645. NLA_U16,
  646. iter->map.std->cat.local[tmp]) != 0)
  647. goto doi_dump_failure;
  648. buf_len -= NETLBL_LEN_U32 + NETLBL_LEN_U16;
  649. }
  650. break;
  651. }
  652. rcu_read_unlock();
  653. return skb;
  654. doi_dump_failure:
  655. rcu_read_unlock();
  656. kfree(skb);
  657. return NULL;
  658. }
  659. /**
  660. * cipso_v4_doi_domhsh_add - Adds a domain entry to a DOI definition
  661. * @doi_def: the DOI definition
  662. * @domain: the domain to add
  663. *
  664. * Description:
  665. * Adds the @domain to the the DOI specified by @doi_def, this function
  666. * should only be called by external functions (i.e. NetLabel). This function
  667. * does allocate memory. Returns zero on success, negative values on failure.
  668. *
  669. */
  670. int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain)
  671. {
  672. struct cipso_v4_domhsh_entry *iter;
  673. struct cipso_v4_domhsh_entry *new_dom;
  674. new_dom = kzalloc(sizeof(*new_dom), GFP_KERNEL);
  675. if (new_dom == NULL)
  676. return -ENOMEM;
  677. if (domain) {
  678. new_dom->domain = kstrdup(domain, GFP_KERNEL);
  679. if (new_dom->domain == NULL) {
  680. kfree(new_dom);
  681. return -ENOMEM;
  682. }
  683. }
  684. new_dom->valid = 1;
  685. INIT_RCU_HEAD(&new_dom->rcu);
  686. rcu_read_lock();
  687. spin_lock(&cipso_v4_doi_list_lock);
  688. list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
  689. if (iter->valid &&
  690. ((domain != NULL && iter->domain != NULL &&
  691. strcmp(iter->domain, domain) == 0) ||
  692. (domain == NULL && iter->domain == NULL))) {
  693. spin_unlock(&cipso_v4_doi_list_lock);
  694. rcu_read_unlock();
  695. kfree(new_dom->domain);
  696. kfree(new_dom);
  697. return -EEXIST;
  698. }
  699. list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);
  700. spin_unlock(&cipso_v4_doi_list_lock);
  701. rcu_read_unlock();
  702. return 0;
  703. }
  704. /**
  705. * cipso_v4_doi_domhsh_remove - Removes a domain entry from a DOI definition
  706. * @doi_def: the DOI definition
  707. * @domain: the domain to remove
  708. *
  709. * Description:
  710. * Removes the @domain from the DOI specified by @doi_def, this function
  711. * should only be called by external functions (i.e. NetLabel). Returns zero
  712. * on success and negative values on error.
  713. *
  714. */
  715. int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
  716. const char *domain)
  717. {
  718. struct cipso_v4_domhsh_entry *iter;
  719. rcu_read_lock();
  720. spin_lock(&cipso_v4_doi_list_lock);
  721. list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
  722. if (iter->valid &&
  723. ((domain != NULL && iter->domain != NULL &&
  724. strcmp(iter->domain, domain) == 0) ||
  725. (domain == NULL && iter->domain == NULL))) {
  726. iter->valid = 0;
  727. list_del_rcu(&iter->list);
  728. spin_unlock(&cipso_v4_doi_list_lock);
  729. rcu_read_unlock();
  730. call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);
  731. return 0;
  732. }
  733. spin_unlock(&cipso_v4_doi_list_lock);
  734. rcu_read_unlock();
  735. return -ENOENT;
  736. }
  737. /*
  738. * Label Mapping Functions
  739. */
  740. /**
  741. * cipso_v4_map_lvl_valid - Checks to see if the given level is understood
  742. * @doi_def: the DOI definition
  743. * @level: the level to check
  744. *
  745. * Description:
  746. * Checks the given level against the given DOI definition and returns a
  747. * negative value if the level does not have a valid mapping and a zero value
  748. * if the level is defined by the DOI.
  749. *
  750. */
  751. static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level)
  752. {
  753. switch (doi_def->type) {
  754. case CIPSO_V4_MAP_PASS:
  755. return 0;
  756. case CIPSO_V4_MAP_STD:
  757. if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)
  758. return 0;
  759. break;
  760. }
  761. return -EFAULT;
  762. }
  763. /**
  764. * cipso_v4_map_lvl_hton - Perform a level mapping from the host to the network
  765. * @doi_def: the DOI definition
  766. * @host_lvl: the host MLS level
  767. * @net_lvl: the network/CIPSO MLS level
  768. *
  769. * Description:
  770. * Perform a label mapping to translate a local MLS level to the correct
  771. * CIPSO level using the given DOI definition. Returns zero on success,
  772. * negative values otherwise.
  773. *
  774. */
  775. static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def,
  776. u32 host_lvl,
  777. u32 *net_lvl)
  778. {
  779. switch (doi_def->type) {
  780. case CIPSO_V4_MAP_PASS:
  781. *net_lvl = host_lvl;
  782. return 0;
  783. case CIPSO_V4_MAP_STD:
  784. if (host_lvl < doi_def->map.std->lvl.local_size) {
  785. *net_lvl = doi_def->map.std->lvl.local[host_lvl];
  786. return 0;
  787. }
  788. break;
  789. }
  790. return -EINVAL;
  791. }
  792. /**
  793. * cipso_v4_map_lvl_ntoh - Perform a level mapping from the network to the host
  794. * @doi_def: the DOI definition
  795. * @net_lvl: the network/CIPSO MLS level
  796. * @host_lvl: the host MLS level
  797. *
  798. * Description:
  799. * Perform a label mapping to translate a CIPSO level to the correct local MLS
  800. * level using the given DOI definition. Returns zero on success, negative
  801. * values otherwise.
  802. *
  803. */
  804. static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def,
  805. u32 net_lvl,
  806. u32 *host_lvl)
  807. {
  808. struct cipso_v4_std_map_tbl *map_tbl;
  809. switch (doi_def->type) {
  810. case CIPSO_V4_MAP_PASS:
  811. *host_lvl = net_lvl;
  812. return 0;
  813. case CIPSO_V4_MAP_STD:
  814. map_tbl = doi_def->map.std;
  815. if (net_lvl < map_tbl->lvl.cipso_size &&
  816. map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) {
  817. *host_lvl = doi_def->map.std->lvl.cipso[net_lvl];
  818. return 0;
  819. }
  820. break;
  821. }
  822. return -EINVAL;
  823. }
  824. /**
  825. * cipso_v4_map_cat_rbm_valid - Checks to see if the category bitmap is valid
  826. * @doi_def: the DOI definition
  827. * @bitmap: category bitmap
  828. * @bitmap_len: bitmap length in bytes
  829. *
  830. * Description:
  831. * Checks the given category bitmap against the given DOI definition and
  832. * returns a negative value if any of the categories in the bitmap do not have
  833. * a valid mapping and a zero value if all of the categories are valid.
  834. *
  835. */
  836. static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
  837. const unsigned char *bitmap,
  838. u32 bitmap_len)
  839. {
  840. int cat = -1;
  841. u32 bitmap_len_bits = bitmap_len * 8;
  842. u32 cipso_cat_size = doi_def->map.std->cat.cipso_size;
  843. u32 *cipso_array = doi_def->map.std->cat.cipso;
  844. switch (doi_def->type) {
  845. case CIPSO_V4_MAP_PASS:
  846. return 0;
  847. case CIPSO_V4_MAP_STD:
  848. for (;;) {
  849. cat = cipso_v4_bitmap_walk(bitmap,
  850. bitmap_len_bits,
  851. cat + 1,
  852. 1);
  853. if (cat < 0)
  854. break;
  855. if (cat >= cipso_cat_size ||
  856. cipso_array[cat] >= CIPSO_V4_INV_CAT)
  857. return -EFAULT;
  858. }
  859. if (cat == -1)
  860. return 0;
  861. break;
  862. }
  863. return -EFAULT;
  864. }
  865. /**
  866. * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network
  867. * @doi_def: the DOI definition
  868. * @host_cat: the category bitmap in host format
  869. * @host_cat_len: the length of the host's category bitmap in bytes
  870. * @net_cat: the zero'd out category bitmap in network/CIPSO format
  871. * @net_cat_len: the length of the CIPSO bitmap in bytes
  872. *
  873. * Description:
  874. * Perform a label mapping to translate a local MLS category bitmap to the
  875. * correct CIPSO bitmap using the given DOI definition. Returns the minimum
  876. * size in bytes of the network bitmap on success, negative values otherwise.
  877. *
  878. */
  879. static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
  880. const unsigned char *host_cat,
  881. u32 host_cat_len,
  882. unsigned char *net_cat,
  883. u32 net_cat_len)
  884. {
  885. int host_spot = -1;
  886. u32 net_spot;
  887. u32 net_spot_max = 0;
  888. u32 host_clen_bits = host_cat_len * 8;
  889. u32 net_clen_bits = net_cat_len * 8;
  890. u32 host_cat_size = doi_def->map.std->cat.local_size;
  891. u32 *host_cat_array = doi_def->map.std->cat.local;
  892. switch (doi_def->type) {
  893. case CIPSO_V4_MAP_PASS:
  894. net_spot_max = host_cat_len - 1;
  895. while (net_spot_max > 0 && host_cat[net_spot_max] == 0)
  896. net_spot_max--;
  897. if (net_spot_max > net_cat_len)
  898. return -EINVAL;
  899. memcpy(net_cat, host_cat, net_spot_max);
  900. return net_spot_max;
  901. case CIPSO_V4_MAP_STD:
  902. for (;;) {
  903. host_spot = cipso_v4_bitmap_walk(host_cat,
  904. host_clen_bits,
  905. host_spot + 1,
  906. 1);
  907. if (host_spot < 0)
  908. break;
  909. if (host_spot >= host_cat_size)
  910. return -EPERM;
  911. net_spot = host_cat_array[host_spot];
  912. if (net_spot >= net_clen_bits)
  913. return -ENOSPC;
  914. cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
  915. if (net_spot > net_spot_max)
  916. net_spot_max = net_spot;
  917. }
  918. if (host_spot == -2)
  919. return -EFAULT;
  920. if (++net_spot_max % 8)
  921. return net_spot_max / 8 + 1;
  922. return net_spot_max / 8;
  923. }
  924. return -EINVAL;
  925. }
  926. /**
  927. * cipso_v4_map_cat_rbm_ntoh - Perform a category mapping from network to host
  928. * @doi_def: the DOI definition
  929. * @net_cat: the category bitmap in network/CIPSO format
  930. * @net_cat_len: the length of the CIPSO bitmap in bytes
  931. * @host_cat: the zero'd out category bitmap in host format
  932. * @host_cat_len: the length of the host's category bitmap in bytes
  933. *
  934. * Description:
  935. * Perform a label mapping to translate a CIPSO bitmap to the correct local
  936. * MLS category bitmap using the given DOI definition. Returns the minimum
  937. * size in bytes of the host bitmap on success, negative values otherwise.
  938. *
  939. */
  940. static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
  941. const unsigned char *net_cat,
  942. u32 net_cat_len,
  943. unsigned char *host_cat,
  944. u32 host_cat_len)
  945. {
  946. u32 host_spot;
  947. u32 host_spot_max = 0;
  948. int net_spot = -1;
  949. u32 net_clen_bits = net_cat_len * 8;
  950. u32 host_clen_bits = host_cat_len * 8;
  951. u32 net_cat_size = doi_def->map.std->cat.cipso_size;
  952. u32 *net_cat_array = doi_def->map.std->cat.cipso;
  953. switch (doi_def->type) {
  954. case CIPSO_V4_MAP_PASS:
  955. if (net_cat_len > host_cat_len)
  956. return -EINVAL;
  957. memcpy(host_cat, net_cat, net_cat_len);
  958. return net_cat_len;
  959. case CIPSO_V4_MAP_STD:
  960. for (;;) {
  961. net_spot = cipso_v4_bitmap_walk(net_cat,
  962. net_clen_bits,
  963. net_spot + 1,
  964. 1);
  965. if (net_spot < 0)
  966. break;
  967. if (net_spot >= net_cat_size ||
  968. net_cat_array[net_spot] >= CIPSO_V4_INV_CAT)
  969. return -EPERM;
  970. host_spot = net_cat_array[net_spot];
  971. if (host_spot >= host_clen_bits)
  972. return -ENOSPC;
  973. cipso_v4_bitmap_setbit(host_cat, host_spot, 1);
  974. if (host_spot > host_spot_max)
  975. host_spot_max = host_spot;
  976. }
  977. if (net_spot == -2)
  978. return -EFAULT;
  979. if (++host_spot_max % 8)
  980. return host_spot_max / 8 + 1;
  981. return host_spot_max / 8;
  982. }
  983. return -EINVAL;
  984. }
  985. /*
  986. * Protocol Handling Functions
  987. */
  988. #define CIPSO_V4_HDR_LEN 6
  989. /**
  990. * cipso_v4_gentag_hdr - Generate a CIPSO option header
  991. * @doi_def: the DOI definition
  992. * @len: the total tag length in bytes
  993. * @buf: the CIPSO option buffer
  994. *
  995. * Description:
  996. * Write a CIPSO header into the beginning of @buffer. Return zero on success,
  997. * negative values on failure.
  998. *
  999. */
  1000. static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
  1001. u32 len,
  1002. unsigned char *buf)
  1003. {
  1004. if (CIPSO_V4_HDR_LEN + len > 40)
  1005. return -ENOSPC;
  1006. buf[0] = IPOPT_CIPSO;
  1007. buf[1] = CIPSO_V4_HDR_LEN + len;
  1008. *(u32 *)&buf[2] = htonl(doi_def->doi);
  1009. return 0;
  1010. }
  1011. #define CIPSO_V4_TAG1_CAT_LEN 30
  1012. /**
  1013. * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
  1014. * @doi_def: the DOI definition
  1015. * @secattr: the security attributes
  1016. * @buffer: the option buffer
  1017. * @buffer_len: length of buffer in bytes
  1018. *
  1019. * Description:
  1020. * Generate a CIPSO option using the restricted bitmap tag, tag type #1. The
  1021. * actual buffer length may be larger than the indicated size due to
  1022. * translation between host and network category bitmaps. Returns zero on
  1023. * success, negative values on failure.
  1024. *
  1025. */
  1026. static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
  1027. const struct netlbl_lsm_secattr *secattr,
  1028. unsigned char **buffer,
  1029. u32 *buffer_len)
  1030. {
  1031. int ret_val = -EPERM;
  1032. unsigned char *buf = NULL;
  1033. u32 buf_len;
  1034. u32 level;
  1035. if (secattr->mls_cat) {
  1036. buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN,
  1037. GFP_ATOMIC);
  1038. if (buf == NULL)
  1039. return -ENOMEM;
  1040. ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
  1041. secattr->mls_cat,
  1042. secattr->mls_cat_len,
  1043. &buf[CIPSO_V4_HDR_LEN + 4],
  1044. CIPSO_V4_TAG1_CAT_LEN);
  1045. if (ret_val < 0)
  1046. goto gentag_failure;
  1047. /* This will send packets using the "optimized" format when
  1048. * possibile as specified in section 3.4.2.6 of the
  1049. * CIPSO draft. */
  1050. if (cipso_v4_rbm_optfmt && (ret_val > 0 && ret_val < 10))
  1051. ret_val = 10;
  1052. buf_len = 4 + ret_val;
  1053. } else {
  1054. buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC);
  1055. if (buf == NULL)
  1056. return -ENOMEM;
  1057. buf_len = 4;
  1058. }
  1059. ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
  1060. if (ret_val != 0)
  1061. goto gentag_failure;
  1062. ret_val = cipso_v4_gentag_hdr(doi_def, buf_len, buf);
  1063. if (ret_val != 0)
  1064. goto gentag_failure;
  1065. buf[CIPSO_V4_HDR_LEN] = 0x01;
  1066. buf[CIPSO_V4_HDR_LEN + 1] = buf_len;
  1067. buf[CIPSO_V4_HDR_LEN + 3] = level;
  1068. *buffer = buf;
  1069. *buffer_len = CIPSO_V4_HDR_LEN + buf_len;
  1070. return 0;
  1071. gentag_failure:
  1072. kfree(buf);
  1073. return ret_val;
  1074. }
  1075. /**
  1076. * cipso_v4_parsetag_rbm - Parse a CIPSO restricted bitmap tag
  1077. * @doi_def: the DOI definition
  1078. * @tag: the CIPSO tag
  1079. * @secattr: the security attributes
  1080. *
  1081. * Description:
  1082. * Parse a CIPSO restricted bitmap tag (tag type #1) and return the security
  1083. * attributes in @secattr. Return zero on success, negatives values on
  1084. * failure.
  1085. *
  1086. */
  1087. static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
  1088. const unsigned char *tag,
  1089. struct netlbl_lsm_secattr *secattr)
  1090. {
  1091. int ret_val;
  1092. u8 tag_len = tag[1];
  1093. u32 level;
  1094. ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
  1095. if (ret_val != 0)
  1096. return ret_val;
  1097. secattr->mls_lvl = level;
  1098. secattr->mls_lvl_vld = 1;
  1099. if (tag_len > 4) {
  1100. switch (doi_def->type) {
  1101. case CIPSO_V4_MAP_PASS:
  1102. secattr->mls_cat_len = tag_len - 4;
  1103. break;
  1104. case CIPSO_V4_MAP_STD:
  1105. secattr->mls_cat_len =
  1106. doi_def->map.std->cat.local_size;
  1107. break;
  1108. }
  1109. secattr->mls_cat = kzalloc(secattr->mls_cat_len, GFP_ATOMIC);
  1110. if (secattr->mls_cat == NULL)
  1111. return -ENOMEM;
  1112. ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
  1113. &tag[4],
  1114. tag_len - 4,
  1115. secattr->mls_cat,
  1116. secattr->mls_cat_len);
  1117. if (ret_val < 0) {
  1118. kfree(secattr->mls_cat);
  1119. return ret_val;
  1120. }
  1121. secattr->mls_cat_len = ret_val;
  1122. }
  1123. return 0;
  1124. }
  1125. /**
  1126. * cipso_v4_validate - Validate a CIPSO option
  1127. * @option: the start of the option, on error it is set to point to the error
  1128. *
  1129. * Description:
  1130. * This routine is called to validate a CIPSO option, it checks all of the
  1131. * fields to ensure that they are at least valid, see the draft snippet below
  1132. * for details. If the option is valid then a zero value is returned and
  1133. * the value of @option is unchanged. If the option is invalid then a
  1134. * non-zero value is returned and @option is adjusted to point to the
  1135. * offending portion of the option. From the IETF draft ...
  1136. *
  1137. * "If any field within the CIPSO options, such as the DOI identifier, is not
  1138. * recognized the IP datagram is discarded and an ICMP 'parameter problem'
  1139. * (type 12) is generated and returned. The ICMP code field is set to 'bad
  1140. * parameter' (code 0) and the pointer is set to the start of the CIPSO field
  1141. * that is unrecognized."
  1142. *
  1143. */
  1144. int cipso_v4_validate(unsigned char **option)
  1145. {
  1146. unsigned char *opt = *option;
  1147. unsigned char *tag;
  1148. unsigned char opt_iter;
  1149. unsigned char err_offset = 0;
  1150. u8 opt_len;
  1151. u8 tag_len;
  1152. struct cipso_v4_doi *doi_def = NULL;
  1153. u32 tag_iter;
  1154. /* caller already checks for length values that are too large */
  1155. opt_len = opt[1];
  1156. if (opt_len < 8) {
  1157. err_offset = 1;
  1158. goto validate_return;
  1159. }
  1160. rcu_read_lock();
  1161. doi_def = cipso_v4_doi_getdef(ntohl(*((u32 *)&opt[2])));
  1162. if (doi_def == NULL) {
  1163. err_offset = 2;
  1164. goto validate_return_locked;
  1165. }
  1166. opt_iter = 6;
  1167. tag = opt + opt_iter;
  1168. while (opt_iter < opt_len) {
  1169. for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];)
  1170. if (doi_def->tags[tag_iter] == CIPSO_V4_TAG_INVALID ||
  1171. ++tag_iter == CIPSO_V4_TAG_MAXCNT) {
  1172. err_offset = opt_iter;
  1173. goto validate_return_locked;
  1174. }
  1175. tag_len = tag[1];
  1176. if (tag_len > (opt_len - opt_iter)) {
  1177. err_offset = opt_iter + 1;
  1178. goto validate_return_locked;
  1179. }
  1180. switch (tag[0]) {
  1181. case CIPSO_V4_TAG_RBITMAP:
  1182. if (tag_len < 4) {
  1183. err_offset = opt_iter + 1;
  1184. goto validate_return_locked;
  1185. }
  1186. /* We are already going to do all the verification
  1187. * necessary at the socket layer so from our point of
  1188. * view it is safe to turn these checks off (and less
  1189. * work), however, the CIPSO draft says we should do
  1190. * all the CIPSO validations here but it doesn't
  1191. * really specify _exactly_ what we need to validate
  1192. * ... so, just make it a sysctl tunable. */
  1193. if (cipso_v4_rbm_strictvalid) {
  1194. if (cipso_v4_map_lvl_valid(doi_def,
  1195. tag[3]) < 0) {
  1196. err_offset = opt_iter + 3;
  1197. goto validate_return_locked;
  1198. }
  1199. if (tag_len > 4 &&
  1200. cipso_v4_map_cat_rbm_valid(doi_def,
  1201. &tag[4],
  1202. tag_len - 4) < 0) {
  1203. err_offset = opt_iter + 4;
  1204. goto validate_return_locked;
  1205. }
  1206. }
  1207. break;
  1208. default:
  1209. err_offset = opt_iter;
  1210. goto validate_return_locked;
  1211. }
  1212. tag += tag_len;
  1213. opt_iter += tag_len;
  1214. }
  1215. validate_return_locked:
  1216. rcu_read_unlock();
  1217. validate_return:
  1218. *option = opt + err_offset;
  1219. return err_offset;
  1220. }
  1221. /**
  1222. * cipso_v4_error - Send the correct reponse for a bad packet
  1223. * @skb: the packet
  1224. * @error: the error code
  1225. * @gateway: CIPSO gateway flag
  1226. *
  1227. * Description:
  1228. * Based on the error code given in @error, send an ICMP error message back to
  1229. * the originating host. From the IETF draft ...
  1230. *
  1231. * "If the contents of the CIPSO [option] are valid but the security label is
  1232. * outside of the configured host or port label range, the datagram is
  1233. * discarded and an ICMP 'destination unreachable' (type 3) is generated and
  1234. * returned. The code field of the ICMP is set to 'communication with
  1235. * destination network administratively prohibited' (code 9) or to
  1236. * 'communication with destination host administratively prohibited'
  1237. * (code 10). The value of the code is dependent on whether the originator
  1238. * of the ICMP message is acting as a CIPSO host or a CIPSO gateway. The
  1239. * recipient of the ICMP message MUST be able to handle either value. The
  1240. * same procedure is performed if a CIPSO [option] can not be added to an
  1241. * IP packet because it is too large to fit in the IP options area."
  1242. *
  1243. * "If the error is triggered by receipt of an ICMP message, the message is
  1244. * discarded and no response is permitted (consistent with general ICMP
  1245. * processing rules)."
  1246. *
  1247. */
  1248. void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
  1249. {
  1250. if (skb->nh.iph->protocol == IPPROTO_ICMP || error != -EACCES)
  1251. return;
  1252. if (gateway)
  1253. icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0);
  1254. else
  1255. icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
  1256. }
  1257. /**
  1258. * cipso_v4_socket_setattr - Add a CIPSO option to a socket
  1259. * @sock: the socket
  1260. * @doi_def: the CIPSO DOI to use
  1261. * @secattr: the specific security attributes of the socket
  1262. *
  1263. * Description:
  1264. * Set the CIPSO option on the given socket using the DOI definition and
  1265. * security attributes passed to the function. This function requires
  1266. * exclusive access to @sock->sk, which means it either needs to be in the
  1267. * process of being created or locked via lock_sock(sock->sk). Returns zero on
  1268. * success and negative values on failure.
  1269. *
  1270. */
  1271. int cipso_v4_socket_setattr(const struct socket *sock,
  1272. const struct cipso_v4_doi *doi_def,
  1273. const struct netlbl_lsm_secattr *secattr)
  1274. {
  1275. int ret_val = -EPERM;
  1276. u32 iter;
  1277. unsigned char *buf = NULL;
  1278. u32 buf_len = 0;
  1279. u32 opt_len;
  1280. struct ip_options *opt = NULL;
  1281. struct sock *sk;
  1282. struct inet_sock *sk_inet;
  1283. struct inet_connection_sock *sk_conn;
  1284. /* In the case of sock_create_lite(), the sock->sk field is not
  1285. * defined yet but it is not a problem as the only users of these
  1286. * "lite" PF_INET sockets are functions which do an accept() call
  1287. * afterwards so we will label the socket as part of the accept(). */
  1288. sk = sock->sk;
  1289. if (sk == NULL)
  1290. return 0;
  1291. /* XXX - This code assumes only one tag per CIPSO option which isn't
  1292. * really a good assumption to make but since we only support the MAC
  1293. * tags right now it is a safe assumption. */
  1294. iter = 0;
  1295. do {
  1296. switch (doi_def->tags[iter]) {
  1297. case CIPSO_V4_TAG_RBITMAP:
  1298. ret_val = cipso_v4_gentag_rbm(doi_def,
  1299. secattr,
  1300. &buf,
  1301. &buf_len);
  1302. break;
  1303. default:
  1304. ret_val = -EPERM;
  1305. goto socket_setattr_failure;
  1306. }
  1307. iter++;
  1308. } while (ret_val != 0 &&
  1309. iter < CIPSO_V4_TAG_MAXCNT &&
  1310. doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
  1311. if (ret_val != 0)
  1312. goto socket_setattr_failure;
  1313. /* We can't use ip_options_get() directly because it makes a call to
  1314. * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
  1315. * we can't block here. */
  1316. opt_len = (buf_len + 3) & ~3;
  1317. opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
  1318. if (opt == NULL) {
  1319. ret_val = -ENOMEM;
  1320. goto socket_setattr_failure;
  1321. }
  1322. memcpy(opt->__data, buf, buf_len);
  1323. opt->optlen = opt_len;
  1324. opt->is_data = 1;
  1325. kfree(buf);
  1326. buf = NULL;
  1327. ret_val = ip_options_compile(opt, NULL);
  1328. if (ret_val != 0)
  1329. goto socket_setattr_failure;
  1330. sk_inet = inet_sk(sk);
  1331. if (sk_inet->is_icsk) {
  1332. sk_conn = inet_csk(sk);
  1333. if (sk_inet->opt)
  1334. sk_conn->icsk_ext_hdr_len -= sk_inet->opt->optlen;
  1335. sk_conn->icsk_ext_hdr_len += opt->optlen;
  1336. sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
  1337. }
  1338. opt = xchg(&sk_inet->opt, opt);
  1339. kfree(opt);
  1340. return 0;
  1341. socket_setattr_failure:
  1342. kfree(buf);
  1343. kfree(opt);
  1344. return ret_val;
  1345. }
  1346. /**
  1347. * cipso_v4_socket_getattr - Get the security attributes from a socket
  1348. * @sock: the socket
  1349. * @secattr: the security attributes
  1350. *
  1351. * Description:
  1352. * Query @sock to see if there is a CIPSO option attached to the socket and if
  1353. * there is return the CIPSO security attributes in @secattr. Returns zero on
  1354. * success and negative values on failure.
  1355. *
  1356. */
  1357. int cipso_v4_socket_getattr(const struct socket *sock,
  1358. struct netlbl_lsm_secattr *secattr)
  1359. {
  1360. int ret_val = -ENOMSG;
  1361. struct sock *sk;
  1362. struct inet_sock *sk_inet;
  1363. unsigned char *cipso_ptr;
  1364. u32 doi;
  1365. struct cipso_v4_doi *doi_def;
  1366. sk = sock->sk;
  1367. lock_sock(sk);
  1368. sk_inet = inet_sk(sk);
  1369. if (sk_inet->opt == NULL || sk_inet->opt->cipso == 0)
  1370. goto socket_getattr_return;
  1371. cipso_ptr = sk_inet->opt->__data + sk_inet->opt->cipso -
  1372. sizeof(struct iphdr);
  1373. ret_val = cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr);
  1374. if (ret_val == 0)
  1375. goto socket_getattr_return;
  1376. doi = ntohl(*(u32 *)&cipso_ptr[2]);
  1377. rcu_read_lock();
  1378. doi_def = cipso_v4_doi_getdef(doi);
  1379. if (doi_def == NULL) {
  1380. rcu_read_unlock();
  1381. goto socket_getattr_return;
  1382. }
  1383. switch (cipso_ptr[6]) {
  1384. case CIPSO_V4_TAG_RBITMAP:
  1385. ret_val = cipso_v4_parsetag_rbm(doi_def,
  1386. &cipso_ptr[6],
  1387. secattr);
  1388. break;
  1389. }
  1390. rcu_read_unlock();
  1391. socket_getattr_return:
  1392. release_sock(sk);
  1393. return ret_val;
  1394. }
  1395. /**
  1396. * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option
  1397. * @skb: the packet
  1398. * @secattr: the security attributes
  1399. *
  1400. * Description:
  1401. * Parse the given packet's CIPSO option and return the security attributes.
  1402. * Returns zero on success and negative values on failure.
  1403. *
  1404. */
  1405. int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
  1406. struct netlbl_lsm_secattr *secattr)
  1407. {
  1408. int ret_val = -ENOMSG;
  1409. unsigned char *cipso_ptr;
  1410. u32 doi;
  1411. struct cipso_v4_doi *doi_def;
  1412. if (!CIPSO_V4_OPTEXIST(skb))
  1413. return -ENOMSG;
  1414. cipso_ptr = CIPSO_V4_OPTPTR(skb);
  1415. if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
  1416. return 0;
  1417. doi = ntohl(*(u32 *)&cipso_ptr[2]);
  1418. rcu_read_lock();
  1419. doi_def = cipso_v4_doi_getdef(doi);
  1420. if (doi_def == NULL)
  1421. goto skbuff_getattr_return;
  1422. switch (cipso_ptr[6]) {
  1423. case CIPSO_V4_TAG_RBITMAP:
  1424. ret_val = cipso_v4_parsetag_rbm(doi_def,
  1425. &cipso_ptr[6],
  1426. secattr);
  1427. break;
  1428. }
  1429. skbuff_getattr_return:
  1430. rcu_read_unlock();
  1431. return ret_val;
  1432. }
  1433. /*
  1434. * Setup Functions
  1435. */
  1436. /**
  1437. * cipso_v4_init - Initialize the CIPSO module
  1438. *
  1439. * Description:
  1440. * Initialize the CIPSO module and prepare it for use. Returns zero on success
  1441. * and negative values on failure.
  1442. *
  1443. */
  1444. static int __init cipso_v4_init(void)
  1445. {
  1446. int ret_val;
  1447. ret_val = cipso_v4_cache_init();
  1448. if (ret_val != 0)
  1449. panic("Failed to initialize the CIPSO/IPv4 cache (%d)\n",
  1450. ret_val);
  1451. return 0;
  1452. }
  1453. subsys_initcall(cipso_v4_init);