无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: 不点
打印 上一主题 下一主题

最简单的 Linux 文件系统是哪个?

    [复制链接]
31#
 楼主| 发表于 2019-3-12 08:36:28 | 只看该作者
2011os_defend 发表于 2019-3-11 20:51
同意前辈的看法,xfs更新得算比较频繁,功能也越来越多。

另外ext3对手应该是ntfs吧?

ext2/3/4之类的,属于 Linux/Unix 阵营;FAT/NTFS 类的属于微软阵营。阵营不同,谈不上 “对手”。FAT/NTFS 类的文件系统,只能在 Linux 中作为辅助文件系统,不能作为主文件系统。而 ext2/3/4 在 Linux 中是“主”的地位,但在微软那里,需要下载一个第三方的文件系统驱动程序,才可以支持它,就是说,处于很“次”的地位。当然了,如果讨论纯技术,就某个侧重点来看,或许 ext3 是 NTFS 的对手,我对两者都没研究,不了解这方面的问题。
回复

使用道具 举报

32#
 楼主| 发表于 2019-3-12 09:45:24 | 只看该作者
gnuxwy 发表于 2019-3-11 22:38
真氏不懂这些底层文件系统的实现细节,看到不点大师的分析,真的有不明觉厉的感觉。。。

真人不露相,您太客气了。文件系统是旧领域,不是新领域。万事万物,都有一个发展过程。每个发展的阶段,也都有其缺点或局限性,都有改进的余地,都可以加入新的思想在里面。在新思想渗透进去之后,或许也可看成是进入新领域了。

搞技术,就是要不断创新。创新是一个思想,一个思路。如果思想死了、思路断了,那就会说 “创新是找死”。有人说,创新是引领发展的动力,而也有人说,创新是找死。这两种都对。这两种反映的是不同的思想状况和不同的思路。创新是来解决事物发展中的矛盾的,是促进事物发展的。创新需要在一定程度上敢于打破教条,打破某些规范。创新也得保持现有的一些框框和规范,不能全盘否定,走极端。我们可以利用的资源总是有限的,我们在各种资源的利用上,就需要有取舍,有侧重点。需要在磁盘占用率以及访问效率等问题上,进行平衡。从某个角度来看,创新也不过就是权衡而已,通过权衡找到更有利的东西。再抽象一点,这就是哲学了。我们通过学习、研究、思考,来对比不同的文件系统的设计,合理抽取各自的优点,从而构造出一个新的文件系统,这大概也属于正常的思维模式吧,符合一般的科学研究或科学探索的规律(或特征)。还有一点非常重要的,就是,外行可做事。外行,就是门外汉的意思。外行不是不能做事,而是 “可做事”,有事可做。你想做事,就能做。你不想做事,整天到处游玩,那也一天天过去了。而且,有些事,还真得是只有外行才可能去做的,你信不信?他是内行,但由于某种原因,他不干那事。比如有可能是这样的情况:某些事做了白做、没好处,甚至做了反而对他(或他的公司)不利(有坏处),他就不可能去做。为什么各大公司都在免费让你下载他们的 APP 或“客户端”?甚至也有公司用金钱鼓励你下载安装的!那个 APP 客户端,肯定对他们公司有利。我以前在其他地方也经常说,这东西都是流氓,虽然流氓也是 “合理”的。你让这样有钱的公司去开发一个没有后门的 Linux 或者一个藏不住秘密的文件系统?凭啥啊?它怎么会去干呢?它钱多了,可以放火烧了,也不会去干这样的事情的。
回复

使用道具 举报

33#
 楼主| 发表于 2019-3-12 21:06:31 | 只看该作者
接上文。

刚才谈到 APP 客户端。微软的系统,不限制任何软件的运行,至少以前是不限制。现在微软也在变化,也在设法限制用户。此处实在无法谈论好和坏。好的东西,如果没人生产它,怎么能好?坏的东西,也不会是绝对的坏,它也有好的一些方面。微软不限制软件的运行,这就让 Windows 成了跑马场,谁都可以上场踢腾。这就是说,微软的开放程度比较高。开放程度高,流氓软件、病毒也就更加泛滥,其中也就包括了 “客户端”。苹果是个封闭的系统,它就不让你随便运行软件。好处是,流氓软件也少。但话又说回来了,那就只剩下苹果自己当流氓了,它自己有完全的自由,想怎么耍你,就怎么耍你。你被完全锁在它的监狱里。失去自由的你,多年以后,显然后悔当初买了苹果。但是,死要面子,硬是说苹果的手机在水泥地上使劲摔也摔不坏,是非常优秀的。Android 比苹果开放,这才占领了苹果的江山。Android 像 Windows 那样,随便可以运行软件,因此,流氓软件也多。但 Android 和 Windows 不同的是,Android 采用权限控制,用户得不到 root 权限,不能更改系统,这样,系统永远可以恢复出厂设置,就不怕死掉了。但缺点是,这跟苹果类似,厂家耍流氓,预装流氓软件,控制用户,盗窃用户资料,泄漏用户秘密,用户只能忍受,毫无办法。 Android 有一半像微软的开放,另一半像苹果的封闭。Android 系统也有彻底死掉的,无法恢复出厂设置。这种情况有可能是用户私自 root 以后造成的,破坏了预装的软件,导致彻底无法恢复。也有可能是预装的流氓软件干的,它有着最高的权限,有能力搞破坏,让系统瘫痪。如果按照常规思维,肯定是微软的“全开放”,对用户更友好吧?可是,全开放以后,跑马场乱糟糟的,流氓病毒太猖狂,用户们通常没有驾驭能力,被耍得筋疲力尽。因此,用户们甘愿被人家 Android 预装软件控制住,反而觉得很省心。所以,后来微软也开始学习 Android 的这种封闭做法了。

点评

牛牛!不点大大!找到了“一般用户为什么傻”的根源, 本来一个菜市场,一些菜贩将它搅乱,导致没人来买菜,都去超市、专卖店了,菜市场的菜贩也只得转行。  详情 回复 发表于 2019-3-13 18:22
回复

使用道具 举报

34#
发表于 2019-3-13 18:22:43 | 只看该作者
不点 发表于 2019-3-12 21:06
接上文。

刚才谈到 APP 客户端。微软的系统,不限制任何软件的运行,至少以前是不限制。现在微软也在变 ...

牛牛!不点大大!找到了“一般用户为什么傻”的根源,

本来一个菜市场,一些菜贩将它搅乱,导致没人来买菜,都去超市、专卖店了,菜市场的菜贩也只得转行。

点评

说的没错,有几次去自由市场买菜,本来也不经常去,只是偶然去了几次。结果你猜咋了?他们卖给我的价格,竟然比超市还贵。它这叫自毁市场啊!只要被骗一次,以后再去那里,就有心理障碍了:“一朝被蛇咬,十年怕井绳  详情 回复 发表于 2019-3-13 19:20
回复

使用道具 举报

35#
 楼主| 发表于 2019-3-13 19:20:48 | 只看该作者
易广白 发表于 2019-3-13 18:22
牛牛!不点大大!找到了“一般用户为什么傻”的根源,

本来一个菜市场,一些菜贩将它搅乱,导致没人来 ...

说的没错,有几次去自由市场买菜,本来也不经常去,只是偶然去了几次。结果你猜咋了?他们卖给我的价格,竟然比超市还贵。它这叫自毁市场啊!只要被骗一次,以后再去那里,就有心理障碍了:“一朝被蛇咬,十年怕井绳”。还是超市比较可信,俗话说,跑了和尚跑不了庙,它要为它的信誉负责。扯远点,美国讲求 “美国第一”,其实,美国一直都没把别国看得重要,它一直都是 “美国第一”。它现在再来提说 “美国第一”,那口味肯定很重。它现在的 “美国第一”,我理解为要从别国身上 “揩油”,或者说是要欺负别国了,这才是 “美国第一”的实在含义。这样的做法,杀鸡取卵,拿自己的国家信誉进行 “消费”,而且是 “透支”。其实是毁掉这个国家而已。看看以后的继任者会不会沿着这条不归路继续走下去。

点评

去超市没有菜市场自由,而且不够丰富,人情味也少了许多,生活都少了乐趣,这又变成了“城市综合症”。 一些老人家坚持去菜市场,与奸商“斗智斗勇”,象俺们吗?  详情 回复 发表于 2019-3-13 20:10
回复

