original development tree for Linux kernel GTP module; now long in mainline.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

593 lines
15 KiB

fs: Limit sys_mount to only request filesystem modules. Modify the request_module to prefix the file system type with "fs-" and add aliases to all of the filesystems that can be built as modules to match. A common practice is to build all of the kernel code and leave code that is not commonly needed as modules, with the result that many users are exposed to any bug anywhere in the kernel. Looking for filesystems with a fs- prefix limits the pool of possible modules that can be loaded by mount to just filesystems trivially making things safer with no real cost. Using aliases means user space can control the policy of which filesystem modules are auto-loaded by editing /etc/modprobe.d/*.conf with blacklist and alias directives. Allowing simple, safe, well understood work-arounds to known problematic software. This also addresses a rare but unfortunate problem where the filesystem name is not the same as it's module name and module auto-loading would not work. While writing this patch I saw a handful of such cases. The most significant being autofs that lives in the module autofs4. This is relevant to user namespaces because we can reach the request module in get_fs_type() without having any special permissions, and people get uncomfortable when a user specified string (in this case the filesystem type) goes all of the way to request_module. After having looked at this issue I don't think there is any particular reason to perform any filtering or permission checks beyond making it clear in the module request that we want a filesystem module. The common pattern in the kernel is to call request_module() without regards to the users permissions. In general all a filesystem module does once loaded is call register_filesystem() and go to sleep. Which means there is not much attack surface exposed by loading a filesytem module unless the filesystem is mounted. In a user namespace filesystems are not mounted unless .fs_flags = FS_USERNS_MOUNT, which most filesystems do not set today. Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Acked-by: Kees Cook <keescook@chromium.org> Reported-by: Kees Cook <keescook@google.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
9 years ago
fs: Limit sys_mount to only request filesystem modules. Modify the request_module to prefix the file system type with "fs-" and add aliases to all of the filesystems that can be built as modules to match. A common practice is to build all of the kernel code and leave code that is not commonly needed as modules, with the result that many users are exposed to any bug anywhere in the kernel. Looking for filesystems with a fs- prefix limits the pool of possible modules that can be loaded by mount to just filesystems trivially making things safer with no real cost. Using aliases means user space can control the policy of which filesystem modules are auto-loaded by editing /etc/modprobe.d/*.conf with blacklist and alias directives. Allowing simple, safe, well understood work-arounds to known problematic software. This also addresses a rare but unfortunate problem where the filesystem name is not the same as it's module name and module auto-loading would not work. While writing this patch I saw a handful of such cases. The most significant being autofs that lives in the module autofs4. This is relevant to user namespaces because we can reach the request module in get_fs_type() without having any special permissions, and people get uncomfortable when a user specified string (in this case the filesystem type) goes all of the way to request_module. After having looked at this issue I don't think there is any particular reason to perform any filtering or permission checks beyond making it clear in the module request that we want a filesystem module. The common pattern in the kernel is to call request_module() without regards to the users permissions. In general all a filesystem module does once loaded is call register_filesystem() and go to sleep. Which means there is not much attack surface exposed by loading a filesytem module unless the filesystem is mounted. In a user namespace filesystems are not mounted unless .fs_flags = FS_USERNS_MOUNT, which most filesystems do not set today. Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Acked-by: Kees Cook <keescook@chromium.org> Reported-by: Kees Cook <keescook@google.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
9 years ago
  1. /*
  2. * linux/fs/sysv/inode.c
  3. *
  4. * minix/inode.c
  5. * Copyright (C) 1991, 1992 Linus Torvalds
  6. *
  7. * xenix/inode.c
  8. * Copyright (C) 1992 Doug Evans
  9. *
  10. * coh/inode.c
  11. * Copyright (C) 1993 Pascal Haible, Bruno Haible
  12. *
  13. * sysv/inode.c
  14. * Copyright (C) 1993 Paul B. Monday
  15. *
  16. * sysv/inode.c
  17. * Copyright (C) 1993 Bruno Haible
  18. * Copyright (C) 1997, 1998 Krzysztof G. Baranowski
  19. *
  20. * This file contains code for read/parsing the superblock.
  21. */
  22. #include <linux/module.h>
  23. #include <linux/init.h>
  24. #include <linux/slab.h>
  25. #include <linux/buffer_head.h>
  26. #include "sysv.h"
  27. /*
  28. * The following functions try to recognize specific filesystems.
  29. *
  30. * We recognize:
  31. * - Xenix FS by its magic number.
  32. * - SystemV FS by its magic number.
  33. * - Coherent FS by its funny fname/fpack field.
  34. * - SCO AFS by s_nfree == 0xffff
  35. * - V7 FS has no distinguishing features.
  36. *
  37. * We discriminate among SystemV4 and SystemV2 FS by the assumption that
  38. * the time stamp is not < 01-01-1980.
  39. */
  40. enum {
  41. JAN_1_1980 = (10*365 + 2) * 24 * 60 * 60
  42. };
  43. static void detected_xenix(struct sysv_sb_info *sbi, unsigned *max_links)
  44. {
  45. struct buffer_head *bh1 = sbi->s_bh1;
  46. struct buffer_head *bh2 = sbi->s_bh2;
  47. struct xenix_super_block * sbd1;
  48. struct xenix_super_block * sbd2;
  49. if (bh1 != bh2)
  50. sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
  51. else {
  52. /* block size = 512, so bh1 != bh2 */
  53. sbd1 = (struct xenix_super_block *) bh1->b_data;
  54. sbd2 = (struct xenix_super_block *) (bh2->b_data - 512);
  55. }
  56. *max_links = XENIX_LINK_MAX;
  57. sbi->s_fic_size = XENIX_NICINOD;
  58. sbi->s_flc_size = XENIX_NICFREE;
  59. sbi->s_sbd1 = (char *)sbd1;
  60. sbi->s_sbd2 = (char *)sbd2;
  61. sbi->s_sb_fic_count = &sbd1->s_ninode;
  62. sbi->s_sb_fic_inodes = &sbd1->s_inode[0];
  63. sbi->s_sb_total_free_inodes = &sbd2->s_tinode;
  64. sbi->s_bcache_count = &sbd1->s_nfree;
  65. sbi->s_bcache = &sbd1->s_free[0];
  66. sbi->s_free_blocks = &sbd2->s_tfree;
  67. sbi->s_sb_time = &sbd2->s_time;
  68. sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd1->s_isize);
  69. sbi->s_nzones = fs32_to_cpu(sbi, sbd1->s_fsize);
  70. }
  71. static void detected_sysv4(struct sysv_sb_info *sbi, unsigned *max_links)
  72. {
  73. struct sysv4_super_block * sbd;
  74. struct buffer_head *bh1 = sbi->s_bh1;
  75. struct buffer_head *bh2 = sbi->s_bh2;
  76. if (bh1 == bh2)
  77. sbd = (struct sysv4_super_block *) (bh1->b_data + BLOCK_SIZE/2);
  78. else
  79. sbd = (struct sysv4_super_block *) bh2->b_data;
  80. *max_links = SYSV_LINK_MAX;
  81. sbi->s_fic_size = SYSV_NICINOD;
  82. sbi->s_flc_size = SYSV_NICFREE;
  83. sbi->s_sbd1 = (char *)sbd;
  84. sbi->s_sbd2 = (char *)sbd;
  85. sbi->s_sb_fic_count = &sbd->s_ninode;
  86. sbi->s_sb_fic_inodes = &sbd->s_inode[0];
  87. sbi->s_sb_total_free_inodes = &sbd->s_tinode;
  88. sbi->s_bcache_count = &sbd->s_nfree;
  89. sbi->s_bcache = &sbd->s_free[0];
  90. sbi->s_free_blocks = &sbd->s_tfree;
  91. sbi->s_sb_time = &sbd->s_time;
  92. sbi->s_sb_state = &sbd->s_state;
  93. sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize);
  94. sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
  95. }
  96. static void detected_sysv2(struct sysv_sb_info *sbi, unsigned *max_links)
  97. {
  98. struct sysv2_super_block *sbd;
  99. struct buffer_head *bh1 = sbi->s_bh1;
  100. struct buffer_head *bh2 = sbi->s_bh2;
  101. if (bh1 == bh2)
  102. sbd = (struct sysv2_super_block *) (bh1->b_data + BLOCK_SIZE/2);
  103. else
  104. sbd = (struct sysv2_super_block *) bh2->b_data;
  105. *max_links = SYSV_LINK_MAX;
  106. sbi->s_fic_size = SYSV_NICINOD;
  107. sbi->s_flc_size = SYSV_NICFREE;
  108. sbi->s_sbd1 = (char *)sbd;
  109. sbi->s_sbd2 = (char *)sbd;
  110. sbi->s_sb_fic_count = &sbd->s_ninode;
  111. sbi->s_sb_fic_inodes = &sbd->s_inode[0];
  112. sbi->s_sb_total_free_inodes = &sbd->s_tinode;
  113. sbi->s_bcache_count = &sbd->s_nfree;
  114. sbi->s_bcache = &sbd->s_free[0];
  115. sbi->s_free_blocks = &sbd->s_tfree;
  116. sbi->s_sb_time = &sbd->s_time;
  117. sbi->s_sb_state = &sbd->s_state;
  118. sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize);
  119. sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
  120. }
  121. static void detected_coherent(struct sysv_sb_info *sbi, unsigned *max_links)
  122. {
  123. struct coh_super_block * sbd;
  124. struct buffer_head *bh1 = sbi->s_bh1;
  125. sbd = (struct coh_super_block *) bh1->b_data;
  126. *max_links = COH_LINK_MAX;
  127. sbi->s_fic_size = COH_NICINOD;
  128. sbi->s_flc_size = COH_NICFREE;
  129. sbi->s_sbd1 = (char *)sbd;
  130. sbi->s_sbd2 = (char *)sbd;
  131. sbi->s_sb_fic_count = &sbd->s_ninode;
  132. sbi->s_sb_fic_inodes = &sbd->s_inode[0];
  133. sbi->s_sb_total_free_inodes = &sbd->s_tinode;
  134. sbi->s_bcache_count = &sbd->s_nfree;
  135. sbi->s_bcache = &sbd->s_free[0];
  136. sbi->s_free_blocks = &sbd->s_tfree;
  137. sbi->s_sb_time = &sbd->s_time;
  138. sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize);
  139. sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
  140. }
  141. static void detected_v7(struct sysv_sb_info *sbi, unsigned *max_links)
  142. {
  143. struct buffer_head *bh2 = sbi->s_bh2;
  144. struct v7_super_block *sbd = (struct v7_super_block *)bh2->b_data;
  145. *max_links = V7_LINK_MAX;
  146. sbi->s_fic_size = V7_NICINOD;
  147. sbi->s_flc_size = V7_NICFREE;
  148. sbi->s_sbd1 = (char *)sbd;
  149. sbi->s_sbd2 = (char *)sbd;
  150. sbi->s_sb_fic_count = &sbd->s_ninode;
  151. sbi->s_sb_fic_inodes = &sbd->s_inode[0];
  152. sbi->s_sb_total_free_inodes = &sbd->s_tinode;
  153. sbi->s_bcache_count = &sbd->s_nfree;
  154. sbi->s_bcache = &sbd->s_free[0];
  155. sbi->s_free_blocks = &sbd->s_tfree;
  156. sbi->s_sb_time = &sbd->s_time;
  157. sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize);
  158. sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
  159. }
  160. static int detect_xenix(struct sysv_sb_info *sbi, struct buffer_head *bh)
  161. {
  162. struct xenix_super_block *sbd = (struct xenix_super_block *)bh->b_data;
  163. if (*(__le32 *)&sbd->s_magic == cpu_to_le32(0x2b5544))
  164. sbi->s_bytesex = BYTESEX_LE;
  165. else if (*(__be32 *)&sbd->s_magic == cpu_to_be32(0x2b5544))
  166. sbi->s_bytesex = BYTESEX_BE;
  167. else
  168. return 0;
  169. switch (fs32_to_cpu(sbi, sbd->s_type)) {
  170. case 1:
  171. sbi->s_type = FSTYPE_XENIX;
  172. return 1;
  173. case 2:
  174. sbi->s_type = FSTYPE_XENIX;
  175. return 2;
  176. default:
  177. return 0;
  178. }
  179. }
  180. static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh)
  181. {
  182. struct super_block *sb = sbi->s_sb;
  183. /* All relevant fields are at the same offsets in R2 and R4 */
  184. struct sysv4_super_block * sbd;
  185. u32 type;
  186. sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
  187. if (*(__le32 *)&sbd->s_magic == cpu_to_le32(0xfd187e20))
  188. sbi->s_bytesex = BYTESEX_LE;
  189. else if (*(__be32 *)&sbd->s_magic == cpu_to_be32(0xfd187e20))
  190. sbi->s_bytesex = BYTESEX_BE;
  191. else
  192. return 0;
  193. type = fs32_to_cpu(sbi, sbd->s_type);
  194. if (fs16_to_cpu(sbi, sbd->s_nfree) == 0xffff) {
  195. sbi->s_type = FSTYPE_AFS;
  196. sbi->s_forced_ro = 1;
  197. if (!(sb->s_flags & MS_RDONLY)) {
  198. printk("SysV FS: SCO EAFS on %s detected, "
  199. "forcing read-only mode.\n",
  200. sb->s_id);
  201. }
  202. return type;
  203. }
  204. if (fs32_to_cpu(sbi, sbd->s_time) < JAN_1_1980) {
  205. /* this is likely to happen on SystemV2 FS */
  206. if (type > 3 || type < 1)
  207. return 0;
  208. sbi->s_type = FSTYPE_SYSV2;
  209. return type;
  210. }
  211. if ((type > 3 || type < 1) && (type > 0x30 || type < 0x10))
  212. return 0;
  213. /* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
  214. 0x20 or 0x30 indicates that symbolic links and the 14-character
  215. filename limit is gone. Due to lack of information about this
  216. feature read-only mode seems to be a reasonable approach... -KGB */
  217. if (type >= 0x10) {
  218. printk("SysV FS: can't handle long file names on %s, "
  219. "forcing read-only mode.\n", sb->s_id);
  220. sbi->s_forced_ro = 1;
  221. }
  222. sbi->s_type = FSTYPE_SYSV4;
  223. return type >= 0x10 ? type >> 4 : type;
  224. }
  225. static int detect_coherent(struct sysv_sb_info *sbi, struct buffer_head *bh)
  226. {
  227. struct coh_super_block * sbd;
  228. sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2);
  229. if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
  230. || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
  231. return 0;
  232. sbi->s_bytesex = BYTESEX_PDP;
  233. sbi->s_type = FSTYPE_COH;
  234. return 1;
  235. }
  236. static int detect_sysv_odd(struct sysv_sb_info *sbi, struct buffer_head *bh)
  237. {
  238. int size = detect_sysv(sbi, bh);
  239. return size>2 ? 0 : size;
  240. }
  241. static struct {
  242. int block;
  243. int (*test)(struct sysv_sb_info *, struct buffer_head *);
  244. } flavours[] = {
  245. {1, detect_xenix},
  246. {0, detect_sysv},
  247. {0, detect_coherent},
  248. {9, detect_sysv_odd},
  249. {15,detect_sysv_odd},
  250. {18,detect_sysv},
  251. };
  252. static char *flavour_names[] = {
  253. [FSTYPE_XENIX] = "Xenix",
  254. [FSTYPE_SYSV4] = "SystemV",
  255. [FSTYPE_SYSV2] = "SystemV Release 2",
  256. [FSTYPE_COH] = "Coherent",
  257. [FSTYPE_V7] = "V7",
  258. [FSTYPE_AFS] = "AFS",
  259. };
  260. static void (*flavour_setup[])(struct sysv_sb_info *, unsigned *) = {
  261. [FSTYPE_XENIX] = detected_xenix,
  262. [FSTYPE_SYSV4] = detected_sysv4,
  263. [FSTYPE_SYSV2] = detected_sysv2,
  264. [FSTYPE_COH] = detected_coherent,
  265. [FSTYPE_V7] = detected_v7,
  266. [FSTYPE_AFS] = detected_sysv4,
  267. };
  268. static int complete_read_super(struct super_block *sb, int silent, int size)
  269. {
  270. struct sysv_sb_info *sbi = SYSV_SB(sb);
  271. struct inode *root_inode;
  272. char *found = flavour_names[sbi->s_type];
  273. u_char n_bits = size+8;
  274. int bsize = 1 << n_bits;
  275. int bsize_4 = bsize >> 2;
  276. sbi->s_firstinodezone = 2;
  277. flavour_setup[sbi->s_type](sbi, &sb->s_max_links);
  278. sbi->s_truncate = 1;
  279. sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone;
  280. sbi->s_inodes_per_block = bsize >> 6;
  281. sbi->s_inodes_per_block_1 = (bsize >> 6)-1;
  282. sbi->s_inodes_per_block_bits = n_bits-6;
  283. sbi->s_ind_per_block = bsize_4;
  284. sbi->s_ind_per_block_2 = bsize_4*bsize_4;
  285. sbi->s_toobig_block = 10 + bsize_4 * (1 + bsize_4 * (1 + bsize_4));
  286. sbi->s_ind_per_block_bits = n_bits-2;
  287. sbi->s_ninodes = (sbi->s_firstdatazone - sbi->s_firstinodezone)
  288. << sbi->s_inodes_per_block_bits;
  289. if (!silent)
  290. printk("VFS: Found a %s FS (block size = %ld) on device %s\n",
  291. found, sb->s_blocksize, sb->s_id);
  292. sb->s_magic = SYSV_MAGIC_BASE + sbi->s_type;
  293. /* set up enough so that it can read an inode */
  294. sb->s_op = &sysv_sops;
  295. if (sbi->s_forced_ro)
  296. sb->s_flags |= MS_RDONLY;
  297. if (sbi->s_truncate)
  298. sb->s_d_op = &sysv_dentry_operations;
  299. root_inode = sysv_iget(sb, SYSV_ROOT_INO);
  300. if (IS_ERR(root_inode)) {
  301. printk("SysV FS: get root inode failed\n");
  302. return 0;
  303. }
  304. sb->s_root = d_make_root(root_inode);
  305. if (!sb->s_root) {
  306. printk("SysV FS: get root dentry failed\n");
  307. return 0;
  308. }
  309. return 1;
  310. }
  311. static int sysv_fill_super(struct super_block *sb, void *data, int silent)
  312. {
  313. struct buffer_head *bh1, *bh = NULL;
  314. struct sysv_sb_info *sbi;
  315. unsigned long blocknr;
  316. int size = 0, i;
  317. BUILD_BUG_ON(1024 != sizeof (struct xenix_super_block));
  318. BUILD_BUG_ON(512 != sizeof (struct sysv4_super_block));
  319. BUILD_BUG_ON(512 != sizeof (struct sysv2_super_block));
  320. BUILD_BUG_ON(500 != sizeof (struct coh_super_block));
  321. BUILD_BUG_ON(64 != sizeof (struct sysv_inode));
  322. sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
  323. if (!sbi)
  324. return -ENOMEM;
  325. sbi->s_sb = sb;
  326. sbi->s_block_base = 0;
  327. mutex_init(&sbi->s_lock);
  328. sb->s_fs_info = sbi;
  329. sb_set_blocksize(sb, BLOCK_SIZE);
  330. for (i = 0; i < ARRAY_SIZE(flavours) && !size; i++) {
  331. brelse(bh);
  332. bh = sb_bread(sb, flavours[i].block);
  333. if (!bh)
  334. continue;
  335. size = flavours[i].test(SYSV_SB(sb), bh);
  336. }
  337. if (!size)
  338. goto Eunknown;
  339. switch (size) {
  340. case 1:
  341. blocknr = bh->b_blocknr << 1;
  342. brelse(bh);
  343. sb_set_blocksize(sb, 512);
  344. bh1 = sb_bread(sb, blocknr);
  345. bh = sb_bread(sb, blocknr + 1);
  346. break;
  347. case 2:
  348. bh1 = bh;
  349. break;
  350. case 3:
  351. blocknr = bh->b_blocknr >> 1;
  352. brelse(bh);
  353. sb_set_blocksize(sb, 2048);
  354. bh1 = bh = sb_bread(sb, blocknr);
  355. break;
  356. default:
  357. goto Ebadsize;
  358. }
  359. if (bh && bh1) {
  360. sbi->s_bh1 = bh1;
  361. sbi->s_bh2 = bh;
  362. if (complete_read_super(sb, silent, size))
  363. return 0;
  364. }
  365. brelse(bh1);
  366. brelse(bh);
  367. sb_set_blocksize(sb, BLOCK_SIZE);
  368. printk("oldfs: cannot read superblock\n");
  369. failed:
  370. kfree(sbi);
  371. return -EINVAL;
  372. Eunknown:
  373. brelse(bh);
  374. if (!silent)
  375. printk("VFS: unable to find oldfs superblock on device %s\n",
  376. sb->s_id);
  377. goto failed;
  378. Ebadsize:
  379. brelse(bh);
  380. if (!silent)
  381. printk("VFS: oldfs: unsupported block size (%dKb)\n",
  382. 1<<(size-2));
  383. goto failed;
  384. }
  385. static int v7_sanity_check(struct super_block *sb, struct buffer_head *bh)
  386. {
  387. struct v7_super_block *v7sb;
  388. struct sysv_inode *v7i;
  389. struct buffer_head *bh2;
  390. struct sysv_sb_info *sbi;
  391. sbi = sb->s_fs_info;
  392. /* plausibility check on superblock */
  393. v7sb = (struct v7_super_block *) bh->b_data;
  394. if (fs16_to_cpu(sbi, v7sb->s_nfree) > V7_NICFREE ||
  395. fs16_to_cpu(sbi, v7sb->s_ninode) > V7_NICINOD ||
  396. fs32_to_cpu(sbi, v7sb->s_fsize) > V7_MAXSIZE)
  397. return 0;
  398. /* plausibility check on root inode: it is a directory,
  399. with a nonzero size that is a multiple of 16 */
  400. bh2 = sb_bread(sb, 2);
  401. if (bh2 == NULL)
  402. return 0;
  403. v7i = (struct sysv_inode *)(bh2->b_data + 64);
  404. if ((fs16_to_cpu(sbi, v7i->i_mode) & ~0777) != S_IFDIR ||
  405. (fs32_to_cpu(sbi, v7i->i_size) == 0) ||
  406. (fs32_to_cpu(sbi, v7i->i_size) & 017) ||
  407. (fs32_to_cpu(sbi, v7i->i_size) > V7_NFILES *
  408. sizeof(struct sysv_dir_entry))) {
  409. brelse(bh2);
  410. return 0;
  411. }
  412. brelse(bh2);
  413. return 1;
  414. }
  415. static int v7_fill_super(struct super_block *sb, void *data, int silent)
  416. {
  417. struct sysv_sb_info *sbi;
  418. struct buffer_head *bh;
  419. if (440 != sizeof (struct v7_super_block))
  420. panic("V7 FS: bad super-block size");
  421. if (64 != sizeof (struct sysv_inode))
  422. panic("sysv fs: bad i-node size");
  423. sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
  424. if (!sbi)
  425. return -ENOMEM;
  426. sbi->s_sb = sb;
  427. sbi->s_block_base = 0;
  428. sbi->s_type = FSTYPE_V7;
  429. mutex_init(&sbi->s_lock);
  430. sb->s_fs_info = sbi;
  431. sb_set_blocksize(sb, 512);
  432. if ((bh = sb_bread(sb, 1)) == NULL) {
  433. if (!silent)
  434. printk("VFS: unable to read V7 FS superblock on "
  435. "device %s.\n", sb->s_id);
  436. goto failed;
  437. }
  438. /* Try PDP-11 UNIX */
  439. sbi->s_bytesex = BYTESEX_PDP;
  440. if (v7_sanity_check(sb, bh))
  441. goto detected;
  442. /* Try PC/IX, v7/x86 */
  443. sbi->s_bytesex = BYTESEX_LE;
  444. if (v7_sanity_check(sb, bh))
  445. goto detected;
  446. goto failed;
  447. detected:
  448. sbi->s_bh1 = bh;
  449. sbi->s_bh2 = bh;
  450. if (complete_read_super(sb, silent, 1))
  451. return 0;
  452. failed:
  453. printk(KERN_ERR "VFS: could not find a valid V7 on %s.\n",
  454. sb->s_id);
  455. brelse(bh);
  456. kfree(sbi);
  457. return -EINVAL;
  458. }
  459. /* Every kernel module contains stuff like this. */
  460. static struct dentry *sysv_mount(struct file_system_type *fs_type,
  461. int flags, const char *dev_name, void *data)
  462. {
  463. return mount_bdev(fs_type, flags, dev_name, data, sysv_fill_super);
  464. }
  465. static struct dentry *v7_mount(struct file_system_type *fs_type,
  466. int flags, const char *dev_name, void *data)
  467. {
  468. return mount_bdev(fs_type, flags, dev_name, data, v7_fill_super);
  469. }
  470. static struct file_system_type sysv_fs_type = {
  471. .owner = THIS_MODULE,
  472. .name = "sysv",
  473. .mount = sysv_mount,
  474. .kill_sb = kill_block_super,
  475. .fs_flags = FS_REQUIRES_DEV,
  476. };
  477. MODULE_ALIAS_FS("sysv");
  478. static struct file_system_type v7_fs_type = {
  479. .owner = THIS_MODULE,
  480. .name = "v7",
  481. .mount = v7_mount,
  482. .kill_sb = kill_block_super,
  483. .fs_flags = FS_REQUIRES_DEV,
  484. };
  485. MODULE_ALIAS_FS("v7");
  486. MODULE_ALIAS("v7");
  487. static int __init init_sysv_fs(void)
  488. {
  489. int error;
  490. error = sysv_init_icache();
  491. if (error)
  492. goto out;
  493. error = register_filesystem(&sysv_fs_type);
  494. if (error)
  495. goto destroy_icache;
  496. error = register_filesystem(&v7_fs_type);
  497. if (error)
  498. goto unregister;
  499. return 0;
  500. unregister:
  501. unregister_filesystem(&sysv_fs_type);
  502. destroy_icache:
  503. sysv_destroy_icache();
  504. out:
  505. return error;
  506. }
  507. static void __exit exit_sysv_fs(void)
  508. {
  509. unregister_filesystem(&sysv_fs_type);
  510. unregister_filesystem(&v7_fs_type);
  511. sysv_destroy_icache();
  512. }
  513. module_init(init_sysv_fs)
  514. module_exit(exit_sysv_fs)
  515. MODULE_LICENSE("GPL");