Re: High UID support for Linux

Albert D. Cahalan (acahalan@cs.uml.edu)
Fri, 20 Nov 1998 19:50:32 -0500 (EST)


> Just for grins, I tried changing the typedef in linux/types.h and
> recompiling the kernel. Wouldn't even boot. Then I noticed that
> the uid and gid fields in ext2 inodes are 16 bits. So it seems
> like this is a project, not than a hack. (This was on 2.0.35.)

There is reserved space for the extra 16 bits. The real ext2 inode
structure (including patches waiting for 2.3.xx) is more like this:

struct ext2_inode {
__u16 i_mode; /* File mode */
__u16 i_uid; /* Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* inode Change time */
__u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
__u32 i_flags; /* File flags */
union {
__u32 i_translator; /* translator (Hurd only) */
__u32 i_res_fork; /* resource fork (Linux privs) */
} u1;
__u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
__u32 i_version; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
union {
__u32 i_dir_acl; /* Directory ACL */
__u32 i_size_high; /* high 32 bits of 64-bit size */
} u2;
__u32 i_reserved1;
__u16 i_reserved2;
__u16 i_mode_high; /* extra mode bits (Hurd only) */
__u16 i_uid_high; /* high 16 bits of 32-bit UID */
__u16 i_gid_high; /* high 16 bits of 32-bit GID */
__u32 i_author; /* author (Hurd only) */
};

So do this:

uid = (ino->i_uid_high << 16) | ino->i_uid;
...
ino->i_uid_high = uid >> 16;
ino->i_uid = uid & 0xffff;

Your real problems will be system calls. There isn't enough space in
some of the structs. Sign extension and trunctuation will cause great
trouble.

Suggestion:

/* Clean up sign extension that could be caused by old code.
* Valid UIDs are 0..0xfffe and 0x10000..0xffff7fff.
* UIDs from 0xffff8000..0xffffffff map to 0x8000..0xffff.
* 0xffff (and thus 0xffffffff) is considered to be -1, which is special.
* Systems should avoid UIDs above 0xffff for which (uid&0xffff) is a
* special UID (root, -1, bin...), since older software may alias UIDs.
*/
if((uid & 0xffff8000) == 0xffff8000) uid &= 0xffff;
if(uid == 0xffff) uid = 0xffffffff;

Any way you do this, it is a dangerous mess.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/