使用道具 举报

36#
发表于 2019-3-13 20:10:54 | 只看该作者
不点 发表于 2019-3-13 19:20
说的没错,有几次去自由市场买菜,本来也不经常去,只是偶然去了几次。结果你猜咋了?他们卖给我的价格, ...

去超市没有菜市场自由,而且不够丰富,人情味也少了许多,生活都少了乐趣,这又变成了“城市综合症”。
一些老人家坚持去菜市场,与奸商“斗智斗勇”,象俺们吗?
回复

使用道具 举报

37#
 楼主| 发表于 2019-3-14 20:42:15 | 只看该作者
本帖最后由 不点 于 2019-3-16 16:44 编辑

为方便起见,新的文件系统,暂时就叫做 sefs 吧(意思是 simple and easy file system)。

文件系统的整体结构分两部分:引导区(含 super block 参数)+数据区。整个文件系统的空间,划分成很多簇,每簇的长度固定为 4K。就是说,无论物理扇区大小是 512 字节、2048 字节、还是 4096 字节,每簇都固定为 4096 字节(相当于 8 个 512 字节的小扇区)。第一簇的簇号是 0,作为引导区(含 super block 参数)。引导区也只占这一簇,剩下的都划归数据区。就是说,从簇号 1 开始,直到卷的结尾,就是数据区。FAT 表的位置是灵活的,它不是固定放在开头,而是可以放在任意一片连续的空间中。FAT 表的起始簇号和长度记录在 super block 参数中。根目录的起始簇号也记录在 super block 参数中。根目录的拥有者和权限等,以后再设计。根目录下有两个文件 /.bootblk 和 /.fattbl 分别用来访问引导区和 FAT 表(由 root 用户只读访问;root 用户也不能写)。今后如果需要的话,可以添加 Allocation bitmap,处理方式与 FAT 类似。

以下是 super block(引导扇区) 的初步设计(本帖将会不断修订完善)。

更动记录:2019-03-16 偏移 0E 处添加保留簇数(双字节整数)。保留簇也包括了引导簇在内,用于保存文件系统的一些关键的或辅助的信息。仍用 .bootblk 来表示它。

sefs Boot Sector(设计)
Offset
Size
Description
Comments
0x00
3
JumpBoot
EB ?? 90
0x03
8
FileSystemName
"SEFS"
0x0B
1
BytesPerSectorShift
Power of 2.
Minimum 9 (512 bytes per sector),
maximum 12 (4096 bytes per sector)
0x0C
1
SectorsPerClusterShift
Power of 2.
12 – BytesPerSectorShift, so cluster size is 4 KB
0x0D
1
DriveSelect
Extended INT 13h drive number; typically 0x80
0x0E
2
ReservedClusters
0x10
8
PartitionOffset
In sectors; if 0, shall be ignored
0x18
8
VolumeLength
Size of volume in sectors
0x20
4
FatCluster
FAT start cluster number. FAT must be contiguous
0x24
4
FatLength
In clusters.
0x28
4
Reserved? ClusterHeapOffset
0x2C
4
Reserved
? ClusterCount. 2^32-11 is the maximum number of clusters could be described
0x30
4
RootDirectoryCluster

0x34
4
Reserved? VolumeSerialNumber
0x38
2
Reserved
? FileSystemRevision, as MAJOR.minor, major revision is high byte, minor is low byte; currently 00.00
0x3A
2
Reserved? VolumeFlags * ↓
Offset
Size
Field
0
1
Reserved (no meaning)
1
1
VolumeDirty (0-clean, 1-dirty)
2
1
MediaFailure (0 – no failures reported or they already marked as BAD clusters) 1- some read/write operations failed)
3
1
ClearToZero (no meaning)
4
12
Reserved (no meaning)
0x3C
4
Reserved

0x40
446
BootCode

0x1FE
2
BootSignature
0xAA55
0x200
3584
Reserved


回复

使用道具 举报

38#
 楼主| 发表于 2019-3-15 11:10:20 | 只看该作者
(sefs 设计,续上)FAT 就像一个普通文件那样,占据连续的簇号。Allocation bitmap 只是为了加快空闲空间的查找速度的,它处于辅助地位。Allocation bitmap 续尾在连续的 FAT 之后(续尾后,仍是连续的文件,它在根目录项中的文件名是 .fattbl)。Boot sector 中记录了 FAT length,因此,可以定位尾部的 Allocation bitmap 的位置。 在创建文件系统(格式化)时,首先要分配 FAT (连同 Allocation bitmap),通常放在数据区的最开头(就是紧接 boot 簇之后)。当文件系统(卷)需要动态调整其大小的时候,FAT(连同 Allocation bitmap)就可以调整到别的位置了(当然仍须保持连续)。接着要分配根目录。根目录项中的第一个有效条目,记录着根目录自己的拥有者、权限等信息(相应于 inode 结构里面的信息),当然,其中有一条信息是指示根目录自己的起始簇号(指向它现在的位置)。一般的目录文件的具体结构,以后再设计。但大致上可以确定,目录文件开头有个信息区域,指示该目录的一些属性。接着才是目录项的各个条目。安全起见,.bootblk 和 .fattbl 也可以放在一个子目录中(比如叫做 .fsstruct),子目录设置为不可进入,不可读写。
回复

使用道具 举报

39#
 楼主| 发表于 2019-3-15 15:16:55 | 只看该作者
看看 kernel 里一般化的 inode 结构:
  1. /*
  2. * Keep mostly read-only and often accessed (especially for
  3. * the RCU path lookup and 'stat' data) fields at the beginning
  4. * of the 'struct inode'
  5. */
  6. struct inode {
  7.         umode_t                        i_mode;
  8.         unsigned short                i_opflags;
  9.         kuid_t                        i_uid;
  10.         kgid_t                        i_gid;
  11.         unsigned int                i_flags;

  12. #ifdef CONFIG_FS_POSIX_ACL
  13.         struct posix_acl        *i_acl;
  14.         struct posix_acl        *i_default_acl;
  15. #endif

  16.         const struct inode_operations        *i_op;
  17.         struct super_block        *i_sb;
  18.         struct address_space        *i_mapping;

  19. #ifdef CONFIG_SECURITY
  20.         void                        *i_security;
  21. #endif

  22.         /* Stat data, not accessed from path walking */
  23.         unsigned long                i_ino;
  24.         /*
  25.          * Filesystems may only read i_nlink directly.  They shall use the
  26.          * following functions for modification:
  27.          *
  28.          *    (set|clear|inc|drop)_nlink
  29.          *    inode_(inc|dec)_link_count
  30.          */
  31.         union {
  32.                 const unsigned int i_nlink;
  33.                 unsigned int __i_nlink;
  34.         };
  35.         dev_t                        i_rdev;
  36.         loff_t                        i_size;
  37.         struct timespec64        i_atime;
  38.         struct timespec64        i_mtime;
  39.         struct timespec64        i_ctime;
  40.         spinlock_t                i_lock;        /* i_blocks, i_bytes, maybe i_size */
  41.         unsigned short          i_bytes;
  42.         u8                        i_blkbits;
  43.         u8                        i_write_hint;
  44.         blkcnt_t                i_blocks;

  45. #ifdef __NEED_I_SIZE_ORDERED
  46.         seqcount_t                i_size_seqcount;
  47. #endif

  48.         /* Misc */
  49.         unsigned long                i_state;
  50.         struct rw_semaphore        i_rwsem;

  51.         unsigned long                dirtied_when;        /* jiffies of first dirtying */
  52.         unsigned long                dirtied_time_when;

  53.         struct hlist_node        i_hash;
  54.         struct list_head        i_io_list;        /* backing dev IO list */
  55. #ifdef CONFIG_CGROUP_WRITEBACK
  56.         struct bdi_writeback        *i_wb;                /* the associated cgroup wb */

  57.         /* foreign inode detection, see wbc_detach_inode() */
  58.         int                        i_wb_frn_winner;
  59.         u16                        i_wb_frn_avg_time;
  60.         u16                        i_wb_frn_history;
  61. #endif
  62.         struct list_head        i_lru;                /* inode LRU list */
  63.         struct list_head        i_sb_list;
  64.         struct list_head        i_wb_list;        /* backing dev writeback list */
  65.         union {
  66.                 struct hlist_head        i_dentry;
  67.                 struct rcu_head                i_rcu;
  68.         };
  69.         atomic64_t                i_version;
  70.         atomic_t                i_count;
  71.         atomic_t                i_dio_count;
  72.         atomic_t                i_writecount;
  73. #ifdef CONFIG_IMA
  74.         atomic_t                i_readcount; /* struct files open RO */
  75. #endif
  76.         const struct file_operations        *i_fop;        /* former ->i_op->default_file_ops */
  77.         struct file_lock_context        *i_flctx;
  78.         struct address_space        i_data;
  79.         struct list_head        i_devices;
  80.         union {
  81.                 struct pipe_inode_info        *i_pipe;
  82.                 struct block_device        *i_bdev;
  83.                 struct cdev                *i_cdev;
  84.                 char                        *i_link;
  85.                 unsigned                i_dir_seq;
  86.         };

  87.         __u32                        i_generation;

  88. #ifdef CONFIG_FSNOTIFY
  89.         __u32                        i_fsnotify_mask; /* all events this inode cares about */
  90.         struct fsnotify_mark_connector __rcu        *i_fsnotify_marks;
  91. #endif

  92. #if IS_ENABLED(CONFIG_FS_ENCRYPTION)
  93.         struct fscrypt_info        *i_crypt_info;
  94. #endif

  95.         void                        *i_private; /* fs or device private pointer */
  96. } __randomize_layout;

