diff --git a/libisofs/aaip-os-freebsd.c b/libisofs/aaip-os-freebsd.c index 34d26f9..842613b 100644 --- a/libisofs/aaip-os-freebsd.c +++ b/libisofs/aaip-os-freebsd.c @@ -755,6 +755,7 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace, -6 support of xattr not enabled at compile time -7 support of ACL not enabled at compile time -8 unsupported xattr namespace + ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other:: */ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, size_t *value_lengths, char **values, int flag) @@ -846,6 +847,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i], &consumed, NULL, 0, &acl_text_fill, 1); + if(ret < -3) + goto ex; if(ret <= 0) {ret= -2; goto ex;} acl_text= calloc(acl_text_fill, 1); @@ -853,6 +856,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, {ret= -1; goto ex;} ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i], &consumed, acl_text, acl_text_fill, &acl_text_fill, 0); + if(ret < -3) + goto ex; if(ret <= 0) {ret= -2; goto ex;} has_default_acl= (ret == 2); diff --git a/libisofs/aaip-os-linux.c b/libisofs/aaip-os-linux.c index c631d58..ede44fc 100644 --- a/libisofs/aaip-os-linux.c +++ b/libisofs/aaip-os-linux.c @@ -435,6 +435,7 @@ ex: -6 support of xattr not enabled at compile time -7 support of ACL not enabled at compile time ( -8 unsupported xattr namespace ) + ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other:: */ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, size_t *value_lengths, char **values, int flag) @@ -521,6 +522,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, /* "access" ACL */ ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i], &consumed, NULL, 0, &acl_text_fill, 1); + if(ret < -3) + goto ex; if(ret <= 0) {ret= -2; goto ex;} acl_text= calloc(acl_text_fill, 1); @@ -528,6 +531,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, {ret= -1; goto ex;} ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i], &consumed, acl_text, acl_text_fill, &acl_text_fill, 0); + if(ret < -3) + goto ex; if(ret <= 0) {ret= -2; goto ex;} has_default_acl= (ret == 2); @@ -546,6 +551,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, ret= aaip_decode_acl((unsigned char *) (values[i] + consumed), value_lengths[i] - consumed, &h_consumed, NULL, 0, &acl_text_fill, 1); + if(ret < -3) + goto ex; if(ret <= 0) {ret= -2; goto ex;} acl_text= calloc(acl_text_fill, 1); @@ -554,6 +561,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, ret= aaip_decode_acl((unsigned char *) (values[i] + consumed), value_lengths[i] - consumed, &h_consumed, acl_text, acl_text_fill, &acl_text_fill, 0); + if(ret < -3) + goto ex; if(ret <= 0) {ret= -2; goto ex;} ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32)); diff --git a/libisofs/aaip_0_2.c b/libisofs/aaip_0_2.c index ba946d7..48062b8 100644 --- a/libisofs/aaip_0_2.c +++ b/libisofs/aaip_0_2.c @@ -272,6 +272,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode, -1= out of memory -2= program error with prediction of result size -3= error with conversion of name to uid or gid + ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other:: */ int aaip_encode_acl(char *acl_text, mode_t st_mode, size_t *result_len, unsigned char **result, int flag) @@ -282,6 +283,8 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode, *result_len= 0; bytes= aaip_encode_acl_text(acl_text, st_mode, (size_t) 0, NULL, 1 | (flag & (2 | 4 | 8))); + if(bytes < -2) + return(bytes); if(bytes < 0) return((int) bytes - 1); if(flag & 1) { @@ -295,6 +298,8 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode, *result_len= bytes; bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result, (flag & (2 | 4 | 8))); + if(bytes < -2) + return(bytes); if(bytes < 0) return((int) bytes - 1); if((size_t) bytes != *result_len) { @@ -348,6 +353,7 @@ static int aaip_make_aaip_perms(int r, int w, int x) <0 means error -1: result size overflow -2: conversion errror with user name or group name + ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other:: */ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode, size_t result_size, unsigned char *result, int flag) @@ -393,6 +399,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode, if(strncmp(rpt, "user:", 5) == 0) { if(cpt - rpt == 5) { type= Aaip_ACL_USER_OBJ; + if (has_u) { + + /* >>> Duplicate u:: entry. */; + /* >>> ??? If it matches the previous one: ignore */ + + return((int) ISO_AAIP_ACL_MULT_OBJ); + } has_u++; } else { if(cpt - (rpt + 5) >= name_size) @@ -431,6 +444,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode, } else if(strncmp(rpt, "group:", 6) == 0) { if(cpt - rpt == 6) { type= Aaip_ACL_GROUP_OBJ; + if (has_g) { + + /* >>> Duplicate g:: entry. */; + /* >>> ??? If it matches the previous one: ignore */ + + return((int) ISO_AAIP_ACL_MULT_OBJ); + } has_g++; } else { if(cpt - (rpt + 6) >= name_size) @@ -468,6 +488,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode, } } else if(strncmp(rpt, "other:", 6) == 0) { type= Aaip_ACL_OTHER; + if (has_o) { + + /* >>> Duplicate o:: entry. */; + /* >>> ??? If it matches the previous one: ignore */ + + return((int) ISO_AAIP_ACL_MULT_OBJ); + } has_o++; } else if(strncmp(rpt, "mask:", 5) == 0) { type= Aaip_ACL_MASK; @@ -2139,8 +2166,9 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed, } ret= 1; ex:; + *acl_text_fill= w_size; if(flag & 1) - *acl_text_fill= w_size + 1; + (*acl_text_fill)++; LIBISO_FREE_MEM(name); return(ret); } diff --git a/libisofs/aaip_0_2.h b/libisofs/aaip_0_2.h index 3b6b574..2c458c7 100644 --- a/libisofs/aaip_0_2.h +++ b/libisofs/aaip_0_2.h @@ -56,7 +56,11 @@ size_t aaip_encode(size_t num_attrs, char **names, bit3= check for completeness of list and eventually fill up with entries deduced from st_mode @return >0 means ok - 0 means error + <=0 means error + -1= out of memory + -2= program error with prediction of result size + -3= error with conversion of name to uid or gid + ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other:: */ int aaip_encode_acl(char *acl_text, mode_t st_mode, size_t *result_len, unsigned char **result, int flag); @@ -80,7 +84,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode, bit3= check for completeness of list and eventually fill up with entries deduced from st_mode @return >0 means ok - 0 means error + <=0 means error, see aaip_encode_acl */ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode, size_t *result_len, unsigned char **result, int flag); @@ -496,6 +500,8 @@ int aaip_set_acl_text(char *path, char *text, int flag); -5 error with deleting attributes -6 support of xattr not enabled at compile time -7 support of ACL not enabled at compile time + -8 unsupported xattr namespace + ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other:: */ int aaip_set_attr_list(char *path, size_t num_attrs, char **names, size_t *value_lengths, char **values, int flag); diff --git a/libisofs/fs_local.c b/libisofs/fs_local.c index cb30ed1..bfd857a 100644 --- a/libisofs/fs_local.c +++ b/libisofs/fs_local.c @@ -874,11 +874,13 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names, return ISO_OUT_OF_MEM; if (ret == -2) return ISO_AAIP_BAD_AASTRING; + if (ret >= -5) + return ISO_AAIP_NO_SET_LOCAL; if (ret == -6 || ret == -7) return ISO_AAIP_NOT_ENABLED; if (ret == -8) return ISO_AAIP_BAD_ATTR_NAME; - return ISO_AAIP_NO_SET_LOCAL; + return ret; } return 1; } diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index ff46681..43dc372 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -6921,6 +6921,11 @@ int iso_md5_match(char first_md5[16], char second_md5[16]); /** Attribute name cannot be represented (FAILURE, HIGH, -380) */ #define ISO_AAIP_BAD_ATTR_NAME 0xE830FE84 +/** ACL text contains multiple entries of user::, group::, other:: + (FAILURE, HIGH, -379) */ +#define ISO_AAIP_ACL_MULT_OBJ 0xE830FE83 + + /* Internal developer note: Place new error codes directly above this comment. diff --git a/libisofs/messages.c b/libisofs/messages.c index 86b19e1..5c11a3d 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -466,6 +466,8 @@ const char *iso_error_to_msg(int errcode) return "Rock Ridge path too long"; case ISO_AAIP_BAD_ATTR_NAME: return "Attribute name cannot be represented"; + case ISO_AAIP_ACL_MULT_OBJ: + return "ACL text contains multiple entries of user::, group::, other::"; default: return "Unknown error"; } diff --git a/libisofs/node.c b/libisofs/node.c index 7963a58..721c645 100644 --- a/libisofs/node.c +++ b/libisofs/node.c @@ -2149,10 +2149,12 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text, ret = aaip_encode_both_acl(access_text, default_text, st_mode, &acl_len, &acl, 2 | 8); } - if (ret <= 0) { + if (ret == -1) ret = ISO_OUT_OF_MEM; + else if (ret <= 0 && ret >= -3) + ret = ISO_AAIP_BAD_ACL_TEXT; + if (ret <= 0) goto ex; - } if(acl == NULL) { /* Delete whole ACL attribute */ /* Update S_IRWXG by eventual "group::" ACL entry. @@ -2205,6 +2207,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text, } ret = aaip_encode_both_acl(access_text, default_text, st_mode, &acl_len, &acl, 2 | 8); + if (ret < -3) + goto ex; if (ret <= 0) { ret = ISO_AAIP_BAD_ACL_TEXT; goto ex;