复制代码
回复

使用道具 举报

40#
 楼主| 发表于 2019-3-15 15:25:15 | 只看该作者
这是 ext4 的 inode:
  1. /*
  2. * Structure of an inode on the disk
  3. */
  4. struct ext4_inode {
  5.         __le16        i_mode;                /* File mode */
  6.         __le16        i_uid;                /* Low 16 bits of Owner Uid */
  7.         __le32        i_size_lo;        /* Size in bytes */
  8.         __le32        i_atime;        /* Access time */
  9.         __le32        i_ctime;        /* Inode Change time */
  10.         __le32        i_mtime;        /* Modification time */
  11.         __le32        i_dtime;        /* Deletion Time */
  12.         __le16        i_gid;                /* Low 16 bits of Group Id */
  13.         __le16        i_links_count;        /* Links count */
  14.         __le32        i_blocks_lo;        /* Blocks count */
  15.         __le32        i_flags;        /* File flags */
  16.         union {
  17.                 struct {
  18.                         __le32  l_i_version;
  19.                 } linux1;
  20.                 struct {
  21.                         __u32  h_i_translator;
  22.                 } hurd1;
  23.                 struct {
  24.                         __u32  m_i_reserved1;
  25.                 } masix1;
  26.         } osd1;                                /* OS dependent 1 */
  27.         __le32        i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
  28.         __le32        i_generation;        /* File version (for NFS) */
  29.         __le32        i_file_acl_lo;        /* File ACL */
  30.         __le32        i_size_high;
  31.         __le32        i_obso_faddr;        /* Obsoleted fragment address */
  32.         union {
  33.                 struct {
  34.                         __le16        l_i_blocks_high; /* were l_i_reserved1 */
  35.                         __le16        l_i_file_acl_high;
  36.                         __le16        l_i_uid_high;        /* these 2 fields */
  37.                         __le16        l_i_gid_high;        /* were reserved2[0] */
  38.                         __le16        l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
  39.                         __le16        l_i_reserved;
  40.                 } linux2;
  41.                 struct {
  42.                         __le16        h_i_reserved1;        /* Obsoleted fragment number/size which are removed in ext4 */
  43.                         __u16        h_i_mode_high;
  44.                         __u16        h_i_uid_high;
  45.                         __u16        h_i_gid_high;
  46.                         __u32        h_i_author;
  47.                 } hurd2;
  48.                 struct {
  49.                         __le16        h_i_reserved1;        /* Obsoleted fragment number/size which are removed in ext4 */
  50.                         __le16        m_i_file_acl_high;
  51.                         __u32        m_i_reserved2[2];
  52.                 } masix2;
  53.         } osd2;                                /* OS dependent 2 */
  54.         __le16        i_extra_isize;
  55.         __le16        i_checksum_hi;        /* crc32c(uuid+inum+inode) BE */
  56.         __le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
  57.         __le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
  58.         __le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
  59.         __le32  i_crtime;       /* File Creation time */
  60.         __le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
  61.         __le32  i_version_hi;        /* high 32 bits for 64-bit version */
  62.         __le32        i_projid;        /* Project ID */
  63. };
复制代码

回复

使用道具 举报

41#
 楼主| 发表于 2019-3-15 17:58:54 | 只看该作者
先研究 ext4 的 inode 结构。

i_mode 是文件的权限模式,16 位。可是后面出现了 h_i_mode_high 也是 16 位。因此,把两者合并,就是 32 位的。Linux 中一般的 VFS 的 inode 中的 i_mode 是 umode_t 类型,即 unsigned short,它也是 16 位的。就是说,Linux 只用 16 位就够了。但别的操作系统(hurd)却使用了 32 位。所以,这里应该采用 32 位。

同理,i_uid 和 i_gid 都应该是 32 位值。而从 i_size_lo(32 位) 和 i_size_high (32 位)可知,文件长度应该是 64 位值。


  1.         __le32        i_atime;        /* Access time */
  2.         __le32        i_ctime;        /* Inode Change time */
  3.         __le32        i_mtime;        /* Modification time */
  4.         __le32        i_dtime;        /* Deletion Time */

  5.         __le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
  6.         __le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
  7.         __le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
  8.         __le32  i_crtime;       /* File Creation time */
  9.         __le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
复制代码


上述这些“时间”,大部分都需要 64 位。只有 “删除时间”不重要,是 32 位的。

dtime 是删除时间。(<---- 它不重要,是 32 位值。其余几个是 64 位值。)
atime 是访问时间。
ctime 是 inode 发生变化的时间。
mtime 是修改时间。
crtime 是文件创建的时间。

在百度上搜,发现 crtime 是个较新的东西,以前只有 ctime,没有这个 crtime。它放在 ext4  inode 的结构的尾部,也说明它是后来才有的。有的地方把它叫做 birthtime(出生时间)。

那么,ctime 和 mtime 有什么差别呢?

mtime 是文件内容最后修改保存的时间。而 ctime 是文件的 inode 信息发生变化的时间,比如更改了 owner, group 或更改了权限位之类的,我理解,应该也包括更改了上述这些 time 吧。因此,只要内容更改了,ctime 也会更改(mtime 当然也变了)。但是,在文件内容未修改的情况下,mtime 就保持为旧的,而 ctime 有可能更新。

既然 “删除时间”不重要,那么,对等地,“创建时间”也不重要。就是说,只要粗略地知道它何时创建即可,没必要精确到毫秒级。创建和删除,就如一个人出生和死亡一样,都是一次性的。所以,这个时间属于常量,不会频繁变化,因此,没有必要精确到毫秒级。这样的话,就可节约 4 个字节。

i_links_count,是 16 位的,用于记录硬链接的个数。在 sefs 中不需要它,去掉它,可节约 2 个字节。

i_blocks_lo 是 32 位,l_i_blocks_high 是 16 位。合起来是 48 位,也就是 6 个字节。sefs 里面文件的块信息都记录在 FAT 表中,不需要知道有多少个块。所以,这 6 个字节可以节约出来。

i_flags 在 VFS 和 ext4 中都是 32 位值。不知道它够不够用。可以扩大到 64 位。

i_block 是 32 位整数数组,记录数据块信息。sefs 只需要一个 32 位的起始簇号即可,又节约了不少字节。

i_generation 是 32 位,在 VFS 中也有它。注释中写着 File version (for NFS),可能有用,就留着。

i_file_acl_lo;  是 32 位。l_i_file_acl_high 是 16 位。ACL 比较重要,但这个 48 位,有点变态。需要再看看相关资料。

i_extra_isize 是 16 位,与 inode 结构长度有关。在 sefs 中不需要它。
i_projid; /* Project ID */ 是个 32 位值,不知道有啥用。
回复

使用道具 举报

42#
 楼主| 发表于 2019-3-16 14:21:37 | 只看该作者
https://www.kernel.org/doc/html/latest/filesystems/ext4/dynamic.html

The inode table entry is laid out in struct ext4_inode.

OffsetSizeNameDescription
0x0__le16i_modeFile mode. See the table i_mode below.
0x2__le16i_uidLower 16-bits of Owner UID.
0x4__le32i_size_loLower 32-bits of size in bytes.
0x8__le32i_atimeLast access time, in seconds since the epoch. However, if the EA_INODEinode flag is set, this inode stores an extended attribute value andthis field contains the checksum of the value.
0xC__le32i_ctimeLast inode change time, in seconds since the epoch. However, if theEA_INODE inode flag is set, this inode stores an extended attributevalue and this field contains the lower 32 bits of the attribute value’sreference count.
0x10__le32i_mtimeLast data modification time, in seconds since the epoch. However, if theEA_INODE inode flag is set, this inode stores an extended attributevalue and this field contains the number of the inode that owns theextended attribute.
0x14__le32i_dtimeDeletion Time, in seconds since the epoch.
0x18__le16i_gidLower 16-bits of GID.
0x1A__le16i_links_countHard link count. Normally, ext4 does not permit an inode to have more than 65,000 hard links. This applies to files as well as directories, which means that there cannot be more than 64,998 subdirectories in a directory (each subdirectory’s ‘..’ entry counts as a hard link, as does the ‘.’ entry in the directory itself). With the DIR_NLINK feature enabled, ext4 supports more than 64,998 subdirectories by setting this field to 1 to indicate that the number of hard links is not known.
0x1C__le32i_blocks_loLower 32-bits of “block” count. If the huge_file feature flag is not set on the filesystem, the file consumes i_blocks_lo 512-byte blocks on disk. If huge_file is set and EXT4_HUGE_FILE_FL is NOT set in inode.i_flags, then the file consumes i_blocks_lo + (i_blocks_hi<< 32) 512-byte blocks on disk. If huge_file is set and EXT4_HUGE_FILE_FL IS set in inode.i_flags, then this file consumes (i_blocks_lo + i_blocks_hi << 32) filesystem blocks on disk.
0x20__le32i_flagsInode flags. See the table i_flags below.
0x244 bytesi_osd1See the table i_osd1 for more details.
0x2860 bytesi_block[EXT4_N_BLOCKS=15]Block map or extent tree. See the section “The Contents of inode.i_block”.
0x64__le32i_generationFile version (for NFS).
0x68__le32i_file_acl_loLower 32-bits of extended attribute block. ACLs are of course one of many possible extended attributes; I think the name of this field is a result of the first use of extended attributes being for ACLs.
0x6C__le32i_size_high / i_dir_aclUpper 32-bits of file/directory size. In ext2/3 this field was named i_dir_acl, though it was usually set to zero and never used.
0x70__le32i_obso_faddr(Obsolete) fragment address.
0x7412 bytesi_osd2See the table i_osd2 for more details.
0x80__le16i_extra_isizeSize of this inode - 128. Alternately, the size of the extended inode fields beyond the original ext2 inode, including this field.
0x82__le16i_checksum_hiUpper 16-bits of the inode checksum.
0x84__le32i_ctime_extraExtra change time bits. This provides sub-second precision. See Inode Timestamps section.
0x88__le32i_mtime_extraExtra modification time bits. This provides sub-second precision.
0x8C__le32i_atime_extraExtra access time bits. This provides sub-second precision.
0x90__le32i_crtimeFile creation time, in seconds since the epoch.
0x94__le32i_crtime_extraExtra file creation time bits. This provides sub-second precision.
0x98__le32i_version_hiUpper 32-bits for version number.
0x9C__le32i_projidProject ID.

The i_mode value is a combination of the following flags:

ValueDescription
0x1S_IXOTH (Others may execute)
0x2S_IWOTH (Others may write)
0x4S_IROTH (Others may read)
0x8S_IXGRP (Group members may execute)
0x10S_IWGRP (Group members may write)
0x20S_IRGRP (Group members may read)
0x40S_IXUSR (Owner may execute)
0x80S_IWUSR (Owner may write)
0x100S_IRUSR (Owner may read)
0x200S_ISVTX (Sticky bit)
0x400S_ISGID (Set GID)
0x800S_ISUID (Set UID)
These are mutually-exclusive file types:
0x1000S_IFIFO (FIFO)
0x2000S_IFCHR (Character device)
0x4000S_IFDIR (Directory)
0x6000S_IFBLK (Block device)
0x8000S_IFREG (Regular file)
0xA000S_IFLNK (Symbolic link)
0xC000S_IFSOCK (Socket)

The i_flags field is a combination of these values:

ValueDescription
0x1This file requires secure deletion (EXT4_SECRM_FL). (not implemented)
0x2This file should be preserved, should undeletion be desired(EXT4_UNRM_FL). (not implemented)
0x4File is compressed (EXT4_COMPR_FL). (not really implemented)
0x8All writes to the file must be synchronous (EXT4_SYNC_FL).
0x10File is immutable (EXT4_IMMUTABLE_FL).
0x20File can only be appended (EXT4_APPEND_FL).
0x40The dump(1) utility should not dump this file (EXT4_NODUMP_FL).
0x80Do not update access time (EXT4_NOATIME_FL).
0x100Dirty compressed file (EXT4_DIRTY_FL). (not used)
0x200File has one or more compressed clusters (EXT4_COMPRBLK_FL). (not used)
0x400Do not compress file (EXT4_NOCOMPR_FL). (not used)
0x800Encrypted inode (EXT4_ENCRYPT_FL). This bit value previously was EXT4_ECOMPR_FL (compression error), which was never used.
0x1000Directory has hashed indexes (EXT4_INDEX_FL).
0x2000AFS magic directory (EXT4_IMAGIC_FL).
0x4000File data must always be written through the journal(EXT4_JOURNAL_DATA_FL).
0x8000File tail should not be merged (EXT4_NOTAIL_FL). (not used by ext4)
0x10000All directory entry data should be written synchronously (see dirsync) (EXT4_DIRSYNC_FL).
0x20000Top of directory hierarchy (EXT4_TOPDIR_FL).
0x40000This is a huge file (EXT4_HUGE_FILE_FL).
0x80000Inode uses extents (EXT4_EXTENTS_FL).
0x200000Inode stores a large extended attribute value in its data blocks(EXT4_EA_INODE_FL).
0x400000This file has blocks allocated past EOF (EXT4_EOFBLOCKS_FL).(deprecated)
0x01000000Inode is a snapshot (EXT4_SNAPFILE_FL). (not in mainline)
0x04000000Snapshot is being deleted (EXT4_SNAPFILE_DELETED_FL). (not inmainline)
0x08000000Snapshot shrink has completed (EXT4_SNAPFILE_SHRUNK_FL). (not inmainline)
0x10000000Inode has inline data (EXT4_INLINE_DATA_FL).
0x20000000Create children with the same project ID (EXT4_PROJINHERIT_FL).
0x80000000Reserved for ext4 library (EXT4_RESERVED_FL).
Aggregate flags:
0x4BDFFFUser-visible flags.
0x4B80FFUser-modifiable flags. Note that while EXT4_JOURNAL_DATA_FL andEXT4_EXTENTS_FL can be set with setattr, they are not in the kernel’s EXT4_FL_USER_MODIFIABLE mask, since it needs to handle the setting of these flags in a special manner and they are masked out of the set of flags that are saved directly to i_flags.

看到 i_flags 的全部 32 位被用光了。因此,用 64 位便于将来的扩展。在 sefs 中,应该有一个控制标志,用于强制文件连续存放(.fattbl),另有一个信息标志,表示文件已经是连续存放。还需要一个标志,强制文件占据的簇号不能更改(.bootblk)。同理,也有标志禁止改变文件长度,以及禁止读取、禁止写入(.bootblk,.fattbl),诸如此类,即使是 root 用户也无法操作。



另外,原网页对 64 位的时间戳印有详细解释,在附加的 32 位中,大部分的位都用于精确到纳秒级,只有少数被用于支持更多年份——最大只支持到 2446 年,可惜了。关于文件的时戳,几十年来一直使用的都是精确到秒,没有什么问题。感觉精确到纳秒级,没有什么意义。因此,sefs 把全部 64 位,都用于秒(像传统一样),不再对时间戳印进行复杂的格式设计。



回复

使用道具 举报

43#
 楼主| 发表于 2019-3-18 10:22:44 | 只看该作者
本帖最后由 不点 于 2019-3-22 06:07 编辑

sefs 目录文件整体结构设计。

目录文件在其开头有一个信息区域,记录该目录下文件的统计信息。该目录下全部文件名的 hash 值也放在这里,hash 值取 32 位整数。信息区域中有一个 32 位变量指示本次所采用的 hash 算法。各种 hash 算法由驱动程序来定义。hash 值与文件的目录项的偏移相对应,找到了 hash 值就知道了目录项的位置。hash 值必须排序。但并非所有的文件名都有 hash 值。操作系统(或驱动程序)在空闲时为各目录下的文件名添加 hash 项。信息区域有一个 32 位变量,指示该目录下有多少个 hash 值。当然也有一个 32 位变量记录该目录下的文件总数。删除文件时,hash 项不一定删除,操作系统(或驱动程序)在空闲时会处理好。操作系统(或驱动程序)会尽量为该目录选用碰撞较少的 hash 算法。总碰撞数以及最大碰撞项的碰撞数也记录在信息区。初始时,可以为信息区域分配一簇。目录项从一个新的簇开始。驱动程序在更新信息区域时,顺便会保证该目录文件是连续存放的。

目录文件至少占用 2 个簇(一个信息簇和一个目录项簇)。在 FAT 表中,目录文件的最后一簇的指针指向该目录文件的起始簇(形成一个簇链循环)。

普通文件与此不同。普通文件的最后一簇,如果是个零头(即,不是刚好填满一个完整簇),它有可能被操作系统(或驱动程序)动态调整到目录项中。在 FAT 表中,普通文件的最后一簇的指针,指向该文件所在目录的目录文件起始簇或目录文件结束簇。当普通文件的最后一个不完整簇被调整到目录项中时,需要从目录项的数据结构中找到最后一簇的数据,此时 FAT 簇链的尾端,其实是最后一个完整簇,它所在位置的指针,指向目录文件的起始簇,需要从起始簇开始查找目录项,再由目录项查找零头数据。当普通文件的最后一簇(不管是否为完整簇)仍然保持在簇链尾端时,就不需要在目录项中保存数据了,此时 FAT 簇链的尾端指向目录文件结束簇。

在 FAT 表中,目录文件的簇链构成一个循环圈,可以想象成一个圆圈。普通文件是一个簇链在尾部又带上一个循环圈(即,该普通文件所在目录的循环圈),可以想象成一条线段连接一个圆圈。所以,仅从 FAT 链的拓扑结构,就可以区分普通文件和目录文件。

目录文件的循环链中,有个最小的簇号和最大的簇号。最小的簇号,一定是目录文件的起始簇,最大的簇号,一定是目录的结束簇。位于起始簇和结束簇之间的其它簇,也都是按顺序排列的,不可以出现逆转。也就是说,只有最后一簇才会发生折转(指向前面较小的簇号),其它簇都是指向较大的簇号。由于目录文件至少有 2 个簇,所以也不会出现指向自己的簇(即,圆圈上只有一个簇的情况)。普通文件的链条部分,也不可以出现折转。只在最后指向循环圈时才可能有折转的发生。指向循环圈的那个簇,就是普通文件本身的最后一个有效簇号,而循环圈是由其所在目录的全部簇构成的。

新创建的文件,或者新修改的文件,都会把文件内容全部放在簇链中(不会把尾部零头调整到目录项中),这便于在短期内频繁修改文件。操作系统(或驱动程序)会按照某种策略,在空闲时,把长期无修改而且有零头的文件进行调整。

以上这种拓扑结构,有利于从 FAT 表的链条找到文件所在的目录项。如果簇链的尾端用一个简单的 0xFFFFFFFF 来结束,那就不知道文件的其它信息了,比如就连文件的精确长度都无法知道。操作系统在读文件的时候,不会用到这最后一簇的指针,因为读到最后一簇就读完了,没有后续簇了。零头尾巴早都在读目录项的时候就已经读到内存里了。
回复

使用道具 举报

44#
 楼主| 发表于 2019-3-19 18:09:27 | 只看该作者
本帖最后由 不点 于 2019-4-8 15:12 编辑

sefs 目录项结构设计(待完善)
OffsetSizeNameDescription
0x0__le32modeValue    Description
0x1       Owner may execute
0x2       Owner may read
0x4       Owner may append
0x8       Owner may erase
0x10      Reserved
0x20      Reserved
0x40      Reserved
0x80      Reserved
0x100     Group may execute
0x200     Group may read
0x400     Group may append
0x800     Group may erase
0x1000      Reserved
0x2000      Reserved
0x4000      Reserved
0x8000      Reserved
0x10000     Others may execute
0x20000     Others may read
0x40000     Others may append
0x80000     Others may erase
0x100000      Reserved
0x200000      Reserved
0x400000      Reserved
0x800000      Reserved
0x1000000   Reserved
0x2000000   Compatibility (Sticky bit)
0x4000000   Compatibility (Set GID)
0x8000000   Compatibility (Set UID)
  These are mutually-exclusive file types:
0x10000000    FIFO
0x20000000    Character device
0x40000000    Directory
0x60000000    Block device
0x80000000    Regular file
0xA0000000    Symbolic link
0xC0000000    Socket

0x4__le32uidOwner UID.
0x8__le64sizeFile size in bytes.
0x10__le32mtimeLast data modification time, in seconds since volume creation.
0x14__le32ctimeLast attribute change time, in seconds since volume creation.
0x18__le32atimeLast access time, in seconds since volume creation.
0x1C__le32reserved1
0x20__le32checksum
0x24__le32gidGID.
0x28__le32cluster_1st
Data chain starting cluster number
0x2C__le32reserved2
0x30__le64flags?控制位,更新 atime。
?控制位,文件 tail 在簇链中,不调整到目录项中。
?控制位,簇链必须连续。
?状态位,簇链已连续。
?状态位,文件被标记为已删除。新的进程不再处理该目录项,但文件的数据尚未被删除,可能有进程在使用该文件的数据。操作系统会在合适的时候删除该文件的内容以及该目录项。
0x38__le16rec_lenLength of this directory entry. Must be 16 byte aligned.
0x3A__le16ext_lenExtended attribute length. 0 if no extended attributes.
0x3C__le16tail_lenData tail is allocated inside the directory entry. If it is 0, then there is no tail or the tail is allocated normally in the cluster chain.
0x3E__le16name_lenLength of the file name, including the ending NULL.
0x40char[]nameFile name. ASCIIZ.

char[]
Data tail in Last block if tail_len != 0. Data tail immediately follows the name.

char[]
Extended attribute (ACL, SELinux, etc.) if exists. Extended attribute is always located at the end of the entry. So it starts at offset (rec_len - ext_len).

回复

使用道具 举报

45#
 楼主| 发表于 2019-3-21 17:02:05 | 只看该作者
本帖最后由 不点 于 2019-3-21 17:14 编辑

搜到下面这个讨论,关于 selinux 的,感觉说到点子上了。感慨一下:安全只能靠自己。靠别人,年都过差(chà)了。一个简单的道理,装了一堆杀毒软件,以为安全了,殊不知这些全是流氓软件,不会有丝毫的安全,只会有后门。不用到处寻找木马,它们就是特洛伊木马。像 Linux 那样全是开源的,都无法保证安全,更不用说闭源的东西了。不装杀毒软件,只要自己平时小心一点,不下载恶意软件,系统反而还能活得久一些。在另一个地方看到有人说,主流 Linux 发行版全都有后门。想想也是这个理啊!世界这么大,开发人员又这么多,怎可能保证里面全都是干净的?看来以后也只能把 Linux 当成另一个 Windows 来用了,不要抱过高的期望。就是说,很无奈的。与其它开源操作系统相比,Linux 这么好用,肯定被各大流氓软件制造商盯上,他们肯定会渗透进去,把 Linux 变成像 Windows 一样的跑马场。由于 Linux 好用(跟用户摆脱不了 Windows 是一个道理,皆是因为好用),Linux 的用户们就无法摆脱 Linux,无法转移到别的“更安全的”系统上(即便存在的话)。



https://www.oschina.net/question/23734_93597
selinux真那么安全吗?
mallon 发布于 2013/03/17 22:55

什么selinux、polkit那套东西,且不说有美国国防部参与开发,算法上给你弄几个后门了,就算是没有后门,我也不信“越复杂越安全”这个道理,弄到root权限还不是一样完蛋?反之简单的linux权限模型没有root权限不也一样安全?

我一直信奉“简单”的原则,近些年来搞Linux的人脑子都有些秀逗了!

七液 2013/03/26 20:48
就和编码一样,写的越简单的代码查找bug和调试的难度越低,凡事一目了然,相同的原理挂在安全上,越是复杂,吃饱了撑的认为用户都是安全高手把安全规则都交给用户来处理的越容易出问题。先不说用户是否懂各种规则如何设定,复杂的系统查找漏洞和后门的难度也高。调试和找bug都不容易,寻找那些刻意留下来的就更难了,现在中国开始越来越重视商业间谍了(三一重工的破事就最好体现了,搞得人家都迁都北京了)但是法律还是个灰色区域,selinux这种专业人士玩起来都很麻烦,您指望一般公司内部的网管玩得起来不?再说我要是渗透的话,肯定先把网管贿赂了(一般网管都是比较不太重视的职业,公司肯定不高--以此延伸,机房的网管---哈哈我什么都没说)




回复

使用道具 举报

46#
 楼主| 发表于 2019-3-22 05:30:05 | 只看该作者
本帖最后由 不点 于 2019-4-5 08:28 编辑

摘录 chattr 命令修改文件属性的一些说明片段:

这些属性共有以下8种:
A:即Atime,告诉系统不要修改对这个文件的最后访问时间。
S:即Sync,一旦应用程序对这个文件执行了写操作,使系统立刻把修改的结果写到磁盘。
a:即Append Only,系统只允许在这个文件之后追加数据,不允许任何进程覆盖或截断这个文件。如果目录具有这个属性,系统将只允许在这个目录下建立和修改文件,而不允许删除任何文件。
b:不更新文件或目录的最后存取时间。
c:将文件或目录压缩后存放。
d:当dump程序执行时,该文件或目录不会被dump备份。
D:检查压缩文件中的错误。
i:即Immutable,系统不允许对这个文件进行任何的修改。如果目录具有这个属性,那么任何的进程只能修改目录之下的文件,不允许建立和删除文件。
s:彻底删除文件,不可恢复,因为是从磁盘上删除,然后用0填充文件所在区域。
u:当一个应用程序请求删除这个文件,系统会保留其数据块以便以后能够恢复删除这个文件,用来防止意外删除文件或目录。
t:文件系统支持尾部合并(tail-merging)。
X:可以直接访问压缩文件的内容。

这些属性,本质上与文件的 chmod 属性是类似的,但却需要一条新的命令才能操作。这暴露出当初 rwx 权限的设计太过于粗糙,不够应用。于是没办法,只好打补丁。chattr 是一种补丁,ACL 是一种补丁,selinux 又是一种补丁,还有别的五花八门的补丁,可以说,补丁打不完了。目前 Linux 在应用层的软件已经很丰富了,这是非常不容易的。但在最擅长的安全领域却不断暴露出不安全的问题,似乎有些奇怪。我们常说,干任何事,安全第一。而在这里,安全被排在并不优先的位置了。需要明确的是,即便没有任何权限设置,也不会对应用层造成太大的问题。Windows 靠易用性打天下,并未依靠安全,至少当初是这样。那么,应用层做好之后,安全问题就摆上了桌面,最终还是得解决安全问题。该从底层彻底改造安全模型了。

补充:考察上述 immutable 参数的设计。它的描述是这样的:“系统不允许对文件进行任何修改,如果是目录,不允许增删文件。”——这不就相当于没有 “写”(w)权限吗?只不过连 root 用户也不允许写罢了。在 root 用户不会被攻陷的前提下,这个参数差不多应该算是多余的吧?只要 root 用户把文件设置为只有自己可以写而其他人不可以写,这就达到了同样的目的(当然不完全一样,因为 root 用户自己能写入)。况且,严格来说,仍然无法限制 root 用户写入,因为 root 用户可以首先去掉 immutable 属性,然后再写入文件。

另一个参数指示 dump 备份工具不备份此文件(或目录)——就这个小小的、完全是应用层的目的,都要浪费文件系统中的一个控制逻辑,感觉好无聊啊!怪不得文件系统和操作系统都搞得那么庞大和复杂——猜猜看——复杂了、混乱了,是不是就方便隐藏后门了?

回复

使用道具 举报

47#
 楼主| 发表于 2019-3-22 18:17:10 | 只看该作者
搜到这样的问答:
Windows 7 中 Administrator 和 SYSTEM 账户权限有什么区别

最高权限账户应该是虚拟账户:TrustedInstaller,拥有最高磁盘访问权限。Administrator 和 SYSTEM 都没有这么高权限,那么这两个账户单从权限上来说,有什么区别?

你好朋友,这两个用户在权限上的区别就是,administrator 是管理员用户,一般你平时运行的程序都是以这个权限身份运行的,你平时安装软件什么什么的、修改系统设置都是以这个权限操作的,system 权限是系统自己的权限,任务管理器里面只要是以 system 这个用户名运行的程序都是系统本身的程序,比如任务管理器里面的 winlogon.exe、svchost.exe、alg.exe 这些进程等等,而不是你运行的程序,像什么 QQ.exe、thunder.exe 这些了,这些都是用户运行的程序,还有就是,注册表里面某些地方只有系统自己可以访问,你的用户不能访问,就是 system 比别的管理员用户权限大的关系,另外 win7 系统我不了解。

从上述问答中可以得到这样一些信息:TrustedInstaller 权限高于 system,而 system 又高于 administrator。但不知道上述问答的内容是否权威、是否准确。从另外一些地方可以知道,只要有 administrator 权限,就可以获得 system 以及 TrustedInstaller 权限。那么,是否可以理解为三个权限是相同的呢?


不管怎么说,Windows 采用不同的管理级别,还是有一定的参考价值的。

回复

使用道具 举报

48#
发表于 2019-3-24 22:45:55 | 只看该作者
大师的sefs文件系统设计好了,还要考虑源码实现,工作量不少。。。
linus本人也搞了几文件系统,比如他曾经为闪存设计过yafs文件系统。如果不点大师有兴趣,可以找源码参考下的。。。

点评

代码其实不难实现,抄抄改改就有了。 关键是(我发现)设计一个文件系统容易,但设计一个操作系统,比较麻烦。 我的意思是说,应该把 Linux 的权限处理部分进行大的改造,究竟如何进行,这个设计的工作量很  详情 回复 发表于 2019-3-24 23:20
回复

使用道具 举报

49#
 楼主| 发表于 2019-3-24 23:20:42 | 只看该作者
gnuxwy 发表于 2019-3-24 22:45
大师的sefs文件系统设计好了,还要考虑源码实现,工作量不少。。。
linus本人也搞了几文件系统,比如他曾 ...

代码其实不难实现,抄抄改改就有了。

关键是(我发现)设计一个文件系统容易,但设计一个操作系统,比较麻烦。


我的意思是说,应该把 Linux 的权限处理部分进行大的改造,究竟如何进行,这个设计的工作量很大。操作系统的权限模型确定了以后,这里的文件系统的设计也就确定了。所以,这个文件系统的设计,暂时搁置起来。


简单说,Linux 的 root 用户权限太大,防范攻击的措施很脆弱,目前的
ACL 和 SELINUX 都不是合适的设计。


我是看到 ext4 的文档里面有 ACL 和 SELINUX 字样,就在百度里面搜,
这样才知道了相关知识。学完之后,觉得这些设计都有很大的问题。
我感觉设计者可能不想从头大搞,所以就采取了 “补丁、再补丁” 的办法。
但是,系统复杂了以后,更不可能安全了,因为可能的漏洞会更多,
且不说后门了。


即便作为桌面,安全性差,也是不行的。服务器当然就更必须保证安全了。
如果没有安全性的话,说实话,我也不需要 Linux 桌面(服务器就更不需要了)。
正是因为对 Windows、Android 跑马场的极度不满,才选择了 Linux。


Linux 这么多年发展出的桌面应用非常丰富,这是难度最高的事情。


其它开源系统要想发展出这么完善的应用,非常困难,不是一朝一夕的事。


相比之下,改造权限模型,工作量就不那么大了。但要把它设计好,
也没那么容易。这些天都在想这个问题。
目前还没有构思出一个完整的解决方案。






回复

使用道具 举报

50#
 楼主| 发表于 2019-3-25 11:31:10 | 只看该作者
本帖最后由 不点 于 2019-3-25 16:18 编辑

前面提到过,无论创新也好,发展也好,都是权衡。创新和发展,都要有基础,要基于现有的一些东西。同时也要有否定,而不是完全被现有的东西捆住了手脚。就是说,既不全盘肯定,也不全盘否定。其实我也知道有些开源项目是连操作系统都从头做起的,并不以 Linux 为基础。我觉得,那可能动作太大了吧?底层系统的设计,对于懂的人来说,或许不难。但困难的是,如何让现有的应用层软件都搬过去?如果操作系统底层重新设计之后又能简单移植现有的应用软件,那当然是完全重新设计操作系统更好了。如果做不到,那么还是应该以现有的操作系统为基础,进行改良,而不是全部推倒重来。

接下来会有不少思维的片段。这些片段会反映对这一技术问题的构思过程,起初可能会有很多错误,但随着时间的推移,应该会逐步完善的。

首先考虑这样一个问题:root 权限太大。简单取缔 root 权限的话,管理起来就没有手段了。但 root 平时不参加管理的时候,躺在那里等待黑客用字典进行穷举式攻击(或者其它各类攻击),也不是一件好事。因此考虑,分散 root 的权力,把 root 的管理工作分给不同的管理员。普通管理员没有什么特权,就跟普通用户一样。所以,它们被攻陷以后,系统只会有部分损失,而不会全部瘫痪。root 权限仍然保留,但平时处于未激活的状态。激活 root 的过程非常严格,只有一个用户能够激活 root。这个用户是谁,别人不知道,只有安装系统的人知道。而且,这个用户除了能够激活 root 以外,别的权限几乎都没有,比如说,他不能添加删除用户,不能删除系统文件,也不能删除其它用户的文件。即使进入了这个用户,也不能轻易激活 root,需要用不对称密钥的反复测试,通过之后才激活 root。

系统设计成在平时无需 root 权限即可正常运行。大部分系统进程都是以非 root 用户的身份运行的。那些需要 root 权限的情况,是很罕见的。所以,平时可以把 root 权限屏蔽掉。系统中保存了 root 以及下属的其它管理员的不对称密钥(公钥)。对这些用户的登录验证很严格。登录者自己所用的客户端操作系统必须十分安全,保证不会泄漏自己的私钥。

激活 root 之前,要首先登入负责启动系统服务的管理员账户,停止一切不必要的服务,防止有其它用户也登入系统。登入进程管理的账户,把所有不太信任的进程都干掉。然后进入账户管理的账户,添加一个秘密账户,此账户就是唯一能够用来激活 root 权限的账户。系统中早已保存了 root 的密钥和秘密账户的密钥,两个身份都得认证成功,此时,内核才激活 root 权限。然后添加并登入 root 账户,进行维护操作。完成后,删除秘密账户和 root 账户,重新禁止内核里的 root 权限。
回复

使用道具 举报

51#
发表于 2019-3-25 22:47:42 | 只看该作者
近年新出现了一个用rust语言写的新操作系统redox,就氏打算从底层开始全部另搞一套的做法。
引导用coreboot,编译噐用llvm,c库自已重新写个relibc。。。

也氏用尛内核结构的,不知这货与gnu的内核hurd相比如何,再等十年再看能否成气侯吧。。。

google不满足安卓的成功,可能也有摆脱linux内核制约考虑,也在打算另起炉灶自已搞个新系统,多等等看吧。。。

点评

今天去了 redox 主页,发现它有自己的文件系统,叫做 RedoxFS。不知您能否再提供点信息?您能否谈谈 redox os 的使用经验?  详情 回复 发表于 2019-3-31 11:08
非常好,那都是了不起的。不过我在想另一个问题。开源的结果究竟会是怎样的? 开源里面可能也是参差不齐的,有特别优秀的,有一般的,有差的。倘若里面混有后门,恐怕也不容易把它揪出来。任何一个开源的实例都可  详情 回复 发表于 2019-3-26 18:10
回复

使用道具 举报

52#
 楼主| 发表于 2019-3-26 18:10:00 | 只看该作者
gnuxwy 发表于 2019-3-25 22:47
近年新出现了一个用rust语言写的新操作系统redox,就氏打算从底层开始全部另搞一套的做法。
引导用coreboo ...

非常好,那都是了不起的。不过我在想另一个问题。开源的结果究竟会是怎样的?

开源里面可能也是参差不齐的,有特别优秀的,有一般的,有差的。倘若里面混有后门,恐怕也不容易把它揪出来。任何一个开源的实例都可能存在这样的问题。至于说究竟哪个 “好”,那是没办法说清楚的。只能说,看各人自己的水平以及缘分了。

当今世界正在发生变化,中国正处于变化的核心。人们开创出多个操作系统,更能体现多元化的发展理念。是的,我们的目光不能仅仅停留在某一片小小的天地(比如 Unix、Linux),应该有更加久远的透射。

有一次我偶尔去查看了一下 Unicode 字符在 65536 之外的部分,我很惊讶,那么多的汉字,我连一个都不认识。我们的祖先怎会有如此强大的造字能力?以至于当时造出的字,后人在几千年里都用不完!这就是跨时代的透射力!那些“扩展字符”都需要 4 个 UTF-8 的字节才能表示。我在 loongson 制作的 startOS 的终端命令行下,居然可以显示这些 “扩展汉字”(打印出对应的 4 个 UTF-8 字节,就打印出了一个扩展汉字),浏览器就更是可以显示了。一个人的生命是有限的,要在有限的生命中,实现无限的价值,这才是生命的意义。尤其是对于从万年古老文明走过来的中国人来说,更是如此。
回复

使用道具 举报

53#
 楼主| 发表于 2019-3-26 18:29:12 | 只看该作者
嗯,谢谢提醒。我意识到了,操作系统可以千变万化,而文件系统并不因操作系统的变化而变化。所以,设计一个带有某种理念(比如 simple & easy)的文件系统,仍然是重要的。它可以超越具体的某个操作系统而成为一般性的存在。
回复

使用道具 举报

54#
 楼主| 发表于 2019-3-26 18:57:00 | 只看该作者
继续探讨 Linux 权限相关问题。

suid —— 是个提权的途径。为什么不允许自己把文件的拥有者无偿赠送给别人?我想,那大概就是因为这个 suid 了。一个用户先设置 suid,然后把拥有者改成别人,这就突破别人的防盗门了。因此之故,才不允许自己把拥有者的权力(免费)赠送给别人。

然而设想一下,假如取缔 suid 之类的设计,这样一来,就完全可以把自己的拥有权让给别人,不再有麻烦了。

一个管理员,负责创建账户。他自己是普通账户,不是 root 账户。他有权在 /home 里面创建文件夹。

他创建的文件夹,拥有权是他自己。但是,他得把拥有权转交给目标用户,否则,他就没有完成 “创建账户”的任务。因此,一个合乎逻辑的权限模型就是,让任何用户都可以把自己对于文件或文件夹的拥有权转让给别人。显然,这样做的话,那就应该取缔 suid 之类的东西了。

提权的途径太多,是隐患的根源。倘若只有一个系统调用才能提权,那就可以堵住很多后门了。

点评

就一个提权占用一个系统调用是不是太浪费了? 我觉得可以使用进程通信等手段解决,反正init进程肯定是在系统里而且以最高权限运行的,如果其他进程需要提权就直接发送给init,init判断权限合格后直接帮他做了,就  详情 回复 发表于 2019-3-28 15:33
回复

使用道具 举报

55#
 楼主| 发表于 2019-3-27 18:37:28 | 只看该作者
sgid 与 suid 存在类似的问题,不再赘述。

sticky bit 也有问题。同一个文件夹底下,有删除权限的人,可不可以删除别人的文件?默认情况下,是允许删除别人的文件的。而在设置 sticky bit 后,才不允许删除别人的文件。

假如我们把这个 sticky bit 的动作当作默认的操作,是不是更合理一点?我们干脆节省这么一个逻辑电路,取消 sticky bit 的使用,让所有的文件夹都执行这一操作,即,任何人都不能删除别人的文件(除非对这个文件有写权限)。

是啊,这又引出另一个问题:普通用户自己的文件夹底下有别人的文件,比如有 root 账户的文件。按照目前的权限逻辑,不管三七二十一,咔嚓就干掉了 root 的文件。你对 root 属主的文件不可读写,却能删除,这样是不是也不怎么合理啊?这与人类生活的常识不相符,那么初学者学用这个奇葩逻辑就得费工夫,不自然。

合理一点的,可以这样设计:要想删除一个文件,需要满足两个条件。第一,你对该文件有写的权限。第二,你对该文件所在的目录有写权限。两者同时满足,才能删除文件。而且这是充分必要条件,只要满足这两条(不需要额外再增加其它限制,比如 sticky 啥的),就能删除文件。法律条文简单,没有例外情况,大家是平等的,都来执行,那就 OK。如果法律条文搞得复杂,那么可以钻空子的地方就多,维护起来难度就大。
回复

使用道具 举报

56#
发表于 2019-3-28 15:33:23 | 只看该作者
不点 发表于 2019-3-26 18:57
继续探讨 Linux 权限相关问题。

suid —— 是个提权的途径。为什么不允许自己把文件的拥有者无偿赠送给 ...

就一个提权占用一个系统调用是不是太浪费了?

我觉得可以使用进程通信等手段解决,反正init进程肯定是在系统里而且以最高权限运行的,如果其他进程需要提权就直接发送给init,init判断权限合格后直接帮他做了,就不需要专门开个api来提权了

点评

不错的思路。但是,那样的话,init 的压力就大了。感觉还是让内核承担这样的风险比较可靠。 提权这种操作,无论给谁都不放心——给 su 不放心,给 passwd 不放心。 只有给内核,让内核开发团队来维护,这才能  详情 回复 发表于 2019-3-28 18:49
回复

使用道具 举报

57#
 楼主| 发表于 2019-3-28 18:49:43 | 只看该作者
2013olly 发表于 2019-3-28 15:33
就一个提权占用一个系统调用是不是太浪费了?

我觉得可以使用进程通信等手段解决,反正init进程肯定是 ...

不错的思路。但是,那样的话,init 的压力就大了。感觉还是让内核承担这样的风险比较可靠。

提权这种操作,无论给谁都不放心——给 su 不放心,给 passwd 不放心。

只有给内核,让内核开发团队来维护,这才能放心。
回复

使用道具 举报

58#
 楼主| 发表于 2019-3-28 21:18:39 | 只看该作者
回到文件系统的讨论。时间戳印。

计算了一下,64 位的秒数,可以达到几千亿年,到太阳系灭亡时,都还绰绰有余。32 位的秒数,可以表示 136 年。跨度 100 多年,也基本够用了。所以,平时用 32 位的时间,也就可以满足需要了。用一个 “基准时间” 来作为一切时间的基数,这个基准时间是 64 位的。基准时间放在哪里?它可以放在文件系统的 super block 里面(或者是 super block 之后的保留区里面)。就是说,文件系统格式化时的时间,就可以作为基准时间,它是 64 位的,可以用到太阳系毁灭时。而每个文件的时间戳印,都是相对于文件系统的基准时间的,采用 32 位,能持续使用 100 多年,足够我们大多数人一生享用了,甚至还没等 100 年过完,这存储介质早坏掉了,该换新了。
回复

使用道具 举报

59#
 楼主| 发表于 2019-3-30 07:29:25 | 只看该作者
今天又对文件的 “写” 权限进行了 “权衡式” 思考。权衡的结果,是对目前的 “写” 权限 (w)进行 “一分为二” 的划分——分为 “擦除”(erase) 和 “增补” (append)两种。

对于普通文件来说,“擦除” 权的含义是,可以 “覆盖式” 地改动文件的现有字节数据,也可以删除文件的现有字节数据。如果一个人只有 “擦除” 权而无 “增补” 权,那么他就不能增加文件长度,只能保持或减小文件长度。而 “增补” 权的含义是,可以为文件追加字节,让文件变长。如果一个人只有 “增补” 权而无 “擦除” 权,那么他不能改写文件原有的字节数据(既不能删除,也不能覆盖)。如果一个人对某个文件既有 “擦除” 权,又有 “增补” 权,那么他就对该文件拥有了完整的 “写” (w)权限。如果一个人对某个文件既无 “擦除” 权,又无 “增补” 权,那么就相当于没有 “写” (w)权限。

对于目录来说,“擦除” 权的含义是,可以 “更名” 现有文件,也可以删除现有文件。如果一个人只有 “擦除” 权而无 “增补” 权,那么他就不能增加该目录下的文件个数,只能保持或减小文件个数。而 “增补” 权的含义是,可以在该目录下创建新文件,增加文件个数。如果一个人只有 “增补” 权而无 “擦除” 权,那么他就不能删除或改名该目录下原有的文件。如果一个人对某个目录既有 “擦除” 权,又有 “增补” 权,那么他就对该目录拥有了完整的 “写” (w)权限。如果一个人对某个目录既无 “擦除” 权,又无 “增补” 权,那么就相当于没有 “写” (w)权限。

你对某个目录拥有 “擦除” 权,并不能保证你一定可以删除或更名该目录下的某个文件,而仅仅是提供了删除或更名它的可能性。到底是否能够删除或更名,还要看你对那个文件是否拥有 “擦除” 权。


同理,你对某个文件拥有 “擦除” 权,并不能保证你一定可以删除该文件或覆盖该文件的字节数据,而仅仅是提供了删除或覆盖的可能性。到底是否能够删除或覆盖,还要看你对该文件所在的目录是否拥有 “擦除” 权。

回复

使用道具 举报

60#
 楼主| 发表于 2019-3-30 13:12:25 | 只看该作者
本帖最后由 不点 于 2019-3-30 14:43 编辑

把 w 权限分拆以后,就要多占用一个 mode 位了。因此,需要设计新的模式。以下是初步设计,并与旧的 mode 进行对比:

【更新】把不太容易变动的 x(可执行) 和 r (可读)调整到低位。append 也不容易变动,因此也放在低位。erase 将来有可能被进一步分拆,因此,放在较高位,同时又保留了最高的 4 位,用于将来可能的扩展。每组权限占用一个字节。owner 一组的存在更稳定(不容易被取缔),因此调整到低端。group 一组放在中间,假如它将来被某个新的(简化式)操作系统所取缔,它的一些低位就可以被 owner 一组使用。


Old file mode
New file mode
  
Value    Description
0x1       Others may execute
0x2       Others may write
0x4       Others may read
0x8       Group may execute
0x10      Group may write
0x20      Group may read
0x40      Owner may execute
0x80      Owner may write
0x100     Owner may read
0x200     Sticky bit
0x400     Set GID
0x800     Set UID
  These are mutually-exclusive file types:
0x1000    FIFO
0x2000    Character device
0x4000    Directory
0x6000    Block device
0x8000    Regular file
0xA000    Symbolic link
0xC000    Socket
  Higher 16-bits - Reserved
  
Value    Description
0x1       Owner may execute
0x2       Owner may read
0x4       Owner may append
0x8       Owner may erase
0x10      Reserved
0x20      Reserved
0x40      Reserved
0x80      Reserved

0x100     Group may execute
0x200     Group may read
0x400     Group may append
0x800     Group may erase
0x1000      Reserved
0x2000      Reserved
0x4000      Reserved
0x8000      Reserved

0x10000     Others may execute
0x20000     Others may read
0x40000     Others may append
0x80000     Others may erase
0x100000      Reserved
0x200000      Reserved
0x400000      Reserved
0x800000      Reserved


0x1000000   Reserved
0x2000000   Compatibility
(Sticky bit)
0x4000000   Compatibility (Set GID)
0x8000000   Compatibility (Set UID)
  These are mutually-exclusive file types:
0x10000000    FIFO
0x20000000    Character device
0x40000000    Directory
0x60000000    Block device
0x80000000    Regular file
0xA0000000    Symbolic link
0xC0000000    Socket


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2025-12-12 03:36

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表